phan 설치

This commit is contained in:
2020-05-01 15:26:54 +09:00
parent a529eba693
commit 51c96b4d04
991 changed files with 239131 additions and 14 deletions
+17
View File
@@ -0,0 +1,17 @@
Copyright (c) Microsoft Corporation
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,22 @@
Microsoft/tolerant-php-parser
THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
Do Not Translate or Localize
This project incorporates components from the projects listed below. The original copyright notices and the licenses under which Microsoft received such components are set forth below. Microsoft reserves all rights not expressly granted herein, whether by implication, estoppel or otherwise.
1. php/php-langspec (https://github.com/php/php-langspec)
%% php/php-langspec NOTICES AND INFORMATION BEGIN HERE
=========================================
Facebook has dedicated all copyright to this specification to the public
domain worldwide under the CC0 Public Domain Dedication located at
<http://creativecommons.org/publicdomain/zero/1.0/>.
The first draft of this specification was initially written in 2014 by
Facebook, Inc.
This specification is distributed without any warranty.
=========================================
END OF php/php-langspec NOTICES AND INFORMATION
+21
View File
@@ -0,0 +1,21 @@
{
"name": "microsoft/tolerant-php-parser",
"description": "Tolerant PHP-to-AST parser designed for IDE usage scenarios",
"type": "library",
"require": {
"php": ">=7.0"
},
"require-dev": {
"phpunit/phpunit": "^6.4"
},
"license": "MIT",
"authors": [
{
"name": "Rob Lourens",
"email": "roblou@microsoft.com"
}
],
"autoload": {
"psr-4": { "Microsoft\\PhpParser\\": ["src/"] }
}
}
+8
View File
@@ -0,0 +1,8 @@
parameters:
level: 2
paths:
- src/
ignoreErrors:
# phpstan issue, see: https://github.com/phpstan/phpstan/issues/1306
- "/Variable .unaryExpression might not be defined./"
- "/Variable .prefix might not be defined./"
@@ -0,0 +1,116 @@
<?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;
class CharacterCodes {
const _0 = 0x30;
const _1 = 0x31;
const _2 = 0x32;
const _3 = 0x33;
const _4 = 0x34;
const _5 = 0x35;
const _6 = 0x36;
const _7 = 0x37;
const _8 = 0x38;
const _9 = 0x39;
const a = 0x61;
const b = 0x62;
const c = 0x63;
const d = 0x64;
const e = 0x65;
const f = 0x66;
const g = 0x67;
const h = 0x68;
const i = 0x69;
const j = 0x6A;
const k = 0x6B;
const l = 0x6C;
const m = 0x6D;
const n = 0x6E;
const o = 0x6F;
const p = 0x70;
const q = 0x71;
const r = 0x72;
const s = 0x73;
const t = 0x74;
const u = 0x75;
const v = 0x76;
const w = 0x77;
const x = 0x78;
const y = 0x79;
const z = 0x7A;
const A = 0x41;
const B = 0x42;
const C = 0x43;
const D = 0x44;
const E = 0x45;
const F = 0x46;
const G = 0x47;
const H = 0x48;
const I = 0x49;
const J = 0x4A;
const K = 0x4B;
const L = 0x4C;
const M = 0x4D;
const N = 0x4E;
const O = 0x4F;
const P = 0x50;
const Q = 0x51;
const R = 0x52;
const S = 0x53;
const T = 0x54;
const U = 0x55;
const V = 0x56;
const W = 0x57;
const X = 0x58;
const Y = 0x59;
const Z = 0x5a;
const _underscore = 0x5F; // _
const _dollar = 0x24; // $
const _ampersand = 0x26; // &
const _asterisk = 0x2A; // *
const _at = 0x40; // @
const _backslash = 0x5C; // \
const _backtick = 0x60; // `
const _bar = 0x7C; // |
const _caret = 0x5E; // ^
const _closeBrace = 0x7D; // }
const _closeBracket = 0x5D; // ]
const _closeParen = 0x29; // )
const _colon = 0x3A; // :
const _comma = 0x2C; // ;
const _dot = 0x2E; // .
const _doubleQuote = 0x22; // "
const _equals = 0x3D; // =
const _exclamation = 0x21; // !
const _greaterThan = 0x3E; // >
const _hash = 0x23; // #
const _lessThan = 0x3C; // <
const _minus = 0x2D; // -
const _openBrace = 0x7B; // {
const _openBracket = 0x5B; // [
const _openParen = 0x28; // (
const _percent = 0x25; // %
const _plus = 0x2B; // +
const _question = 0x3F; // ?
const _semicolon = 0x3B; // ;
const _singleQuote = 0x27; // '
const _slash = 0x2F; // /
const _tilde = 0x7E; // ~
const _backspace = 0x08; // \b
const _formFeed = 0x0C; // \f
const _byteOrderMark = 0xFEFF;
const _space = 0x20;
const _newline = 0x0A; // \n
const _return = 0x0D; // \r
const _tab = 0x09; // \t
const _verticalTab = 0x0B; // \v
}
+12
View File
@@ -0,0 +1,12 @@
<?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;
/**
* Represents Classes, Interfaces and Traits.
*/
interface ClassLike {}
+28
View File
@@ -0,0 +1,28 @@
<?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;
class Diagnostic {
/** @var int */
public $kind;
/** @var string */
public $message;
/** @var int */
public $start;
/** @var int */
public $length;
public function __construct(int $kind, string $message, int $start, int $length) {
$this->kind = $kind;
$this->message = $message;
$this->start = $start;
$this->length = $length;
}
}
@@ -0,0 +1,12 @@
<?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;
class DiagnosticKind {
const Error = 0;
const Warning = 1;
}
@@ -0,0 +1,110 @@
<?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 Microsoft\PhpParser\Node;
class DiagnosticsProvider {
/**
* @var string[] maps the token kind to the corresponding name
*/
private static $tokenKindToText;
/**
* @param int $kind (must be a valid token kind)
* @return string
*/
public static function getTextForTokenKind($kind) {
return self::$tokenKindToText[$kind];
}
/**
* This is called when this class is loaded, at the bottom of this file.
* @return void
*/
public static function initTokenKindToText() {
self::$tokenKindToText = \array_flip(\array_merge(
TokenStringMaps::OPERATORS_AND_PUNCTUATORS,
TokenStringMaps::KEYWORDS,
TokenStringMaps::RESERVED_WORDS
));
}
/**
* Returns the diagnostic for $node, or null.
* @param \Microsoft\PhpParser\Node|\Microsoft\PhpParser\Token $node
* @return Diagnostic|null
*/
public static function checkDiagnostics($node) {
if ($node instanceof Token) {
if (\get_class($node) === Token::class) {
return null;
}
return self::checkDiagnosticForUnexpectedToken($node);
}
if ($node instanceof Node) {
return $node->getDiagnosticForNode();
}
return null;
}
/**
* @param Token $token
* @return Diagnostic|null
*/
private static function checkDiagnosticForUnexpectedToken($token) {
if ($token instanceof SkippedToken) {
// TODO - consider also attaching parse context information to skipped tokens
// this would allow us to provide more helpful error messages that inform users what to do
// about the problem rather than simply pointing out the mistake.
return new Diagnostic(
DiagnosticKind::Error,
"Unexpected '" .
(self::$tokenKindToText[$token->kind]
?? Token::getTokenKindNameFromValue($token->kind)) .
"'",
$token->start,
$token->getEndPosition() - $token->start
);
} elseif ($token instanceof MissingToken) {
return new Diagnostic(
DiagnosticKind::Error,
"'" .
(self::$tokenKindToText[$token->kind]
?? Token::getTokenKindNameFromValue($token->kind)) .
"' expected.",
$token->start,
$token->getEndPosition() - $token->start
);
}
return null;
}
/**
* Traverses AST to generate diagnostics.
* @param \Microsoft\PhpParser\Node $n
* @return Diagnostic[]
*/
public static function getDiagnostics(Node $n) : array {
$diagnostics = [];
/**
* @param \Microsoft\PhpParser\Node|\Microsoft\PhpParser\Token $node
*/
$n->walkDescendantNodesAndTokens(function($node) use (&$diagnostics) {
if (($diagnostic = self::checkDiagnostics($node)) !== null) {
$diagnostics[] = $diagnostic;
}
});
return $diagnostics;
}
}
DiagnosticsProvider::initTokenKindToText();
@@ -0,0 +1,142 @@
<?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;
/**
* FilePositionMap can be used to get the line number for a large number of nodes (starting from 1).
* It works the most efficiently when the requested node is close to the previously requested node.
*
* Other designs that weren't chosen:
* - Precomputing all of the start/end offsets when initializing was slower - Some offsets weren't needed, and walking the tree was slower.
* - Caching line numbers for previously requested offsets wasn't really necessary, since offsets are usually close together and weren't requested repeatedly.
*/
class FilePositionMap {
/** @var string the full file contents */
private $fileContents;
/** @var int - Precomputed strlen($file_contents) */
private $fileContentsLength;
/** @var int the 0-based byte offset of the most recent request for a line number. */
private $currentOffset;
/** @var int the 1-based line number for $this->currentOffset (updated whenever currentOffset is updated) */
private $lineForCurrentOffset;
public function __construct(string $file_contents) {
$this->fileContents = $file_contents;
$this->fileContentsLength = \strlen($file_contents);
$this->currentOffset = 0;
$this->lineForCurrentOffset = 1;
}
/**
* @param Node $node the node to get the start line for.
* TODO deprecate and merge this and getTokenStartLine into getStartLine
* if https://github.com/Microsoft/tolerant-php-parser/issues/166 is fixed,
* (i.e. if there is a consistent way to get the start offset)
*/
public function getNodeStartLine(Node $node) : int {
return $this->getLineNumberForOffset($node->getStart());
}
/**
* @param Token $token the token to get the start line for.
*/
public function getTokenStartLine(Token $token) : int {
return $this->getLineNumberForOffset($token->start);
}
/**
* @param Node|Token $node
*/
public function getStartLine($node) : int {
if ($node instanceof Token) {
$offset = $node->start;
} else {
$offset = $node->getStart();
}
return $this->getLineNumberForOffset($offset);
}
/**
* @param Node|Token $node
* Similar to getStartLine but includes the column
*/
public function getStartLineCharacterPositionForOffset($node) : LineCharacterPosition {
if ($node instanceof Token) {
$offset = $node->start;
} else {
$offset = $node->getStart();
}
return $this->getLineCharacterPositionForOffset($offset);
}
/** @param Node|Token $node */
public function getEndLine($node) : int {
return $this->getLineNumberForOffset($node->getEndPosition());
}
/**
* @param Node|Token $node
* Similar to getStartLine but includes the column
*/
public function getEndLineCharacterPosition($node) : LineCharacterPosition {
return $this->getLineCharacterPositionForOffset($node->getEndPosition());
}
/**
* @param int $offset
* Similar to getStartLine but includes both the line and the column
*/
public function getLineCharacterPositionForOffset(int $offset) : LineCharacterPosition {
$line = $this->getLineNumberForOffset($offset);
$character = $this->getColumnForOffset($offset);
return new LineCharacterPosition($line, $character);
}
/**
* @param int $offset - A 0-based byte offset
* @return int - gets the 1-based line number for $offset
*/
public function getLineNumberForOffset(int $offset) : int {
if ($offset < 0) {
$offset = 0;
} elseif ($offset > $this->fileContentsLength) {
$offset = $this->fileContentsLength;
}
$currentOffset = $this->currentOffset;
if ($offset > $currentOffset) {
$this->lineForCurrentOffset += \substr_count($this->fileContents, "\n", $currentOffset, $offset - $currentOffset);
$this->currentOffset = $offset;
} elseif ($offset < $currentOffset) {
$this->lineForCurrentOffset -= \substr_count($this->fileContents, "\n", $offset, $currentOffset - $offset);
$this->currentOffset = $offset;
}
return $this->lineForCurrentOffset;
}
/**
* @param int $offset - A 0-based byte offset
* @return int - gets the 1-based column number for $offset
*/
public function getColumnForOffset(int $offset) : int {
$length = $this->fileContentsLength;
if ($offset <= 1) {
return 1;
} elseif ($offset > $length) {
$offset = $length;
}
// Postcondition: offset >= 1, ($lastNewlinePos < $offset)
// If there was no previous newline, lastNewlinePos = 0
// Start strrpos check from the character before the current character,
// in case the current character is a newline.
$lastNewlinePos = \strrpos($this->fileContents, "\n", -$length + $offset - 1);
return 1 + $offset - ($lastNewlinePos === false ? 0 : $lastNewlinePos + 1);
}
}
@@ -0,0 +1,13 @@
<?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;
/**
* Interface for recognizing functions easily.
* Each Node that implements this interface can be considered a function.
*/
interface FunctionLike {}
@@ -0,0 +1,17 @@
<?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;
class LineCharacterPosition {
public $line;
public $character;
public function __construct(int $line, int $character) {
$this->line = $line;
$this->character = $character;
}
}
@@ -0,0 +1,20 @@
<?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;
class MissingToken extends Token {
public function __construct(int $kind, int $fullStart) {
parent::__construct($kind, $fullStart, $fullStart, 0);
}
public function jsonSerialize() {
return array_merge(
["error" => $this->getTokenKindNameFromValue(TokenKind::MissingToken)],
parent::jsonSerialize()
);
}
}
@@ -0,0 +1,11 @@
<?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;
interface NamespacedNameInterface {
public function getNamespacedName() : ResolvedName;
}
@@ -0,0 +1,50 @@
<?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 Microsoft\PhpParser\Node\NamespaceUseClause;
use Microsoft\PhpParser\Node\NamespaceUseGroupClause;
use Microsoft\PhpParser\Node\QualifiedName;
use Microsoft\PhpParser\Node\Statement\NamespaceDefinition;
use Microsoft\PhpParser\Node\Statement\NamespaceUseDeclaration;
trait NamespacedNameTrait {
public abstract function getNamespaceDefinition();
public abstract function getFileContents() : string;
public abstract function getNameParts() : array;
/**
* Gets resolved name from current namespace. Note that this is not necessarily the *actual* name
* that is resolved during compilation or at runtime. For that, see QualifiedName::getResolvedName().
*
* @return ResolvedName
*/
public function getNamespacedName() : ResolvedName {
$namespaceDefinition = $this->getNamespaceDefinition();
$content = $this->getFileContents();
if ($namespaceDefinition === null) {
// global namespace -> strip namespace\ prefix
return ResolvedName::buildName($this->getNameParts(), $content);
}
if ($namespaceDefinition->name !== null) {
$resolvedName = ResolvedName::buildName($namespaceDefinition->name->nameParts, $content);
} else {
$resolvedName = ResolvedName::buildName([], $content);
}
if (
!($this instanceof QualifiedName && (
($this->parent instanceof NamespaceDefinition) ||
($this->parent instanceof NamespaceUseDeclaration) ||
($this->parent instanceof NamespaceUseClause) ||
($this->parent instanceof NamespaceUseGroupClause)))
) {
$resolvedName->addNameParts($this->getNameParts(), $content);
}
return $resolvedName;
}
}
+698
View File
@@ -0,0 +1,698 @@
<?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 Microsoft\PhpParser\Node\NamespaceUseClause;
use Microsoft\PhpParser\Node\NamespaceUseGroupClause;
use Microsoft\PhpParser\Node\SourceFileNode;
use Microsoft\PhpParser\Node\Statement\NamespaceDefinition;
use Microsoft\PhpParser\Node\Statement\NamespaceUseDeclaration;
abstract class Node implements \JsonSerializable {
const CHILD_NAMES = [];
/** @var array[] Map from node class to array of child keys */
private static $childNames = [];
/** @var Node|null */
public $parent;
public function getNodeKindName() : string {
// Use strrpos (rather than explode) to avoid creating a temporary array.
return substr(static::class, strrpos(static::class, "\\") + 1);
}
/**
* Gets start position of Node, not including leading comments and whitespace.
* @return int
* @throws \Exception
*/
public function getStart() : int {
$child = $this->getChildNodesAndTokens()->current();
if ($child instanceof Node) {
return $child->getStart();
} elseif ($child instanceof Token) {
return $child->start;
}
throw new \Exception("Unknown type in AST");
}
/**
* Gets start position of Node, including leading comments and whitespace
* @return int
* @throws \Exception
*/
public function getFullStart() : int {
foreach($this::CHILD_NAMES as $name) {
if (($child = $this->$name) !== null) {
if (\is_array($child)) {
if(!isset($child[0])) {
continue;
}
$child = $child[0];
}
if ($child instanceof Node) {
return $child->getFullStart();
}
if ($child instanceof Token) {
return $child->fullStart;
}
throw new \Exception("Unknown type in AST: " . \gettype($child));
}
};
throw new \RuntimeException("Could not resolve full start position");
}
/**
* Gets parent of current node (returns null if has no parent)
* @return null|Node
*/
public function getParent() {
return $this->parent;
}
/**
* Gets first ancestor that is an instance of one of the provided classes.
* Returns null if there is no match.
*
* @param string ...$classNames
* @return Node|null
*/
public function getFirstAncestor(...$classNames) {
$ancestor = $this;
while (($ancestor = $ancestor->parent) !== null) {
foreach ($classNames as $className) {
if ($ancestor instanceof $className) {
return $ancestor;
}
}
}
return null;
}
/**
* Gets first child that is an instance of one of the provided classes.
* Returns null if there is no match.
*
* @param array ...$classNames
* @return Node|null
*/
public function getFirstChildNode(...$classNames) {
foreach ($this::CHILD_NAMES as $name) {
$val = $this->$name;
foreach ($classNames as $className) {
if (\is_array($val)) {
foreach ($val as $child) {
if ($child instanceof $className) {
return $child;
}
}
continue;
} elseif ($val instanceof $className) {
return $val;
}
}
}
return null;
}
/**
* Gets first descendant node that is an instance of one of the provided classes.
* Returns null if there is no match.
*
* @param array ...$classNames
* @return Node|null
*/
public function getFirstDescendantNode(...$classNames) {
foreach ($this->getDescendantNodes() as $descendant) {
foreach ($classNames as $className) {
if ($descendant instanceof $className) {
return $descendant;
}
}
}
return null;
}
/**
* Gets root of the syntax tree (returns self if has no parents)
* @return SourceFileNode (expect root to be SourceFileNode unless the tree was manipulated)
*/
public function getRoot() : Node {
$node = $this;
while ($node->parent !== null) {
$node = $node->parent;
}
return $node;
}
/**
* Gets generator containing all descendant Nodes and Tokens.
*
* @param callable|null $shouldDescendIntoChildrenFn
* @return \Generator|Node[]|Token[]
*/
public function getDescendantNodesAndTokens(callable $shouldDescendIntoChildrenFn = null) {
// TODO - write unit tests to prove invariants
// (concatenating all descendant Tokens should produce document, concatenating all Nodes should produce document)
foreach ($this->getChildNodesAndTokens() as $child) {
// Check possible types of $child, most frequent first
if ($child instanceof Node) {
yield $child;
if ($shouldDescendIntoChildrenFn === null || $shouldDescendIntoChildrenFn($child)) {
yield from $child->getDescendantNodesAndTokens($shouldDescendIntoChildrenFn);
}
} elseif ($child instanceof Token) {
yield $child;
}
}
}
/**
* Iterate over all descendant Nodes and Tokens, calling $callback.
* This can often be faster than getDescendantNodesAndTokens
* if you just need to call something and don't need a generator.
*
* @param callable $callback a callback that accepts Node|Token
* @param callable|null $shouldDescendIntoChildrenFn
* @return void
*/
public function walkDescendantNodesAndTokens(callable $callback, callable $shouldDescendIntoChildrenFn = null) {
// TODO - write unit tests to prove invariants
// (concatenating all descendant Tokens should produce document, concatenating all Nodes should produce document)
foreach (static::CHILD_NAMES as $name) {
$child = $this->$name;
// Check possible types of $child, most frequent first
if ($child instanceof Token) {
$callback($child);
} elseif ($child instanceof Node) {
$callback($child);
if ($shouldDescendIntoChildrenFn === null || $shouldDescendIntoChildrenFn($child)) {
$child->walkDescendantNodesAndTokens($callback, $shouldDescendIntoChildrenFn);
}
} elseif (\is_array($child)) {
foreach ($child as $childElement) {
if ($childElement instanceof Token) {
$callback($childElement);
} elseif ($childElement instanceof Node) {
$callback($childElement);
if ($shouldDescendIntoChildrenFn === null || $shouldDescendIntoChildrenFn($childElement)) {
$childElement->walkDescendantNodesAndTokens($callback, $shouldDescendIntoChildrenFn);
}
}
}
}
}
}
/**
* Gets a generator containing all descendant Nodes.
* @param callable|null $shouldDescendIntoChildrenFn
* @return \Generator|Node[]
*/
public function getDescendantNodes(callable $shouldDescendIntoChildrenFn = null) {
foreach ($this->getChildNodes() as $child) {
yield $child;
if ($shouldDescendIntoChildrenFn === null || $shouldDescendIntoChildrenFn($child)) {
yield from $child->getDescendantNodes($shouldDescendIntoChildrenFn);
}
}
}
/**
* Gets generator containing all descendant Tokens.
* @param callable|null $shouldDescendIntoChildrenFn
* @return \Generator|Token[]
*/
public function getDescendantTokens(callable $shouldDescendIntoChildrenFn = null) {
foreach ($this->getChildNodesAndTokens() as $child) {
if ($child instanceof Node) {
if ($shouldDescendIntoChildrenFn == null || $shouldDescendIntoChildrenFn($child)) {
yield from $child->getDescendantTokens($shouldDescendIntoChildrenFn);
}
} elseif ($child instanceof Token) {
yield $child;
}
}
}
/**
* Gets generator containing all child Nodes and Tokens (direct descendants).
* Does not return null elements.
*
* @return \Generator|Token[]|Node[]
*/
public function getChildNodesAndTokens() : \Generator {
foreach ($this::CHILD_NAMES as $name) {
$val = $this->$name;
if (\is_array($val)) {
foreach ($val as $child) {
if ($child !== null) {
yield $name => $child;
}
}
continue;
}
if ($val !== null) {
yield $name => $val;
}
}
}
/**
* Gets generator containing all child Nodes (direct descendants)
* @return \Generator|Node[]
*/
public function getChildNodes() : \Generator {
foreach ($this::CHILD_NAMES as $name) {
$val = $this->$name;
if (\is_array($val)) {
foreach ($val as $child) {
if ($child instanceof Node) {
yield $child;
}
}
continue;
} elseif ($val instanceof Node) {
yield $val;
}
}
}
/**
* Gets generator containing all child Tokens (direct descendants)
*
* @return \Generator|Token[]
*/
public function getChildTokens() {
foreach ($this::CHILD_NAMES as $name) {
$val = $this->$name;
if (\is_array($val)) {
foreach ($val as $child) {
if ($child instanceof Token) {
yield $child;
}
}
continue;
} elseif ($val instanceof Token) {
yield $val;
}
}
}
/**
* Gets array of declared child names (cached).
*
* This is used as an optimization when iterating over nodes: For direct iteration
* PHP will create a properties hashtable on the object, thus doubling memory usage.
* We avoid this by iterating over just the names instead.
*
* @return string[]
*/
public function getChildNames() {
return $this::CHILD_NAMES;
}
/**
* Gets width of a Node (not including comment / whitespace trivia)
*
* @return int
*/
public function getWidth() : int {
$first = $this->getStart();
$last = $this->getEndPosition();
return $last - $first;
}
/**
* Gets width of a Node (including comment / whitespace trivia)
*
* @return int
*/
public function getFullWidth() : int {
$first = $this->getFullStart();
$last = $this->getEndPosition();
return $last - $first;
}
/**
* Gets string representing Node text (not including leading comment + whitespace trivia)
* @return string
*/
public function getText() : string {
$start = $this->getStart();
$end = $this->getEndPosition();
$fileContents = $this->getFileContents();
return \substr($fileContents, $start, $end - $start);
}
/**
* Gets full text of Node (including leading comment + whitespace trivia)
* @return string
*/
public function getFullText() : string {
$start = $this->getFullStart();
$end = $this->getEndPosition();
$fileContents = $this->getFileContents();
return \substr($fileContents, $start, $end - $start);
}
/**
* Gets string representing Node's leading comment and whitespace text.
* @return string
*/
public function getLeadingCommentAndWhitespaceText() : string {
// TODO re-tokenize comments and whitespace
$fileContents = $this->getFileContents();
foreach ($this->getDescendantTokens() as $token) {
return $token->getLeadingCommentsAndWhitespaceText($fileContents);
}
return '';
}
protected function getChildrenKvPairs() {
$result = array();
foreach ($this::CHILD_NAMES as $name) {
$result[$name] = $this->$name;
}
return $result;
}
public function jsonSerialize() {
$kindName = $this->getNodeKindName();
return ["$kindName" => $this->getChildrenKvPairs()];
}
/**
* Get the end index of a Node.
* @return int
* @throws \Exception
*/
public function getEndPosition() {
// TODO test invariant - start of next node is end of previous node
for ($i = \count($childKeys = $this::CHILD_NAMES) - 1; $i >= 0; $i--) {
$lastChildKey = $childKeys[$i];
$lastChild = $this->$lastChildKey;
if (\is_array($lastChild)) {
$lastChild = \end($lastChild);
}
if ($lastChild instanceof Token) {
return $lastChild->fullStart + $lastChild->length;
} elseif ($lastChild instanceof Node) {
return $lastChild->getEndPosition();
}
}
throw new \Exception("Unhandled node type");
}
public function getFileContents() : string {
// TODO consider renaming to getSourceText
return $this->getRoot()->fileContents;
}
public function getUri() : string {
return $this->getRoot()->uri;
}
public function getLastChild() {
$a = iterator_to_array($this->getChildNodesAndTokens());
return \end($a);
}
/**
* Searches descendants to find a Node at the given position.
*
* @param int $pos
* @return Node
*/
public function getDescendantNodeAtPosition(int $pos) {
foreach ($this->getChildNodes() as $child) {
if ($child->containsPosition($pos)) {
$node = $child->getDescendantNodeAtPosition($pos);
if (!is_null($node)) {
return $node;
}
}
}
return $this;
}
/**
* Returns true if the given Node or Token contains the given position.
* @param int $pos
* @return bool
*/
private function containsPosition(int $pos): bool {
return $this->getStart() <= $pos && $pos <= $this->getEndPosition();
}
/**
* Gets leading PHP Doc Comment text corresponding to the current Node.
* Returns last doc comment in leading comment / whitespace trivia,
* and returns null if there is no preceding doc comment.
*
* @return string|null
*/
public function getDocCommentText() {
$leadingTriviaText = $this->getLeadingCommentAndWhitespaceText();
$leadingTriviaTokens = PhpTokenizer::getTokensArrayFromContent(
$leadingTriviaText, ParseContext::SourceElements, $this->getFullStart(), false
);
for ($i = \count($leadingTriviaTokens) - 1; $i >= 0; $i--) {
$token = $leadingTriviaTokens[$i];
if ($token->kind === TokenKind::DocCommentToken) {
return $token->getText($this->getFileContents());
}
}
return null;
}
public function __toString() {
return $this->getText();
}
/**
* @return array|ResolvedName[][]
* @throws \Exception
*/
public function getImportTablesForCurrentScope() {
$namespaceDefinition = $this->getNamespaceDefinition();
// Use declarations can exist in either the global scope, or inside namespace declarations.
// http://php.net/manual/en/language.namespaces.importing.php#language.namespaces.importing.scope
//
// The only code allowed before a namespace declaration is a declare statement, and sub-namespaces are
// additionally unaffected by by import rules of higher-level namespaces. Therefore, we can make the assumption
// that we need not travel up the spine any further once we've found the current namespace.
// http://php.net/manual/en/language.namespaces.definition.php
if ($namespaceDefinition instanceof NamespaceDefinition) {
$topLevelNamespaceStatements = $namespaceDefinition->compoundStatementOrSemicolon instanceof Token
? $namespaceDefinition->parent->statementList // we need to start from the namespace definition.
: $namespaceDefinition->compoundStatementOrSemicolon->statements;
$namespaceFullStart = $namespaceDefinition->getFullStart();
} else {
$topLevelNamespaceStatements = $this->getRoot()->statementList;
$namespaceFullStart = 0;
}
$nodeFullStart = $this->getFullStart();
// TODO optimize performance
// Currently we rebuild the import tables on every call (and therefore every name resolution operation)
// It is likely that a consumer will attempt many consecutive name resolution requests within the same file.
// Therefore, we can consider optimizing on the basis of the "most recently used" import table set.
// The idea: Keep a single set of import tables cached based on a unique root node id, and invalidate
// cache whenever we attempt to resolve a qualified name with a different root node.
//
// In order to make this work, it will probably make sense to change the way we parse namespace definitions.
// https://github.com/Microsoft/tolerant-php-parser/issues/81
//
// Currently the namespace definition only includes a compound statement or semicolon token as one if it's children.
// Instead, we should move to a model where we parse future statements as a child rather than as a separate
// statement. This would enable us to retrieve all the information we would need to find the fully qualified
// name by simply traveling up the spine to find the first ancestor of type NamespaceDefinition.
$namespaceImportTable = $functionImportTable = $constImportTable = [];
$contents = $this->getFileContents();
foreach ($topLevelNamespaceStatements as $useDeclaration) {
if ($useDeclaration->getFullStart() <= $namespaceFullStart) {
continue;
}
if ($useDeclaration->getFullStart() > $nodeFullStart) {
break;
} elseif (!($useDeclaration instanceof NamespaceUseDeclaration)) {
continue;
}
// TODO fix getValues
foreach ((isset($useDeclaration->useClauses) ? $useDeclaration->useClauses->getValues() : []) as $useClause) {
$namespaceNamePartsPrefix = $useClause->namespaceName !== null ? $useClause->namespaceName->nameParts : [];
if ($useClause->groupClauses !== null && $useClause instanceof NamespaceUseClause) {
// use A\B\C\{D\E}; namespace import: ["E" => [A,B,C,D,E]]
// use A\B\C\{D\E as F}; namespace import: ["F" => [A,B,C,D,E]]
// use function A\B\C\{A, B} function import: ["A" => [A,B,C,A], "B" => [A,B,C]]
// use function A\B\C\{const A} const import: ["A" => [A,B,C,A]]
foreach ($useClause->groupClauses->children as $groupClause) {
if (!($groupClause instanceof NamespaceUseGroupClause)) {
continue;
}
$namespaceNameParts = \array_merge($namespaceNamePartsPrefix, $groupClause->namespaceName->nameParts);
$functionOrConst = $groupClause->functionOrConst ?? $useDeclaration->functionOrConst;
$alias = $groupClause->namespaceAliasingClause === null
? $groupClause->namespaceName->getLastNamePart()->getText($contents)
: $groupClause->namespaceAliasingClause->name->getText($contents);
$this->addToImportTable(
$alias, $functionOrConst, $namespaceNameParts, $contents,
$namespaceImportTable, $functionImportTable, $constImportTable
);
}
} else {
// use A\B\C; namespace import: ["C" => [A,B,C]]
// use A\B\C as D; namespace import: ["D" => [A,B,C]]
// use function A\B\C as D function import: ["D" => [A,B,C]]
// use A\B, C\D; namespace import: ["B" => [A,B], "D" => [C,D]]
$alias = $useClause->namespaceAliasingClause === null
? $useClause->namespaceName->getLastNamePart()->getText($contents)
: $useClause->namespaceAliasingClause->name->getText($contents);
$functionOrConst = $useDeclaration->functionOrConst;
$namespaceNameParts = $namespaceNamePartsPrefix;
$this->addToImportTable(
$alias, $functionOrConst, $namespaceNameParts, $contents,
$namespaceImportTable, $functionImportTable, $constImportTable
);
}
}
}
return [$namespaceImportTable, $functionImportTable, $constImportTable];
}
/**
* Gets corresponding NamespaceDefinition for Node. Returns null if in global namespace.
*
* @return NamespaceDefinition|null
*/
public function getNamespaceDefinition() {
$namespaceDefinition = $this instanceof NamespaceDefinition
? $this
: $this->getFirstAncestor(NamespaceDefinition::class, SourceFileNode::class);
if ($namespaceDefinition instanceof NamespaceDefinition && !($namespaceDefinition->parent instanceof SourceFileNode)) {
$namespaceDefinition = $namespaceDefinition->getFirstAncestor(SourceFileNode::class);
}
if ($namespaceDefinition === null) {
// TODO provide a way to throw errors without crashing consumer
throw new \Exception("Invalid tree - SourceFileNode must always exist at root of tree.");
}
$fullStart = $this->getFullStart();
$lastNamespaceDefinition = null;
if ($namespaceDefinition instanceof SourceFileNode) {
foreach ($namespaceDefinition->getChildNodes() as $childNode) {
if ($childNode instanceof NamespaceDefinition && $childNode->getFullStart() < $fullStart) {
$lastNamespaceDefinition = $childNode;
}
}
}
if ($lastNamespaceDefinition !== null && $lastNamespaceDefinition->compoundStatementOrSemicolon instanceof Token) {
$namespaceDefinition = $lastNamespaceDefinition;
} elseif ($namespaceDefinition instanceof SourceFileNode) {
$namespaceDefinition = null;
}
return $namespaceDefinition;
}
public function getPreviousSibling() {
// TODO make more efficient
$parent = $this->parent;
if ($parent === null) {
return null;
}
$prevSibling = null;
foreach ($parent::CHILD_NAMES as $name) {
$val = $parent->$name;
if (\is_array($val)) {
foreach ($val as $sibling) {
if ($sibling === $this) {
return $prevSibling;
} elseif ($sibling instanceof Node) {
$prevSibling = $sibling;
}
}
continue;
} elseif ($val instanceof Node) {
if ($val === $this) {
return $prevSibling;
}
$prevSibling = $val;
}
}
return null;
}
/**
* Add the alias and resolved name to the corresponding namespace, function, or const import table.
* If the alias already exists, it will get replaced by the most recent using.
*
* TODO - worth throwing an error here in stead?
*/
private function addToImportTable($alias, $functionOrConst, $namespaceNameParts, $contents, & $namespaceImportTable, & $functionImportTable, & $constImportTable):array
{
if ($alias !== null) {
if ($functionOrConst === null) {
// namespaces are case-insensitive
// $alias = \strtolower($alias);
$namespaceImportTable[$alias] = ResolvedName::buildName($namespaceNameParts, $contents);
return array($namespaceImportTable, $functionImportTable, $constImportTable);
} elseif ($functionOrConst->kind === TokenKind::FunctionKeyword) {
// functions are case-insensitive
// $alias = \strtolower($alias);
$functionImportTable[$alias] = ResolvedName::buildName($namespaceNameParts, $contents);
return array($namespaceImportTable, $functionImportTable, $constImportTable);
} elseif ($functionOrConst->kind === TokenKind::ConstKeyword) {
// constants are case-sensitive
$constImportTable[$alias] = ResolvedName::buildName($namespaceNameParts, $contents);
return array($namespaceImportTable, $functionImportTable, $constImportTable);
}
return array($namespaceImportTable, $functionImportTable, $constImportTable);
}
return array($namespaceImportTable, $functionImportTable, $constImportTable);
}
/**
* This is overridden in subclasses
* @return Diagnostic|null - Callers should use DiagnosticsProvider::getDiagnostics instead
* @internal
*/
public function getDiagnosticForNode() {
return null;
}
}
@@ -0,0 +1,32 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Node\DelimitedList\UseVariableNameList;
use Microsoft\PhpParser\Token;
class AnonymousFunctionUseClause extends Node {
/** @var Token */
public $useKeyword;
/** @var Token */
public $openParen;
/** @var UseVariableNameList */
public $useVariableNameList;
/** @var Token */
public $closeParen;
const CHILD_NAMES = [
'useKeyword',
'openParen',
'useVariableNameList',
'closeParen'
];
}
@@ -0,0 +1,36 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class ArrayElement extends Node {
/** @var Expression|null */
public $elementKey;
/** @var Token|null */
public $arrowToken;
/** @var Token|null */
public $byRef;
/** @var Token|null if this is set for PHP 7.4's array spread operator, then other preceding tokens aren't */
public $dotDotDot;
/** @var Expression */
public $elementValue;
const CHILD_NAMES = [
'elementKey',
'arrowToken',
'byRef',
'dotDotDot',
'elementValue'
];
}
@@ -0,0 +1,28 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class CaseStatementNode extends Node {
/** @var Token */
public $caseKeyword;
/** @var Expression */
public $expression;
/** @var Token */
public $defaultLabelTerminator;
/** @var StatementNode[] */
public $statementList;
const CHILD_NAMES = [
'caseKeyword',
'expression',
'defaultLabelTerminator',
'statementList'
];
}
@@ -0,0 +1,43 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class CatchClause extends Node {
/** @var Token */
public $catch;
/** @var Token */
public $openParen;
/** @var QualifiedName */
public $qualifiedName;
/**
* @var QualifiedName[]|Token[] Remaining tokens and qualified names in the catch clause
* (e.g. `catch (FirstException|SecondException $x)` would contain
* the representation of `|SecondException`)
*
* TODO: In the next backwards incompatible release, replace qualifiedName with qualifiedNameList?
*/
public $otherQualifiedNameList;
/** @var Token */
public $variableName;
/** @var Token */
public $closeParen;
/** @var StatementNode */
public $compoundStatement;
const CHILD_NAMES = [
'catch',
'openParen',
'qualifiedName',
'otherQualifiedNameList',
'variableName',
'closeParen',
'compoundStatement'
];
}
@@ -0,0 +1,23 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class ClassBaseClause extends Node {
/** @var Token */
public $extendsKeyword;
/** @var QualifiedName */
public $baseClass;
const CHILD_NAMES = [
'extendsKeyword',
'baseClass'
];
}
@@ -0,0 +1,32 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class ClassConstDeclaration extends Node {
/** @var Token[] */
public $modifiers;
/** @var Token */
public $constKeyword;
/** @var DelimitedList\ConstElementList */
public $constElements;
/** @var Token */
public $semicolon;
const CHILD_NAMES = [
'modifiers',
'constKeyword',
'constElements',
'semicolon'
];
}
@@ -0,0 +1,23 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class ClassInterfaceClause extends Node {
/** @var Token */
public $implementsKeyword;
/** @var DelimitedList\QualifiedNameList|null */
public $interfaceNameList;
const CHILD_NAMES = [
'implementsKeyword',
'interfaceNameList'
];
}
@@ -0,0 +1,27 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class ClassMembersNode extends Node {
/** @var Token */
public $openBrace;
/** @var Node[] */
public $classMemberDeclarations;
/** @var Token */
public $closeBrace;
const CHILD_NAMES = [
'openBrace',
'classMemberDeclarations',
'closeBrace'
];
}
@@ -0,0 +1,39 @@
<?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\Node;
use Microsoft\PhpParser\NamespacedNameInterface;
use Microsoft\PhpParser\NamespacedNameTrait;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class ConstElement extends Node implements NamespacedNameInterface {
use NamespacedNameTrait;
/** @var Token */
public $name;
/** @var Token */
public $equalsToken;
/** @var Expression */
public $assignment;
const CHILD_NAMES = [
'name',
'equalsToken',
'assignment'
];
public function getNameParts() : array {
return [$this->name];
}
public function getName() {
return $this->name->getText($this->getFileContents());
}
}
@@ -0,0 +1,25 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class DeclareDirective extends Node {
/** @var Token */
public $name;
/** @var Token */
public $equals;
/** @var Token */
public $literal;
const CHILD_NAMES = [
'name',
'equals',
'literal'
];
}
@@ -0,0 +1,25 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class DefaultStatementNode extends Node {
/** @var Token */
public $defaultKeyword;
/** @var Token */
public $defaultLabelTerminator;
/** @var StatementNode[] */
public $statementList;
const CHILD_NAMES = [
'defaultKeyword',
'defaultLabelTerminator',
'statementList'
];
}
@@ -0,0 +1,51 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
use Microsoft\PhpParser\TokenKind;
abstract class DelimitedList extends Node {
/** @var Token[]|Node[] */
public $children;
const CHILD_NAMES = [
'children'
];
const DELIMITERS = [TokenKind::CommaToken, TokenKind::BarToken, TokenKind::SemicolonToken];
public function getElements() : \Generator {
foreach ($this->children as $child) {
if ($child instanceof Node) {
yield $child;
} elseif ($child instanceof Token && !\in_array($child->kind, self::DELIMITERS)) {
yield $child;
}
}
}
public function getValues() {
foreach ($this->children as $idx=>$value) {
if ($idx % 2 == 0) {
yield $value;
}
}
}
public function addElement($node) {
if ($node === null) {
return;
}
if ($this->children === null) {
$this->children = [$node];
return;
}
$this->children[] = $node;
}
}
@@ -0,0 +1,12 @@
<?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\Node\DelimitedList;
use Microsoft\PhpParser\Node\DelimitedList;
class ArgumentExpressionList extends DelimitedList {
}
@@ -0,0 +1,12 @@
<?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\Node\DelimitedList;
use Microsoft\PhpParser\Node\DelimitedList;
class ArrayElementList extends DelimitedList {
}
@@ -0,0 +1,12 @@
<?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\Node\DelimitedList;
use Microsoft\PhpParser\Node\DelimitedList;
class ConstElementList extends DelimitedList {
}
@@ -0,0 +1,12 @@
<?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\Node\DelimitedList;
use Microsoft\PhpParser\Node\DelimitedList;
class ExpressionList extends DelimitedList {
}
@@ -0,0 +1,12 @@
<?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\Node\DelimitedList;
use Microsoft\PhpParser\Node\DelimitedList;
class ListExpressionList extends DelimitedList {
}
@@ -0,0 +1,12 @@
<?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\Node\DelimitedList;
use Microsoft\PhpParser\Node\DelimitedList;
class NamespaceUseClauseList extends DelimitedList {
}
@@ -0,0 +1,12 @@
<?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\Node\DelimitedList;
use Microsoft\PhpParser\Node\DelimitedList;
class NamespaceUseGroupClauseList extends DelimitedList {
}
@@ -0,0 +1,12 @@
<?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\Node\DelimitedList;
use Microsoft\PhpParser\Node\DelimitedList;
class ParameterDeclarationList extends DelimitedList {
}
@@ -0,0 +1,12 @@
<?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\Node\DelimitedList;
use Microsoft\PhpParser\Node\DelimitedList;
class QualifiedNameList extends DelimitedList {
}
@@ -0,0 +1,12 @@
<?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\Node\DelimitedList;
use Microsoft\PhpParser\Node\DelimitedList;
class QualifiedNameParts extends DelimitedList {
}
@@ -0,0 +1,12 @@
<?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\Node\DelimitedList;
use Microsoft\PhpParser\Node\DelimitedList;
class StaticVariableNameList extends DelimitedList {
}
@@ -0,0 +1,12 @@
<?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\Node\DelimitedList;
use Microsoft\PhpParser\Node\DelimitedList;
class TraitSelectOrAliasClauseList extends DelimitedList {
}
@@ -0,0 +1,12 @@
<?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\Node\DelimitedList;
use Microsoft\PhpParser\Node\DelimitedList;
class UseVariableNameList extends DelimitedList {
}
@@ -0,0 +1,12 @@
<?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\Node\DelimitedList;
use Microsoft\PhpParser\Node\DelimitedList;
class VariableNameList extends DelimitedList {
}
@@ -0,0 +1,25 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class ElseClauseNode extends Node {
/** @var Token */
public $elseKeyword;
/** @var Token */
public $colon;
/** @var StatementNode|StatementNode[] */
public $statements;
const CHILD_NAMES = [
'elseKeyword',
'colon',
'statements'
];
}
@@ -0,0 +1,34 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class ElseIfClauseNode extends Node {
/** @var Token */
public $elseIfKeyword;
/** @var Token */
public $openParen;
/** @var Expression */
public $expression;
/** @var Token */
public $closeParen;
/** @var Token|null */
public $colon;
/** @var StatementNode|StatementNode[] */
public $statements;
const CHILD_NAMES = [
'elseIfKeyword',
'openParen',
'expression',
'closeParen',
'colon',
'statements'
];
}
@@ -0,0 +1,12 @@
<?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\Node;
use Microsoft\PhpParser\Node;
abstract class Expression extends Node {
}
@@ -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\Node\Expression;
use Microsoft\PhpParser\FunctionLike;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Node\FunctionBody;
use Microsoft\PhpParser\Node\FunctionHeader;
use Microsoft\PhpParser\Node\FunctionReturnType;
use Microsoft\PhpParser\Node\FunctionUseClause;
use Microsoft\PhpParser\Token;
class AnonymousFunctionCreationExpression extends Expression implements FunctionLike {
/** @var Token|null */
public $staticModifier;
use FunctionHeader, FunctionUseClause, FunctionReturnType, FunctionBody;
const CHILD_NAMES = [
'staticModifier',
// FunctionHeader
'functionKeyword',
'byRefToken',
'name',
'openParen',
'parameters',
'closeParen',
// FunctionUseClause
'anonymousFunctionUseClause',
// FunctionReturnType
'colonToken',
'questionToken',
'returnType',
'otherReturnTypes',
// FunctionBody
'compoundStatementOrSemicolon'
];
}
@@ -0,0 +1,27 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class ArgumentExpression extends Expression {
/** @var Token|null */
public $byRefToken; // TODO removed in newer versions of PHP. Also only accept variable, not expression if byRef
/** @var Token|null */
public $dotDotDotToken;
/** @var Expression */
public $expression;
const CHILD_NAMES = [
'byRefToken',
'dotDotDotToken',
'expression'
];
}
@@ -0,0 +1,33 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\DelimitedList;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class ArrayCreationExpression extends Expression {
/** @var Token|null */
public $arrayKeyword;
/** @var Token */
public $openParenOrBracket;
/** @var DelimitedList\ArrayElementList */
public $arrayElements;
/** @var Token */
public $closeParenOrBracket;
const CHILD_NAMES = [
'arrayKeyword',
'openParenOrBracket',
'arrayElements',
'closeParenOrBracket'
];
}
@@ -0,0 +1,49 @@
<?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\Node\Expression;
use Microsoft\PhpParser\FunctionLike;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Node\FunctionHeader;
use Microsoft\PhpParser\Node\FunctionReturnType;
use Microsoft\PhpParser\Token;
class ArrowFunctionCreationExpression extends Expression implements FunctionLike {
/** @var Token|null */
public $staticModifier;
use FunctionHeader, FunctionReturnType;
/** @var Token `=>` */
public $arrowToken;
/** @var Node|Token */
public $resultExpression;
const CHILD_NAMES = [
'staticModifier',
// FunctionHeader
'functionKeyword',
'byRefToken',
'name',
'openParen',
'parameters',
'closeParen',
// FunctionReturnType
'colonToken',
'questionToken',
'returnType',
'otherReturnTypes',
// body
'arrowToken',
'resultExpression',
];
}
@@ -0,0 +1,32 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class AssignmentExpression extends BinaryExpression {
/** @var Expression */
public $leftOperand;
/** @var Token */
public $operator;
/** @var Token */
public $byRef;
/** @var Expression */
public $rightOperand;
const CHILD_NAMES = [
'leftOperand',
'operator',
'byRef',
'rightOperand'
];
}
@@ -0,0 +1,28 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class BinaryExpression extends Expression {
/** @var Expression */
public $leftOperand;
/** @var Token */
public $operator;
/** @var Expression */
public $rightOperand;
const CHILD_NAMES = [
'leftOperand',
'operator',
'rightOperand'
];
}
@@ -0,0 +1,27 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class BracedExpression extends Expression {
/** @var Token */
public $openBrace;
/** @var Expression */
public $expression;
/** @var Token */
public $closeBrace;
const CHILD_NAMES = [
'openBrace',
'expression',
'closeBrace'
];
}
@@ -0,0 +1,32 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\DelimitedList;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class CallExpression extends Expression {
/** @var Expression */
public $callableExpression;
/** @var Token */
public $openParen;
/** @var DelimitedList\ArgumentExpressionList|null */
public $argumentExpressionList;
/** @var Token */
public $closeParen;
const CHILD_NAMES = [
'callableExpression',
'openParen',
'argumentExpressionList',
'closeParen'
];
}
@@ -0,0 +1,31 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Token;
class CastExpression extends UnaryExpression {
/** @var Token */
public $openParen;
/** @var Token */
public $castType;
/** @var Token */
public $closeParen;
/** @var Variable */
public $operand;
const CHILD_NAMES = [
'openParen',
'castType',
'closeParen',
'operand'
];
}
@@ -0,0 +1,24 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class CloneExpression extends Expression {
/** @var Token */
public $cloneKeyword;
/** @var Expression */
public $expression;
const CHILD_NAMES = [
'cloneKeyword',
'expression'
];
}
@@ -0,0 +1,34 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Node\DelimitedList\ExpressionList;
use Microsoft\PhpParser\Token;
/**
* This represents either a literal echo expression (`echo expr`)
* or a short echo tag (`<?= expr...`)
*
* TODO: An echo statement cannot be used as an expression.
* Consider refactoring this to become EchoStatement in a future backwards incompatible release.
*/
class EchoExpression extends Expression {
/**
* @var Token|null this is null if generated from `<?=`
*/
public $echoKeyword;
/** @var ExpressionList */
public $expressions;
const CHILD_NAMES = [
'echoKeyword',
'expressions'
];
}
@@ -0,0 +1,32 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class EmptyIntrinsicExpression extends Expression {
/** @var Token */
public $emptyKeyword;
/** @var Token */
public $openParen;
/** @var Expression */
public $expression;
/** @var Token */
public $closeParen;
const CHILD_NAMES = [
'emptyKeyword',
'openParen',
'expression',
'closeParen'
];
}
@@ -0,0 +1,23 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Token;
class ErrorControlExpression extends UnaryExpression {
/** @var Token */
public $operator;
/** @var UnaryExpression */
public $operand;
const CHILD_NAMES = [
'operator',
'operand'
];
}
@@ -0,0 +1,32 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class EvalIntrinsicExpression extends Expression {
/** @var Token */
public $evalKeyword;
/** @var Token */
public $openParen;
/** @var Expression */
public $expression;
/** @var Token */
public $closeParen;
const CHILD_NAMES = [
'evalKeyword',
'openParen',
'expression',
'closeParen'
];
}
@@ -0,0 +1,32 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class ExitIntrinsicExpression extends Expression {
/** @var Token */
public $exitOrDieKeyword;
/** @var Token|null */
public $openParen;
/** @var Expression|null */
public $expression;
/** @var Token|null */
public $closeParen;
const CHILD_NAMES = [
'exitOrDieKeyword',
'openParen',
'expression',
'closeParen'
];
}
@@ -0,0 +1,33 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\DelimitedList;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class IssetIntrinsicExpression extends Expression {
/** @var Token */
public $issetKeyword;
/** @var Token */
public $openParen;
/** @var DelimitedList\ExpressionList */
public $expressions;
/** @var Token */
public $closeParen;
const CHILD_NAMES = [
'issetKeyword',
'openParen',
'expressions',
'closeParen'
];
}
@@ -0,0 +1,33 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\DelimitedList;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class ListIntrinsicExpression extends Expression {
/** @var Token */
public $listKeyword;
/** @var Token */
public $openParen;
/** @var DelimitedList\ListExpressionList */
public $listElements;
/** @var Token */
public $closeParen;
const CHILD_NAMES = [
'listKeyword',
'openParen',
'listElements',
'closeParen'
];
}
@@ -0,0 +1,28 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class MemberAccessExpression extends Expression {
/** @var Expression */
public $dereferencableExpression;
/** @var Token */
public $arrowToken;
/** @var Token */
public $memberName;
const CHILD_NAMES = [
'dereferencableExpression',
'arrowToken',
'memberName'
];
}
@@ -0,0 +1,53 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\ClassBaseClause;
use Microsoft\PhpParser\Node\ClassInterfaceClause;
use Microsoft\PhpParser\Node\ClassMembersNode;
use Microsoft\PhpParser\Node\DelimitedList;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Node\QualifiedName;
use Microsoft\PhpParser\Token;
class ObjectCreationExpression extends Expression {
/** @var Token */
public $newKeword;
/** @var QualifiedName|Variable|Token */
public $classTypeDesignator;
/** @var Token|null */
public $openParen;
/** @var DelimitedList\ArgumentExpressionList|null */
public $argumentExpressionList;
/** @var Token|null */
public $closeParen;
/** @var ClassBaseClause|null */
public $classBaseClause;
/** @var ClassInterfaceClause|null */
public $classInterfaceClause;
/** @var ClassMembersNode|null */
public $classMembers;
const CHILD_NAMES = [
'newKeword', // TODO
'classTypeDesignator',
'openParen',
'argumentExpressionList',
'closeParen',
'classBaseClause',
'classInterfaceClause',
'classMembers'
];
}
@@ -0,0 +1,28 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class ParenthesizedExpression extends Expression {
/** @var Token */
public $openParen;
/** @var Expression */
public $expression;
/** @var Token */
public $closeParen;
const CHILD_NAMES = [
'openParen',
'expression',
'closeParen'
];
}
@@ -0,0 +1,23 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class PostfixUpdateExpression extends Expression {
/** @var Variable */
public $operand;
/** @var Token */
public $incrementOrDecrementOperator;
const CHILD_NAMES = [
'operand',
'incrementOrDecrementOperator'
];
}
@@ -0,0 +1,23 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Token;
class PrefixUpdateExpression extends UnaryExpression {
/** @var Token */
public $incrementOrDecrementOperator;
/** @var Variable */
public $operand;
const CHILD_NAMES = [
'incrementOrDecrementOperator',
'operand'
];
}
@@ -0,0 +1,24 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class PrintIntrinsicExpression extends Expression {
/** @var Token */
public $printKeyword;
/** @var Expression */
public $expression;
const CHILD_NAMES = [
'printKeyword',
'expression'
];
}
@@ -0,0 +1,29 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Node\QualifiedName;
use Microsoft\PhpParser\Token;
class ScopedPropertyAccessExpression extends Expression {
/** @var Expression|QualifiedName|Token */
public $scopeResolutionQualifier;
/** @var Token */
public $doubleColon;
/** @var Token|Variable */
public $memberName;
const CHILD_NAMES = [
'scopeResolutionQualifier',
'doubleColon',
'memberName'
];
}
@@ -0,0 +1,22 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class ScriptInclusionExpression extends Expression {
/** @var Token */
public $requireOrIncludeKeyword;
/** @var Expression */
public $expression;
const CHILD_NAMES = [
'requireOrIncludeKeyword',
'expression'
];
}
@@ -0,0 +1,32 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class SubscriptExpression extends Expression {
/** @var Expression */
public $postfixExpression;
/** @var Token */
public $openBracketOrBrace;
/** @var Expression */
public $accessExpression;
/** @var Token */
public $closeBracketOrBrace;
const CHILD_NAMES = [
'postfixExpression',
'openBracketOrBrace',
'accessExpression',
'closeBracketOrBrace'
];
}
@@ -0,0 +1,36 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class TernaryExpression extends Expression {
/** @var Expression|Token (only a token when token before '?' is invalid/missing) */
public $condition;
/** @var Token */
public $questionToken;
/** @var Expression */
public $ifExpression;
/** @var Token */
public $colonToken;
/** @var Expression */
public $elseExpression;
const CHILD_NAMES = [
'condition',
'questionToken',
'ifExpression',
'colonToken',
'elseExpression'
];
}
@@ -0,0 +1,18 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
class UnaryExpression extends Expression {
/** @var UnaryExpression|Variable */
public $operand;
const CHILD_NAMES = [
'operand'
];
}
@@ -0,0 +1,23 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Token;
class UnaryOpExpression extends UnaryExpression {
/** @var Token */
public $operator;
/** @var UnaryExpression */
public $operand;
const CHILD_NAMES = [
'operator',
'operand'
];
}
@@ -0,0 +1,33 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\DelimitedList;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class UnsetIntrinsicExpression extends Expression {
/** @var Token */
public $unsetKeyword;
/** @var Token */
public $openParen;
/** @var DelimitedList\ExpressionList */
public $expressions;
/** @var Token */
public $closeParen;
const CHILD_NAMES = [
'unsetKeyword',
'openParen',
'expressions',
'closeParen'
];
}
@@ -0,0 +1,33 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class Variable extends Expression {
/** @var Token */
public $dollar;
/** @var Token|Variable|BracedExpression */
public $name;
const CHILD_NAMES = [
'dollar',
'name'
];
public function getName() {
if (
$this->name instanceof Token &&
$name = ltrim($this->name->getText($this->getFileContents()), '$')
) {
return $name;
}
return null;
}
}
@@ -0,0 +1,21 @@
<?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\Node\Expression;
use Microsoft\PhpParser\Node\ArrayElement;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class YieldExpression extends Expression {
/** @var Token */
public $yieldOrYieldFromKeyword;
/** @var ArrayElement */
public $arrayElement;
const CHILD_NAMES = ['yieldOrYieldFromKeyword', 'arrayElement'];
}
@@ -0,0 +1,22 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class FinallyClause extends Node {
/** @var Token */
public $finallyToken;
/** @var StatementNode */
public $compoundStatement;
const CHILD_NAMES = [
'finallyToken',
'compoundStatement'
];
}
@@ -0,0 +1,22 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class ForeachKey extends Node {
/** @var Expression */
public $expression;
/** @var Token */
public $arrow;
const CHILD_NAMES = [
'expression',
'arrow'
];
}
@@ -0,0 +1,22 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class ForeachValue extends Node {
/** @var Token|null */
public $ampersand;
/** @var Expression */
public $expression;
const CHILD_NAMES = [
'ampersand',
'expression'
];
}
@@ -0,0 +1,15 @@
<?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\Node;
use Microsoft\PhpParser\Node\Statement\CompoundStatementNode;
use Microsoft\PhpParser\Token;
trait FunctionBody {
/** @var CompoundStatementNode|Token */
public $compoundStatementOrSemicolon;
}
@@ -0,0 +1,24 @@
<?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\Node;
use Microsoft\PhpParser\Token;
trait FunctionHeader {
/** @var Token */
public $functionKeyword;
/** @var Token */
public $byRefToken;
/** @var null|Token */
public $name;
/** @var Token */
public $openParen;
/** @var DelimitedList\ParameterDeclarationList */
public $parameters;
/** @var Token */
public $closeParen;
}
@@ -0,0 +1,20 @@
<?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\Node;
use Microsoft\PhpParser\Token;
trait FunctionReturnType {
/** @var Token */
public $colonToken;
/** @var Token|null */
public $questionToken;
/** @var Token|QualifiedName */
public $returnType;
/** @var DelimitedList\QualifiedNameList|null TODO: Merge with returnType in a future backwards incompatible release */
public $otherReturnTypes;
}
@@ -0,0 +1,12 @@
<?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\Node;
trait FunctionUseClause {
/** @var AnonymousFunctionUseClause|null */
public $anonymousFunctionUseClause;
}
@@ -0,0 +1,23 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class InterfaceBaseClause extends Node {
/** @var Token */
public $extendsKeyword;
/** @var DelimitedList\QualifiedNameList */
public $interfaceNameList;
const CHILD_NAMES = [
'extendsKeyword',
'interfaceNameList'
];
}
@@ -0,0 +1,27 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class InterfaceMembers extends Node {
/** @var Token */
public $openBrace;
/** @var Node[] */
public $interfaceMemberDeclarations;
/** @var Token */
public $closeBrace;
const CHILD_NAMES = [
'openBrace',
'interfaceMemberDeclarations',
'closeBrace'
];
}
@@ -0,0 +1,82 @@
<?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\Node;
use Microsoft\PhpParser\Diagnostic;
use Microsoft\PhpParser\DiagnosticKind;
use Microsoft\PhpParser\DiagnosticsProvider;
use Microsoft\PhpParser\FunctionLike;
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;
const CHILD_NAMES = [
'modifiers',
// FunctionHeader
'functionKeyword',
'byRefToken',
'name',
'openParen',
'parameters',
'closeParen',
// FunctionReturnType
'colonToken',
'questionToken',
'returnType',
'otherReturnTypes',
// FunctionBody
'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() {
return $this->name->getText($this->getFileContents());
}
/**
* @return Diagnostic|null - Callers should use DiagnosticsProvider::getDiagnostics instead
* @internal
* @override
*/
public function getDiagnosticForNode() {
foreach ($this->modifiers as $modifier) {
if ($modifier->kind === TokenKind::VarKeyword) {
return new Diagnostic(
DiagnosticKind::Error,
"Unexpected modifier '" . DiagnosticsProvider::getTextForTokenKind($modifier->kind) . "'",
$modifier->start,
$modifier->length
);
}
}
return null;
}
}
@@ -0,0 +1,32 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class MissingMemberDeclaration extends Node {
/** @var Token[] */
public $modifiers;
/** @var Token|null needed along with typeDeclaration for what looked like typed property declarations but was missing VariableName */
public $questionToken;
/** @var QualifiedName|Token|null */
public $typeDeclaration;
/** @var DelimitedList\QualifiedNameList|null */
public $otherTypeDeclarations;
const CHILD_NAMES = [
'modifiers',
'questionToken',
'typeDeclaration',
'otherTypeDeclarations',
];
}
@@ -0,0 +1,22 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class NamespaceAliasingClause extends Node {
/** @var Token */
public $asKeyword;
/** @var Token */
public $name;
const CHILD_NAMES = [
'asKeyword',
'name'
];
}
@@ -0,0 +1,32 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Node\DelimitedList;
use Microsoft\PhpParser\Token;
class NamespaceUseClause extends Node {
/** @var QualifiedName */
public $namespaceName;
/** @var NamespaceAliasingClause */
public $namespaceAliasingClause;
/** @var Token|null */
public $openBrace;
/** @var DelimitedList\NamespaceUseGroupClauseList|null */
public $groupClauses;
/** @var Token|null */
public $closeBrace;
const CHILD_NAMES = [
'namespaceName',
'namespaceAliasingClause',
'openBrace',
'groupClauses',
'closeBrace'
];
}
@@ -0,0 +1,26 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class NamespaceUseGroupClause extends Node {
/** @var Token */
public $functionOrConst;
/** @var QualifiedName */
public $namespaceName;
/** @var NamespaceAliasingClause */
public $namespaceAliasingClause;
const CHILD_NAMES = [
'functionOrConst',
'namespaceName',
'namespaceAliasingClause'
];
}
@@ -0,0 +1,18 @@
<?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\Node;
use Microsoft\PhpParser\Token;
class NumericLiteral extends Expression {
/** @var Token */
public $children;
const CHILD_NAMES = [
'children'
];
}
@@ -0,0 +1,57 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class Parameter extends Node {
/** @var Token|null */
public $questionToken;
/** @var QualifiedName|Token|null */
public $typeDeclaration;
/**
* @var DelimitedList\QualifiedNameList a list of other types, to support php 8 union types while remaining backwards compatible.
* TODO: Merge with typeDeclaration in a future backwards incompatible release.
*/
public $otherTypeDeclarations;
/** @var Token|null */
public $byRefToken;
/** @var Token|null */
public $dotDotDotToken;
/** @var Token */
public $variableName;
/** @var Token|null */
public $equalsToken;
/** @var null|Expression */
public $default;
const CHILD_NAMES = [
'questionToken',
'typeDeclaration',
'otherTypeDeclarations',
'byRefToken',
'dotDotDotToken',
'variableName',
'equalsToken',
'default'
];
public function isVariadic() {
return $this->byRefToken !== null;
}
public function getName() {
if (
$this->variableName instanceof Token &&
$name = substr($this->variableName->getText($this->getFileContents()), 1)
) {
return $name;
}
return null;
}
}
@@ -0,0 +1,56 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
use Microsoft\PhpParser\TokenKind;
class PropertyDeclaration extends Node {
/** @var Token[] */
public $modifiers;
/** @var Token|null question token for PHP 7.4 type declaration */
public $questionToken;
/** @var QualifiedName|Token|null */
public $typeDeclaration;
/**
* @var DelimitedList\QualifiedNameList|null
* TODO: Unify with typeDeclaration in a future backwards incompatible release
*/
public $otherTypeDeclarations;
/** @var DelimitedList\ExpressionList */
public $propertyElements;
/** @var Token */
public $semicolon;
const CHILD_NAMES = [
'modifiers',
'questionToken',
'typeDeclaration',
'otherTypeDeclarations',
'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;
}
}
@@ -0,0 +1,192 @@
<?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\Node;
use Microsoft\PhpParser\NamespacedNameInterface;
use Microsoft\PhpParser\NamespacedNameTrait;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Node\Expression\AnonymousFunctionCreationExpression;
use Microsoft\PhpParser\Node\Expression\ArrowFunctionCreationExpression;
use Microsoft\PhpParser\Node\Expression\CallExpression;
use Microsoft\PhpParser\Node\Expression\ObjectCreationExpression;
use Microsoft\PhpParser\ResolvedName;
use Microsoft\PhpParser\Token;
use Microsoft\PhpParser\TokenKind;
class QualifiedName extends Node implements NamespacedNameInterface {
use NamespacedNameTrait;
/** @var Token */
public $globalSpecifier; // \_opt
/** @var RelativeSpecifier */
public $relativeSpecifier; // namespace\
/** @var array */
public $nameParts;
const CHILD_NAMES = [
'globalSpecifier',
'relativeSpecifier',
'nameParts'
];
/**
* Checks whether a QualifiedName is prefixed with a backslash global specifier.
* @return bool
*/
public function isFullyQualifiedName() : bool {
return isset($this->globalSpecifier);
}
/**
* Checks whether a QualifiedName begins with a "namespace" keyword
* @return bool
*/
public function isRelativeName() : bool {
return isset($this->relativeSpecifier);
}
/**
* Checks whether a Name includes at least one namespace separator (and is neither fully-qualified nor relative)
* @return bool
*/
public function isQualifiedName() : bool {
return
!$this->isFullyQualifiedName() &&
!$this->isRelativeName() &&
\count($this->nameParts) > 1; // at least one namespace separator
}
/**
* Checks whether a name is does not include a namespace separator.
* @return bool
*/
public function isUnqualifiedName() : bool {
return !($this->isFullyQualifiedName() || $this->isRelativeName() || $this->isQualifiedName());
}
/**
* Gets resolved name based on name resolution rules defined in:
* http://php.net/manual/en/language.namespaces.rules.php
*
* Returns null if one of the following conditions is met:
* - name resolution is not valid for this element (e.g. part of the name in a namespace definition)
* - name cannot be resolved (unqualified namespaced function/constant names that are not explicitly imported.)
*
* @return null|string|ResolvedName
* @throws \Exception
*/
public function getResolvedName($namespaceDefinition = null) {
// Name resolution not applicable to constructs that define symbol names or aliases.
if (($this->parent instanceof Node\Statement\NamespaceDefinition && $this->parent->name->getStart() === $this->getStart()) ||
$this->parent instanceof Node\Statement\NamespaceUseDeclaration ||
$this->parent instanceof Node\NamespaceUseClause ||
$this->parent instanceof Node\NamespaceUseGroupClause ||
$this->parent->parent instanceof Node\TraitUseClause ||
$this->parent instanceof Node\TraitSelectOrAliasClause ||
($this->parent instanceof TraitSelectOrAliasClause &&
($this->parent->asOrInsteadOfKeyword == null || $this->parent->asOrInsteadOfKeyword->kind === TokenKind::AsKeyword))
) {
return null;
}
if (in_array($lowerText = strtolower($this->getText()), ["self", "static", "parent"])) {
return $lowerText;
}
// FULLY QUALIFIED NAMES
// - resolve to the name without leading namespace separator.
if ($this->isFullyQualifiedName()) {
return ResolvedName::buildName($this->nameParts, $this->getFileContents());
}
// RELATIVE NAMES
// - resolve to the name with namespace replaced by the current namespace.
// - if current namespace is global, strip leading namespace\ prefix.
if ($this->isRelativeName()) {
return $this->getNamespacedName();
}
list($namespaceImportTable, $functionImportTable, $constImportTable) = $this->getImportTablesForCurrentScope();
// QUALIFIED NAMES
// - first segment of the name is translated according to the current class/namespace import table.
// - If no import rule applies, the current namespace is prepended to the name.
if ($this->isQualifiedName()) {
return $this->tryResolveFromImportTable($namespaceImportTable) ?? $this->getNamespacedName();
}
// UNQUALIFIED NAMES
// - translated according to the current import table for the respective symbol type.
// (class-like => namespace import table, constant => const import table, function => function import table)
// - if no import rule applies:
// - all symbol types: if current namespace is global, resolve to global namespace.
// - class-like symbols: resolve from current namespace.
// - function or const: resolved at runtime (from current namespace, with fallback to global namespace).
if ($this->isConstantName()) {
$resolvedName = $this->tryResolveFromImportTable($constImportTable, /* case-sensitive */ true);
$namespaceDefinition = $this->getNamespaceDefinition();
if ($namespaceDefinition !== null && $namespaceDefinition->name === null) {
$resolvedName = $resolvedName ?? ResolvedName::buildName($this->nameParts, $this->getFileContents());
}
return $resolvedName;
} elseif ($this->parent instanceof CallExpression) {
$resolvedName = $this->tryResolveFromImportTable($functionImportTable);
if (($namespaceDefinition = $this->getNamespaceDefinition()) === null || $namespaceDefinition->name === null) {
$resolvedName = $resolvedName ?? ResolvedName::buildName($this->nameParts, $this->getFileContents());
}
return $resolvedName;
}
return $this->tryResolveFromImportTable($namespaceImportTable) ?? $this->getNamespacedName();
}
public function getLastNamePart() {
$parts = $this->nameParts;
for ($i = \count($parts) - 1; $i >= 0; $i--) {
// TODO - also handle reserved word tokens
if ($parts[$i]->kind === TokenKind::Name) {
return $parts[$i];
}
}
return null;
}
/**
* @param ResolvedName[] $importTable
* @param bool $isCaseSensitive
* @return string|null
*/
private function tryResolveFromImportTable($importTable, bool $isCaseSensitive = false) {
$content = $this->getFileContents();
$index = $this->nameParts[0]->getText($content);
// if (!$isCaseSensitive) {
// $index = strtolower($index);
// }
if(isset($importTable[$index])) {
$resolvedName = $importTable[$index];
$resolvedName->addNameParts(\array_slice($this->nameParts, 1), $content);
return $resolvedName;
}
return null;
}
private function isConstantName() : bool {
return
($this->parent instanceof Node\Statement\ExpressionStatement || $this->parent instanceof Expression) &&
!(
$this->parent instanceof Node\Expression\MemberAccessExpression || $this->parent instanceof CallExpression ||
$this->parent instanceof ObjectCreationExpression ||
$this->parent instanceof Node\Expression\ScopedPropertyAccessExpression || $this->parent instanceof AnonymousFunctionCreationExpression ||
$this->parent instanceof ArrowFunctionCreationExpression ||
($this->parent instanceof Node\Expression\BinaryExpression && $this->parent->operator->kind === TokenKind::InstanceOfKeyword)
);
}
public function getNameParts() : array {
return $this->nameParts;
}
}
@@ -0,0 +1,23 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class RelativeSpecifier extends Node {
/** @var Token */
public $namespaceKeyword;
/** @var Token */
public $backslash;
const CHILD_NAMES = [
'namespaceKeyword',
'backslash'
];
}
@@ -0,0 +1,18 @@
<?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\Node;
use Microsoft\PhpParser\Token;
class ReservedWord extends Expression {
/** @var Token */
public $children;
const CHILD_NAMES = [
'children'
];
}
@@ -0,0 +1,26 @@
<?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\Node;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Token;
class SourceFileNode extends Node {
/** @var string */
public $fileContents;
/** @var string */
public $uri;
/** @var Node[] */
public $statementList;
/** @var Token */
public $endOfFileToken;
const CHILD_NAMES = ['statementList', 'endOfFileToken'];
}
@@ -0,0 +1,78 @@
<?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\Node\Statement;
use Microsoft\PhpParser\Diagnostic;
use Microsoft\PhpParser\DiagnosticKind;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Node\StatementNode;
use Microsoft\PhpParser\Token;
use Microsoft\PhpParser\TokenKind;
class BreakOrContinueStatement extends StatementNode {
/** @var Token */
public $breakOrContinueKeyword;
/** @var Expression|null */
public $breakoutLevel;
/** @var Token */
public $semicolon;
const CHILD_NAMES = [
'breakOrContinueKeyword',
'breakoutLevel',
'semicolon'
];
/**
* @return Diagnostic|null - Callers should use DiagnosticsProvider::getDiagnostics instead
* @internal
* @override
*/
public function getDiagnosticForNode() {
if ($this->breakoutLevel === null) {
return null;
}
$breakoutLevel = $this->breakoutLevel;
while ($breakoutLevel instanceof Node\Expression\ParenthesizedExpression) {
$breakoutLevel = $breakoutLevel->expression;
}
if (
$breakoutLevel instanceof Node\NumericLiteral
&& $breakoutLevel->children->kind === TokenKind::IntegerLiteralToken
) {
$literalString = $breakoutLevel->getText();
$firstTwoChars = \substr($literalString, 0, 2);
if ($firstTwoChars === '0b' || $firstTwoChars === '0B') {
if (\bindec(\substr($literalString, 2)) > 0) {
return null;
}
}
else if (\intval($literalString, 0) > 0) {
return null;
}
}
if ($breakoutLevel instanceof Token) {
$start = $breakoutLevel->getStartPosition();
}
else {
$start = $breakoutLevel->getStart();
}
$end = $breakoutLevel->getEndPosition();
return new Diagnostic(
DiagnosticKind::Error,
"Positive integer literal expected.",
$start,
$end - $start
);
}
}
@@ -0,0 +1,51 @@
<?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\Node\Statement;
use Microsoft\PhpParser\ClassLike;
use Microsoft\PhpParser\NamespacedNameInterface;
use Microsoft\PhpParser\NamespacedNameTrait;
use Microsoft\PhpParser\Node\ClassBaseClause;
use Microsoft\PhpParser\Node\ClassInterfaceClause;
use Microsoft\PhpParser\Node\ClassMembersNode;
use Microsoft\PhpParser\Node\StatementNode;
use Microsoft\PhpParser\Token;
class ClassDeclaration extends StatementNode implements NamespacedNameInterface, ClassLike {
use NamespacedNameTrait;
/** @var Token */
public $abstractOrFinalModifier;
/** @var Token */
public $classKeyword;
/** @var Token */
public $name;
/** @var ClassBaseClause */
public $classBaseClause;
/** @var ClassInterfaceClause */
public $classInterfaceClause;
/** @var ClassMembersNode */
public $classMembers;
const CHILD_NAMES = [
'abstractOrFinalModifier',
'classKeyword',
'name',
'classBaseClause',
'classInterfaceClause',
'classMembers'
];
public function getNameParts() : array {
return [$this->name];
}
}

Some files were not shown because too many files have changed in this diff Show More