Page MenuHomeWickedGov Phorge

QualifiedName.php
No OneTemporary

Size
8 KB
Referenced Files
None
Subscribers
None

QualifiedName.php

<?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->getStartPosition() === $this->getStartPosition()) ||
$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();
}
[$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;
}
}

File Metadata

Mime Type
text/x-php
Expires
Sat, May 16, 21:38 (1 d, 4 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
90/19/a847926dedfa50ae6f76b2e09d64
Default Alt Text
QualifiedName.php (8 KB)

Event Timeline