public getPropertyByFQSEN ( Phan\Language\FQSEN\FullyQualifiedPropertyName $fqsen ) : Phan\Language\Element\Property | ||
$fqsen | Phan\Language\FQSEN\FullyQualifiedPropertyName | The FQSEN of a property to get |
return | Phan\Language\Element\Property | A property with the given FQSEN |
/** * @param string $name * The name of the property * * @param Context $context * The context of the caller requesting the property * * @return Property * A property with the given name * * @throws IssueException * An exception may be thrown if the caller does not * have access to the given property from the given * context */ public function getPropertyByNameInContext(CodeBase $code_base, string $name, Context $context) : Property { // Get the FQSEN of the property we're looking for $property_fqsen = FullyQualifiedPropertyName::make($this->getFQSEN(), $name); $property = null; // Figure out if we have the property $has_property = $code_base->hasPropertyWithFQSEN($property_fqsen); // Figure out if the property is accessible $is_property_accessible = false; if ($has_property) { $property = $code_base->getPropertyByFQSEN($property_fqsen); $is_remote_access = !$context->isInClassScope() || !$context->getClassInScope($code_base)->getUnionType()->canCastToExpandedUnionType($this->getUnionType(), $code_base); $is_property_accessible = !$is_remote_access || $property->isPublic(); } // If the property exists and is accessible, return it if ($is_property_accessible) { return $property; } // Check to see if we can use a __get magic method if ($this->hasMethodWithName($code_base, '__get')) { $method = $this->getMethodByName($code_base, '__get'); // Make sure the magic method is accessible if ($method->isPrivate()) { throw new IssueException(Issue::fromType(Issue::AccessPropertyPrivate)($context->getFile(), $context->getLineNumberStart(), [(string) $property_fqsen])); } else { if ($method->isProtected()) { throw new IssueException(Issue::fromType(Issue::AccessPropertyProtected)($context->getFile(), $context->getLineNumberStart(), [(string) $property_fqsen])); } } $property = new Property($context, $name, $method->getUnionType(), 0, $property_fqsen); $this->addProperty($code_base, $property, new None()); return $property; } else { if ($has_property) { // If we have a property, but its inaccessible, emit // an issue if ($property->isPrivate()) { throw new IssueException(Issue::fromType(Issue::AccessPropertyPrivate)($context->getFile(), $context->getLineNumberStart(), ["{$this->getFQSEN()}::\${$property->getName()}"])); } if ($property->isProtected()) { throw new IssueException(Issue::fromType(Issue::AccessPropertyProtected)($context->getFile(), $context->getLineNumberStart(), ["{$this->getFQSEN()}::\${$property->getName()}"])); } } } // Check to see if missing properties are allowed // or we're stdclass if (Config::get()->allow_missing_properties || $this->getFQSEN() == FullyQualifiedClassName::getStdClassFQSEN()) { $property = new Property($context, $name, new UnionType(), 0, $property_fqsen); $this->addProperty($code_base, $property, new None()); return $property; } throw new IssueException(Issue::fromType(Issue::UndeclaredProperty)($context->getFile(), $context->getLineNumberStart(), ["{$this->getFQSEN()}::\${$name}}"])); }