private function inferTypeForParameter(AbstractFunction $function, Parameter $param) { $builder = new UnionTypeBuilder($this->typeRegistry); $index = $param->getIndex(); foreach ($function->getInCallSites() as $site) { $args = $site->getArgs(); if (!isset($args[$index])) { continue; } $builder->addAlternate($args[$index]->getPhpType()); } $newType = $builder->build(); if (!$newType->isNoType() && !$newType->isUnknownType()) { $param->setPhpType($newType); } }
private function inferTypesForParameter(Parameter $param, AbstractFunction $function, Clazz $clazz = null) { if (($type = $param->getPhpType()) && !$type->isUnknownType() && !$type->isNullType() && !$type->isFalse() && !$type->isAllType()) { return; } $allowsNull = $type && $type->isNullType(); if (null !== ($node = $param->getAstNode())) { $type = $this->parser->getTypeFromParamAnnotation($node, $param->getName()); // Check whether we can use the type of a overridden method. // We only do this if we find a parent method that has been defined // on an interface (I), or if we find an abstract method (II). if (null === $type && $function instanceof Method && null !== $clazz) { foreach ($this->findOverriddenMethodsForDocInheritance($function->getName(), $clazz) as $parentMethod) { if (null !== ($docType = $parentMethod->getParamDocType($param->getIndex()))) { $type = $this->parser->getType($docType); break; } } } } if (null === $type) { $type = $this->registry->getNativeType('unknown'); } else { if ($allowsNull) { $type = $this->registry->createNullableType($type); } } $param->setPhpType($type); if ($node) { $node->setAttribute('type', $type); } }