fromType() public static method

public static fromType ( Type $type, UnionType[] $template_parameter_type_list ) : Type
$type Type The base type of this generic type referencing a generic class
$template_parameter_type_list UnionType[] A map from a template type identifier to a concrete union type
return Type
Example #1
0
File: Clazz.php Project: etsy/phan
 /**
  * @param Type|null $parent_type
  * The type of the parent (extended) class of this class.
  *
  * @return void
  */
 public function setParentType(Type $parent_type = null)
 {
     if ($this->getInternalScope()->hasAnyTemplateType()) {
         // Get a reference to the local list of templated
         // types. We'll use this to map templated types on the
         // parent to locally templated types.
         $template_type_map = $this->getInternalScope()->getTemplateTypeMap();
         // Figure out if the given parent type contains any template
         // types.
         $contains_templated_type = false;
         foreach ($parent_type->getTemplateParameterTypeList() as $i => $union_type) {
             foreach ($union_type->getTypeSet() as $type) {
                 if (isset($template_type_map[$type->getName()])) {
                     $contains_templated_type = true;
                     break 2;
                 }
             }
         }
         // If necessary, map the template parameter type list through the
         // local list of templated types.
         if ($contains_templated_type) {
             $parent_type = Type::fromType($parent_type, array_map(function (UnionType $union_type) use($template_type_map) : UnionType {
                 return new UnionType(array_map(function (Type $type) use($template_type_map) : Type {
                     return $template_type_map[$type->getName()] ?? $type;
                 }, $union_type->getTypeSet()->toArray()));
             }, $parent_type->getTemplateParameterTypeList()));
         }
     }
     $this->parent_type = $parent_type;
     // Add the parent to the union type of this
     // class
     $this->getUnionType()->addUnionType($parent_type->asUnionType());
 }
Example #2
0
 /**
  * Visit a node with kind `\ast\AST_NEW`
  *
  * @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 visitNew(Node $node) : UnionType
 {
     $union_type = $this->visitClassNode($node->children['class']);
     // For any types that are templates, map them to concrete
     // types based on the parameters passed in.
     return new UnionType(array_map(function (Type $type) use($node) {
         // Get a fully qualified name for the type
         $fqsen = $type->asFQSEN();
         // If this isn't a class, its fine as is
         if (!$fqsen instanceof FullyQualifiedClassName) {
             return $type;
         }
         // If we don't have the class, we'll catch that problem
         // elsewhere
         if (!$this->code_base->hasClassWithFQSEN($fqsen)) {
             return $type;
         }
         $class = $this->code_base->getClassByFQSEN($fqsen);
         // If this class doesn't have any generics on it, we're
         // fine as we are with this Type
         if (!$class->isGeneric()) {
             return $type;
         }
         // Now things are interesting. We need to map the
         // arguments to the generic types and return a special
         // kind of type.
         // Get the constructor so that we can figure out what
         // template types we're going to be mapping
         $constructor_method = $class->getMethodByName($this->code_base, '__construct');
         // Map each argument to its type
         $arg_type_list = array_map(function ($arg_node) {
             return UnionType::fromNode($this->context, $this->code_base, $arg_node);
         }, $node->children['args']->children ?? []);
         // Map each template type o the argument's concrete type
         $template_type_list = [];
         foreach ($constructor_method->getParameterList() as $i => $parameter) {
             if (isset($arg_type_list[$i])) {
                 $template_type_list[] = $arg_type_list[$i];
             }
         }
         // Create a new type that assigns concrete
         // types to template type identifiers.
         return Type::fromType($type, $template_type_list);
     }, $union_type->getTypeSet()->toArray()));
 }