src/Phan/Language/Scope/BranchScope.php
<?php
declare(strict_types=1);
namespace Phan\Language\Scope;
use Phan\Language\Element\Variable;
use Phan\Language\FQSEN\FullyQualifiedClassName;
use Phan\Language\FQSEN\FullyQualifiedFunctionName;
use Phan\Language\FQSEN\FullyQualifiedMethodName;
use Phan\Language\Scope;
/**
* A branch scope represents a scope created by branching off of the current scope
* (e.g. an if/elseif/else statement, a ternary conditional (`?:`) operator, etc.
*/
class BranchScope extends Scope
{
public function __construct(Scope $scope)
{
parent::__construct($scope, null, $scope->flags);
}
/**
* @return bool
* True if a variable with the given name is defined
* within this scope
*
* TODO: Allow unsetting a variable within a scope, and properly account for that in this check.
*/
public function hasVariableWithName(string $name): bool
{
return (
\array_key_exists($name, $this->variable_map)
|| $this->parent_scope->hasVariableWithName($name)
);
}
public function getVariableByName(string $name): Variable
{
return (
$this->variable_map[$name]
?? $this->parent_scope->getVariableByName($name)
);
}
public function getVariableByNameOrNull(string $name): ?Variable
{
return (
$this->variable_map[$name]
?? $this->parent_scope->getVariableByNameOrNull($name)
);
}
/**
* @return array<string|int,Variable> (keys are variable names, which are *almost* always strings)
* A map from name to Variable in this scope
*/
public function getVariableMap(): array
{
return $this->variable_map + $this->parent_scope->getVariableMap();
}
/**
* @return array<string|int,Variable> (keys are variable names, which are *almost* always strings)
* A map from name to Variable in this scope
*/
public function getVariableMapExcludingScope(?Scope $common_scope): array
{
if ($this === $common_scope) {
return [];
}
return $this->variable_map + $this->parent_scope->getVariableMapExcludingScope($common_scope);
}
/**
* @return FullyQualifiedClassName
* Crawl the scope hierarchy to get a class FQSEN.
*/
public function getClassFQSEN(): FullyQualifiedClassName
{
return $this->parent_scope->getClassFQSEN();
}
/**
* @return ?FullyQualifiedClassName
* Crawl the scope hierarchy to get a class FQSEN.
* Return null if there is no class FQSEN.
*/
public function getClassFQSENOrNull(): ?FullyQualifiedClassName
{
return $this->parent_scope->getClassFQSENOrNull();
}
/**
* @return FullyQualifiedMethodName|FullyQualifiedFunctionName
* Get the FQSEN for the closure, method or function we're in
*/
public function getFunctionLikeFQSEN()
{
return $this->parent_scope->getFunctionLikeFQSEN();
}
}