本文整理汇总了PHP中Phan\Language\Context::getClassFQSEN方法的典型用法代码示例。如果您正苦于以下问题:PHP Context::getClassFQSEN方法的具体用法?PHP Context::getClassFQSEN怎么用?PHP Context::getClassFQSEN使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Phan\Language\Context
的用法示例。
在下文中一共展示了Context::getClassFQSEN方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。
示例1: visitVar
/**
* @param Node $node
* A node of the type indicated by the method name that we'd
* like to figure out the type that it produces.
*
* @return string
* The class name represented by the given call
*/
public function visitVar(Node $node) : string
{
// $$var->method()
if ($node->children['name'] instanceof Node) {
return '';
}
// $this->method()
if ($node->children['name'] == 'this') {
if (!$this->context->isInClassScope()) {
Log::err(Log::ESTATIC, 'Using $this when not in object context', $this->context->getFile(), $node->lineno);
return '';
}
return (string) $this->context->getClassFQSEN();
}
$variable_name = $node->children['name'];
if (!$this->context->getScope()->hasVariableWithName($variable_name)) {
// Got lost, couldn't find the variable in the current scope
// If it really isn't defined, it will be caught by the
// undefined var error
return '';
}
$variable = $this->context->getScope()->getVariableWithName($variable_name);
// Hack - loop through the possible types of the var and assume
// first found class is correct
foreach ($variable->getUnionType()->nonGenericArrayTypes()->getTypeList() as $type) {
$child_class_fqsen = FullyQualifiedClassName::fromStringInContext((string) $type, $this->context);
if ($this->code_base->hasClassWithFQSEN($child_class_fqsen)) {
return (string) FullyQualifiedClassName::fromStringInContext((string) $type, $this->context);
}
}
// We land here if we have a variable
// with a native type or no known type.
return '';
}
示例2: visitNew
/**
* @param Node $node
* A node to parse
*
* @return Context
* A new or an unchanged context resulting from
* parsing the node
*/
public function visitNew(Node $node) : Context
{
try {
$context_node = new ContextNode($this->code_base, $this->context, $node);
$method = $context_node->getMethod('__construct', false);
// Add a reference to each class this method
// could be called on
foreach ($context_node->getClassList() as $class) {
$class->addReference($this->context);
}
$this->analyzeCallToMethod($this->code_base, $method, $node);
$class_list = $context_node->getClassList();
foreach ($class_list as $class) {
// Make sure we're not instantiating an abstract
// class
if ($class->isAbstract() && (!$this->context->hasClassFQSEN() || $class->getFQSEN() != $this->context->getClassFQSEN())) {
Issue::emit(Issue::TypeInstantiateAbstract, $this->context->getFile(), $node->lineno ?? 0, (string) $class->getFQSEN());
}
// Make sure we're not instantiating an interface
if ($class->isInterface()) {
Issue::emit(Issue::TypeInstantiateInterface, $this->context->getFile(), $node->lineno ?? 0, (string) $class->getFQSEN());
}
}
} catch (IssueException $exception) {
$exception->getIssueInstance()();
} catch (\Exception $exception) {
// If we can't figure out what kind of a call
// this is, don't worry about it
return $this->context;
}
return $this->context;
}
示例3: visitNew
public function visitNew(Node $node) : bool
{
if (!$this->classExists()) {
return $this->classExistsOrIsNative($node);
}
$clazz = $this->code_base->getClassByFQSEN($this->class_fqsen);
if ($clazz->isAbstract()) {
if (!$this->context->hasClassFQSEN() || $clazz->getFQSEN() != $this->context->getClassFQSEN()) {
Log::err(Log::ETYPE, "Cannot instantiate abstract class {$this->class_name}", $this->context->getFile(), $node->lineno);
return false;
}
return true;
}
if ($clazz->isInterface()) {
if (!UnionType::fromStringInContext($this->class_name, $this->context)->isNativeType()) {
Log::err(Log::ETYPE, "Cannot instantiate interface {$this->class_name}", $this->context->getFile(), $node->lineno);
return false;
}
}
return true;
}
示例4: visitClassNode
private function visitClassNode(Node $node) : UnionType
{
// Things of the form `new $class_name();`
if ($node->kind == \ast\AST_VAR) {
return new UnionType();
}
// Anonymous class of form `new class { ... }`
if ($node->kind == \ast\AST_CLASS && $node->flags & \ast\flags\CLASS_ANONYMOUS) {
// Generate a stable name for the anonymous class
$anonymous_class_name = (new ContextNode($this->code_base, $this->context, $node))->getUnqualifiedNameForAnonymousClass();
// Turn that into a fully qualified name
$fqsen = FullyQualifiedClassName::fromStringInContext($anonymous_class_name, $this->context);
// Turn that into a union type
return Type::fromFullyQualifiedString((string) $fqsen)->asUnionType();
}
// Things of the form `new $method->name()`
if ($node->kind !== \ast\AST_NAME) {
return new UnionType();
}
// Get the name of the class
$class_name = $node->children['name'];
// If this is a straight-forward class name, recurse into the
// class node and get its type
if (!Type::isSelfTypeString($class_name)) {
// TODO: does anyone else call this method?
return self::unionTypeFromClassNode($this->code_base, $this->context, $node);
}
// This is a self-referential node
if (!$this->context->isInClassScope()) {
Log::err(Log::ESTATIC, "Cannot access {$class_name} when not in a class scope", $this->context->getFile(), $node->lineno);
return new UnionType();
}
// Reference to a parent class
if ($class_name === 'parent') {
$class = $this->context->getClassInScope($this->code_base);
if (!$class->hasParentClassFQSEN()) {
Log::err(Log::ESTATIC, "Reference to parent of parentless class {$class->getFQSEN()}", $this->context->getFile(), $node->lineno);
return new UnionType();
}
return Type::fromFullyQualifiedString((string) $class->getParentClassFQSEN())->asUnionType();
}
return Type::fromFullyQualifiedString((string) $this->context->getClassFQSEN())->asUnionType();
}
示例5: visitVar
/**
* @param Node $node
* A node of the type indicated by the method name that we'd
* like to figure out the type that it produces.
*
* @return string
* The class name represented by the given call
*/
public function visitVar(Node $node) : string
{
// $$var->method()
if ($node->children['name'] instanceof Node) {
return '';
}
// $this->method()
if ($node->children['name'] == 'this') {
if (!$this->context->isInClassScope()) {
Log::err(Log::ESTATIC, 'Using $this when not in object context', $this->context->getFile(), $node->lineno);
return '';
}
return (string) $this->context->getClassFQSEN();
}
$variable_name = $node->children['name'];
if (!$this->context->getScope()->hasVariableWithName($variable_name)) {
// Got lost, couldn't find the variable in the current scope
// If it really isn't defined, it will be caught by the
// undefined var error
return '';
}
$variable = $this->context->getScope()->getVariableWithName($variable_name);
$union_type = $variable->getUnionType()->nonNativeTypes()->nonGenericArrayTypes();
// If there are no candidate classes, we'll emit whatever
// we have so that we can differentiate between
// no-known-type and a shitty type
if ($union_type->isEmpty()) {
if (!$variable->getUnionType()->isEmpty() && !$variable->getUnionType()->hasType(MixedType::instance()) && !$variable->getUnionType()->hasType(ArrayType::instance()) && !$variable->getUnionType()->hasType(ObjectType::instance())) {
$type = (string) $variable->getUnionType();
throw new TypeException("Calling method on non-class type {$type}");
}
// No viable class types for the variable.
return '';
}
$class_fqsen = $this->chooseSingleFQSEN(array_map(function (Type $type) {
return $type->asFQSEN();
}, $union_type->getTypeList()));
if ($this->code_base->hasClassWithFQSEN($class_fqsen)) {
return (string) $class_fqsen;
}
// We couldn't find any viable classes
return '';
}
示例6: visitNew
/**
* @param Node $node
* A node of the type indicated by the method name that we'd
* like to figure out the type that it produces.
*
* @return string
* The class name represented by the given call
*/
public function visitNew(Node $node) : string
{
// Things of the form `new $class_name();`
if ($node->children['class']->kind == \ast\AST_VAR) {
return '';
}
// Anonymous class
// $v = new class { ... }
if ($node->children['class']->kind == \ast\AST_CLASS && $node->children['class']->flags & \ast\flags\CLASS_ANONYMOUS) {
return AST::unqualifiedNameForAnonymousClassNode($node->children['class'], $this->context);
}
// Things of the form `new $method->name()`
if ($node->children['class']->kind !== \ast\AST_NAME) {
return '';
}
$class_name = $node->children['class']->children['name'];
if (!in_array($class_name, ['self', 'static', 'parent'])) {
return (string) UnionTypeVisitor::unionTypeFromClassNode($this->code_base, $this->context, $node->children['class']);
}
if (!$this->context->isInClassScope()) {
Log::err(Log::ESTATIC, "Cannot access {$class_name}:: when no class scope is active", $this->context->getFile(), $node->lineno);
return '';
}
if ($class_name == 'static') {
return (string) $this->context->getClassFQSEN();
}
if ($class_name == 'self') {
if ($this->context->isGlobalScope()) {
assert(false, "Unimplemented branch is required for {$this->context}");
} else {
return (string) $this->context->getClassFQSEN();
}
}
if ($class_name == 'parent') {
$clazz = $this->context->getClassInScope($this->code_base);
if (!$clazz->hasParentClassFQSEN()) {
return '';
}
return (string) $clazz->getParentClassFQSEN();
}
return '';
}
示例7: fromStringInContext
/**
* @param string $string
* A string representing a type
*
* @param Context $context
* The context in which the type string was
* found
*
* @return Type
* Parse a type from the given string
*/
public static function fromStringInContext(string $string, Context $context) : Type
{
assert($string !== '', "Type cannot be empty in {$context}");
$namespace = null;
// Extract the namespace if the type string is
// fully-qualified
if ('\\' === $string[0]) {
list($namespace, $string) = self::namespaceAndTypeFromString($string);
}
$type_name = $string;
// @var bool
// True if this type name if of the form 'C[]'
$is_generic_array_type = self::isGenericArrayString($type_name);
// If this is a generic array type, get the name of
// the type of each element
$non_generic_array_type_name = $type_name;
if ($is_generic_array_type && false !== ($pos = strpos($type_name, '[]'))) {
$non_generic_array_type_name = substr($type_name, 0, $pos);
}
// Check to see if the type name is mapped via
// a using clause.
//
// Gotta check this before checking for native types
// because there are monsters out there that will
// remap the names via things like `use \Foo\String`.
if ($context->hasNamespaceMapFor(T_CLASS, $non_generic_array_type_name)) {
$fqsen = $context->getNamespaceMapFor(T_CLASS, $non_generic_array_type_name);
if ($is_generic_array_type) {
return GenericArrayType::fromElementType(Type::make($fqsen->getNamespace(), $fqsen->getName()));
}
return Type::make($fqsen->getNamespace(), $fqsen->getName());
}
// If this was a fully qualified type, we're all
// set
if (!empty($namespace)) {
return self::fromNamespaceAndName($namespace, $type_name);
}
if ($is_generic_array_type && self::isNativeTypeString($type_name)) {
return self::fromInternalTypeName($type_name);
} else {
// Check to see if its a builtin type
switch (self::canonicalNameFromName($type_name)) {
case 'array':
return \Phan\Language\Type\ArrayType::instance();
case 'bool':
return \Phan\Language\Type\BoolType::instance();
case 'callable':
return \Phan\Language\Type\CallableType::instance();
case 'float':
return \Phan\Language\Type\FloatType::instance();
case 'int':
return \Phan\Language\Type\IntType::instance();
case 'mixed':
return \Phan\Language\Type\MixedType::instance();
case 'null':
return \Phan\Language\Type\NullType::instance();
case 'object':
return \Phan\Language\Type\ObjectType::instance();
case 'resource':
return \Phan\Language\Type\ResourceType::instance();
case 'string':
return \Phan\Language\Type\StringType::instance();
case 'void':
return \Phan\Language\Type\VoidType::instance();
}
}
// Things like `self[]` or `$this[]`
if ($is_generic_array_type && self::isSelfTypeString($non_generic_array_type_name) && $context->isInClassScope()) {
// Callers of this method should be checking on their own
// to see if this type is a reference to 'parent' and
// dealing with it there. We don't want to have this
// method be dependent on the code base
assert('parent' !== $non_generic_array_type_name, __METHOD__ . " does not know how to handle the type name 'parent' in {$context}");
return GenericArrayType::fromElementType(static::fromFullyQualifiedString((string) $context->getClassFQSEN()));
}
// If this is a type referencing the current class
// in scope such as 'self' or 'static', return that.
if (self::isSelfTypeString($type_name) && $context->isInClassScope()) {
// Callers of this method should be checking on their own
// to see if this type is a reference to 'parent' and
// dealing with it there. We don't want to have this
// method be dependent on the code base
assert('parent' !== $type_name, __METHOD__ . " does not know how to handle the type name 'parent' in {$context}");
return static::fromFullyQualifiedString((string) $context->getClassFQSEN());
}
// Attach the context's namespace to the type name
return self::fromNamespaceAndName($context->getNamespace() ?: '\\', $type_name);
}
示例8: getPropertyByNameInContext
/**
* @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 AccessException
* 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
{
$property = $code_base->getProperty($this->getFQSEN(), $name);
// If we're getting the property from outside of this
// class and the property isn't public and we don't
// have a getter or setter, emit an access error
if ((!$context->hasClassFQSEN() || $context->getClassFQSEN() != $this->getFQSEN()) && !$property->isPublic() && !$this->hasMethodWithName($code_base, '__get') && !$this->hasMethodWithName($code_base, '__set')) {
if ($property->isPrivate()) {
throw new AccessException("Cannot access private property {$this->getFQSEN()}::\${$property->getName()}");
}
if ($property->isProtected()) {
throw new AccessException("Cannot access protected property {$this->getFQSEN()}::\${$property->getName()}");
}
}
return $property;
}
示例9: fromStringInContext
/**
* @param Context $context
* The context in which the FQSEN string was found
*
* @param $fqsen_string
* An FQSEN string like '\Namespace\Class::methodName'
*
* @return FullyQualifiedMethodName
*/
public static function fromStringInContext(string $fqsen_string, Context $context)
{
// Test to see if we have a class defined
if (false === strpos($fqsen_string, '::')) {
assert($context->isInClassScope(), "Cannot reference class element without class name when not in class scope.");
$fully_qualified_class_name = $context->getClassFQSEN();
} else {
assert(false !== strpos($fqsen_string, '::'), "Fully qualified class element lacks '::' delimiter");
list($class_name_string, $fqsen_string) = explode('::', $fqsen_string);
$fully_qualified_class_name = FullyQualifiedClassName::fromStringInContext($class_name_string, $context);
}
// Split off the alternate ID
$parts = explode(',', $fqsen_string);
$name = $parts[0];
$alternate_id = (int) ($parts[1] ?? 0);
assert(is_int($alternate_id), "Alternate must be an integer");
return static::make($fully_qualified_class_name, $name, $alternate_id);
}
示例10: fromStringInContext
/**
* @param string $string
* A string representing a type
*
* @param Context $context
* The context in which the type string was
* found
*
* @return Type
* Parse a type from the given string
*/
public static function fromStringInContext(string $string, Context $context) : Type
{
assert($string !== '', "Type cannot be empty in {$context}");
$namespace = null;
// Extract the namespace if the type string is
// fully-qualified
if ('\\' === $string[0]) {
list($namespace, $string) = self::namespaceAndTypeFromString($string);
}
$type_name = strtolower($string);
// Check to see if the type name is mapped via
// a using clause.
//
// Gotta check this before checking for native types
// because there are monsters out there that will
// remap the names via things like `use \Foo\String`.
if ($context->hasNamespaceMapFor(T_CLASS, $type_name)) {
$fqsen = $context->getNamespaceMapFor(T_CLASS, $type_name);
return new Type($fqsen->getNamespace(), $fqsen->getName());
}
// If this was a fully qualified type, we're all
// set
if (!empty($namespace)) {
return self::fromNamespaceAndName($namespace, $type_name);
}
// Check to see if its a builtin type
switch (self::canonicalNameFromName($type_name)) {
case 'array':
return \Phan\Language\Type\ArrayType::instance();
case 'bool':
return \Phan\Language\Type\BoolType::instance();
case 'callable':
return \Phan\Language\Type\CallableType::instance();
case 'float':
return \Phan\Language\Type\FloatType::instance();
case 'int':
return \Phan\Language\Type\IntType::instance();
case 'mixed':
return \Phan\Language\Type\MixedType::instance();
case 'null':
return \Phan\Language\Type\NullType::instance();
case 'object':
return \Phan\Language\Type\ObjectType::instance();
case 'resource':
return \Phan\Language\Type\ResourceType::instance();
case 'string':
return \Phan\Language\Type\StringType::instance();
case 'void':
return \Phan\Language\Type\VoidType::instance();
}
// If this is a type referencing the current class
// in scope such as 'self' or 'static', return that.
if (self::isSelfTypeString($type_name) && $context->isInClassScope()) {
return static::fromFullyQualifiedString((string) $context->getClassFQSEN());
}
// Attach the context's namespace to the type name
return self::fromNamespaceAndName($context->getNamespace() ?: '\\', $type_name);
}
示例11: visitMethodCall
/**
* @param Node $node
* A node of the type indicated by the method name that we'd
* like to figure out the type that it produces.
*
* @return string
* The class name represented by the given call
*/
public function visitMethodCall(Node $node) : string
{
if ($node->children['expr']->kind == \ast\AST_VAR) {
if ($node->children['expr']->children['name'] instanceof Node) {
return '';
}
// $var->method()
if ($node->children['expr']->children['name'] == 'this') {
if (!$this->context->isInClassScope()) {
Log::err(Log::ESTATIC, 'Using $this when not in object context', $this->context->getFile(), $node->lineno);
return '';
}
return (string) $this->context->getClassFQSEN();
}
$variable_name = $node->children['expr']->children['name'];
if (!$this->context->getScope()->hasVariableWithName($variable_name)) {
// Got lost, couldn't find the variable in the current scope
// If it really isn't defined, it will be caught by the
// undefined var error
return '';
}
$variable = $this->context->getScope()->getVariableWithName($variable_name);
// Hack - loop through the possible types of the var and assume
// first found class is correct
foreach ($variable->getUnionType()->nonGenericArrayTypes()->getTypeList() as $type) {
$child_class_fqsen = FullyQualifiedClassName::fromStringInContext((string) $type, $this->context);
if ($this->code_base->hasClassWithFQSEN($child_class_fqsen)) {
return (string) FullyQualifiedClassName::fromStringInContext((string) $type, $this->context);
}
}
// Could not find name
return '';
}
if ($node->children['expr']->kind == \ast\AST_PROP) {
$prop = $node->children['expr'];
if (!($prop->children['expr']->kind == \ast\AST_VAR && !$prop->children['expr']->children['name'] instanceof Node)) {
return '';
}
// $var->prop->method()
$var = $prop->children['expr'];
if ($var->children['name'] == 'this') {
// If we're not in a class scope, 'this' won't work
if (!$this->context->isInClassScope()) {
Log::err(Log::ESTATIC, 'Using $this when not in object context', $this->context->getFile(), $node->lineno);
return '';
}
// Get the class in scope
$clazz = $this->code_base->getClassByFQSEN($this->context->getClassFQSEN());
if ($prop->children['prop'] instanceof Node) {
// $this->$prop->method() - too dynamic, give up
return '';
}
$property_name = $prop->children['prop'];
if ($clazz->hasPropertyWithName($this->code_base, $property_name)) {
try {
$property = $clazz->getPropertyByNameInContext($this->code_base, $property_name, $this->context);
} catch (AccessException $exception) {
Log::err(Log::EACCESS, $exception->getMessage(), $this->context->getFile(), $node->lineno);
return '';
}
// Find the first viable property type
foreach ($property->getUnionType()->nonGenericArrayTypes()->getTypeList() as $type) {
$class_fqsen = FullyQualifiedClassName::fromStringInContext((string) $type, $this->context);
if ($this->code_base->hasClassWithFQSEN($class_fqsen)) {
return (string) $class_fqsen;
}
}
}
// No such property was found, or none were classes
// that could be found
return '';
}
return '';
}
if ($node->children['expr']->kind == \ast\AST_METHOD_CALL) {
// Get the type returned by the first method
// call.
$union_type = UnionType::fromNode($this->context, $this->code_base, $node->children['expr']);
// Find the subset of types that are viable
// classes
$viable_class_types = $union_type->nonNativeTypes()->nonGenericArrayTypes();
// If there are no non-native types, give up
if ($viable_class_types->isEmpty()) {
return '';
}
// Return the first non-native type in the
// list and hope its a class
return (string) $viable_class_types->head();
}
return '';
}
示例12: getPropertyByNameInContext
/**
* @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
{
// Check to see if we have the property
if (!$code_base->hasProperty($this->getFQSEN(), $name)) {
// If we don't have the property but do have a
// __get method, then we can create the property
if ($this->hasMethodWithName($code_base, '__get')) {
$property = new Property($context, $name, new UnionType(), 0);
$property->setFQSEN(FullyQualifiedPropertyName::make($this->getFQSEN(), $name));
$this->addProperty($code_base, $property);
} else {
throw new IssueException(Issue::fromType(Issue::UndeclaredProperty)($context->getFile(), $context->getLineNumberStart(), ["{$this->getFQSEN()}::\${$name}}"]));
}
}
$property = $code_base->getProperty($this->getFQSEN(), $name);
// If we're getting the property from outside of this
// class and the property isn't public and we don't
// have a getter or setter, emit an access error
if ((!$context->hasClassFQSEN() || $context->getClassFQSEN() != $this->getFQSEN()) && !$property->isPublic() && !$this->hasMethodWithName($code_base, '__get') && !$this->hasMethodWithName($code_base, '__set')) {
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()}"]));
}
}
return $property;
}
示例13: getPropertyByNameInContext
/**
* @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->hasClassFQSEN() || $context->getClassFQSEN() != $this->getFQSEN();
$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->setFQSEN($property_fqsen);
$this->addProperty($code_base, $property);
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
if (Config::get()->allow_missing_properties) {
$property = new Property($context, $name, new UnionType(), 0);
$property->setFQSEN($property_fqsen);
$this->addProperty($code_base, $property);
return $property;
}
throw new IssueException(Issue::fromType(Issue::UndeclaredProperty)($context->getFile(), $context->getLineNumberStart(), ["{$this->getFQSEN()}::\${$name}}"]));
}
示例14: withStaticResolvedInContext
/**
* @return UnionType
* A new UnionType with any references to 'static' resolved
* in the given context.
*/
public function withStaticResolvedInContext(Context $context) : UnionType
{
// If the context isn't in a class scope, there's nothing
// we can do
if (!$context->isInClassScope()) {
return $this;
}
// Find the static type on the list
$static_type = $this->getTypeSet()->find(function (Type $type) : bool {
return $type->isStaticType();
});
// If we don't actually have a static type, we're all set
if (!$static_type) {
return $this;
}
// Get a copy of this UnionType to avoid having to know
// who has copies of it out in the wild and what they're
// hoping for.
$union_type = clone $this;
// Remove the static type
$union_type->removeType($static_type);
// Add in the class in scope
$union_type->addType($context->getClassFQSEN()->asType());
return $union_type;
}