hasNamespaceMapFor() public method

public hasNamespaceMapFor ( integer $flags, string $name ) : boolean
$flags integer
$name string
return boolean True if we have a mapped NS for the given named element
Example #1
0
 /**
  * Visit a node with kind `\ast\AST_CALL`
  *
  * @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 UnionType
  * The set of types that are possibly produced by the
  * given node
  */
 public function visitCall(Node $node) : UnionType
 {
     if ($node->children['expr']->kind !== \ast\AST_NAME) {
         // Things like `$func()`
         return new UnionType();
     }
     $function_name = $node->children['expr']->children['name'];
     $function_fqsen = null;
     // If its not fully qualified
     if ($node->children['expr']->flags & \ast\flags\NAME_NOT_FQ) {
         // Check to see if we have a mapped name
         if ($this->context->hasNamespaceMapFor(T_FUNCTION, $function_name)) {
             $function_fqsen = $this->context->getNamespaceMapFor(T_FUNCTION, $function_name);
         } else {
             $function_fqsen = FullyQualifiedFunctionName::fromStringInContext($function_name, $this->context);
         }
         // If the name is fully qualified
     } else {
         $function_fqsen = FullyQualifiedFunctionName::fromFullyQualifiedString($function_name);
     }
     // If the function doesn't exist, check to see if its
     // a call to a builtin method
     if (!$this->code_base->hasMethod($function_fqsen)) {
         $function_fqsen = FullyQualifiedFunctionName::make('', $function_name);
     }
     if (!$this->code_base->hasMethod($function_fqsen)) {
         // Missing internal (bulitin) method.
         return new UnionType();
     }
     $function = $this->code_base->getMethod($function_fqsen);
     // If this is an internal function, see if we can get
     // its types from the static dataset.
     if ($function->getContext()->isInternal() && $function->getUnionType()->isEmpty()) {
         $map = UnionType::internalFunctionSignatureMapForFQSEN($function_fqsen);
         return $map[$function_name] ?? new UnionType();
     }
     return $function->getUnionType();
 }
 /**
  * @param Context $context
  * The context in which the FQSEN string was found
  *
  * @param $fqsen_string
  * An FQSEN string like '\Namespace\Class'
  */
 public static function fromStringInContext(string $fqsen_string, Context $context) : FullyQualifiedFunctionName
 {
     // Check to see if we're fully qualified
     if (0 === strpos($fqsen_string, '\\')) {
         return static::fromFullyQualifiedString($fqsen_string);
     }
     // Split off the alternate ID
     $parts = explode(',', $fqsen_string);
     $fqsen_string = $parts[0];
     $alternate_id = (int) ($parts[1] ?? 0);
     assert(is_int($alternate_id), "Alternate must be an integer in {$fqsen_string}");
     $parts = explode('\\', $fqsen_string);
     $name = array_pop($parts);
     assert(!empty($name), "The name cannot be empty in {$fqsen_string}");
     // Check for a name map
     if ($context->hasNamespaceMapFor(static::getNamespaceMapType(), $name)) {
         return $context->getNamespaceMapFor(static::getNamespaceMapType(), $name);
     }
     // For functions we don't use the context's namespace if
     // there is no NS on the call.
     $namespace = implode('\\', array_filter($parts));
     return static::make($namespace, $name, $alternate_id);
 }
Example #3
0
 /**
  * @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);
 }
Example #4
0
 /**
  * @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);
 }
 /**
  * @param Context $context
  * The context in which the FQSEN string was found
  *
  * @param $fqsen_string
  * An FQSEN string like '\Namespace\Class'
  */
 public static function fromStringInContext(string $fqsen_string, Context $context) : FullyQualifiedGlobalStructuralElement
 {
     // Check to see if we're fully qualified
     if (0 === strpos($fqsen_string, '\\')) {
         return static::fromFullyQualifiedString($fqsen_string);
     }
     // Split off the alternate ID
     $parts = explode(',', $fqsen_string);
     $fqsen_string = $parts[0];
     $alternate_id = (int) ($parts[1] ?? 0);
     assert(is_int($alternate_id), "Alternate must be an integer in {$fqsen_string}");
     $parts = explode('\\', $fqsen_string);
     $name = array_pop($parts);
     assert(!empty($name), "The name cannot be empty in {$fqsen_string}");
     // Check for a name map
     if ($context->hasNamespaceMapFor(static::getNamespaceMapType(), $name)) {
         return $context->getNamespaceMapFor(static::getNamespaceMapType(), $name);
     }
     $namespace = implode('\\', array_filter($parts));
     // n.b.: Functions must override this method because
     //       they don't prefix the namespace for naked
     //       calls
     if (empty($namespace)) {
         $namespace = $context->getNamespace();
     }
     return static::make($namespace, $name, $alternate_id);
 }