public function getProperty($property_name) : Property
{
$property_name = $this->node->children['prop'];
// Give up for things like C::$prop_name
if (!is_string($property_name)) {
throw new NodeException($this->node, "Cannot figure out non-string property name");
}
$class_fqsen = null;
try {
$class_list = (new ContextNode($this->code_base, $this->context, $this->node->children['expr'] ?? $this->node->children['class']))->getClassList(true);
} catch (CodeBaseException $exception) {
throw new IssueException(Issue::fromType(Issue::UndeclaredProperty)($this->context->getFile(), $this->node->lineno ?? 0, ["{$exception->getFQSEN()}->{$property_name}"]));
}
foreach ($class_list as $i => $class) {
$class_fqsen = $class->getFQSEN();
// Keep hunting if this class doesn't have the given
// property
if (!$class->hasPropertyWithName($this->code_base, $property_name)) {
// If there's a getter on properties then all
// bets are off.
if ($class->hasGetMethod($this->code_base)) {
throw new UnanalyzableException($this->node, "Can't determine if property {$property_name} exists in class {$class->getFQSEN()} with __get defined");
}
continue;
}
$property = $class->getPropertyByNameInContext($this->code_base, $property_name, $this->context);
if ($property->isDeprecated()) {
throw new IssueException(Issue::fromType(Issue::DeprecatedProperty)($this->context->getFile(), $this->node->lineno ?? 0, [(string) $property->getFQSEN(), $property->getFileRef()->getFile(), $property->getFileRef()->getLineNumberStart()]));
}
return $property;
}
// Since we didn't find the property on any of the
// possible classes, check for classes with dynamic
// properties
foreach ($class_list as $i => $class) {
if (Config::get()->allow_missing_properties || $class->getHasDynamicProperties($this->code_base)) {
return $class->getPropertyByNameInContext($this->code_base, $property_name, $this->context);
}
}
/*
$std_class_fqsen =
FullyQualifiedClassName::getStdClassFQSEN();
// If missing properties are cool, create it on
// the first class we found
if (($class_fqsen && ($class_fqsen === $std_class_fqsen))
|| Config::get()->allow_missing_properties
) {
if (count($class_list) > 0) {
$class = $class_list[0];
return $class->getPropertyByNameInContext(
$this->code_base,
$property_name,
$this->context
);
}
}
*/
// If the class isn't found, we'll get the message elsewhere
if ($class_fqsen) {
throw new IssueException(Issue::fromType(Issue::UndeclaredProperty)($this->context->getFile(), $this->node->lineno ?? 0, ["{$class_fqsen}->{$property_name}"]));
}
throw new NodeException($this->node, "Cannot figure out property from {$this->context}");
}