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);
     }
 }
 private function inferTypeForParameter(AbstractFunction $function, \Scrutinizer\PhpAnalyzer\Model\Parameter $param)
 {
     $index = $param->getIndex();
     $types = array();
     foreach ($function->getInCallSites() as $site) {
         $args = $site->getArgs();
         if (!isset($args[$index])) {
             continue;
         }
         $argType = $args[$index]->getPhpType();
         if ($argType->isUnknownType() || $argType->isNoType()) {
             continue;
         }
         $types[] = $argType;
     }
     if (null !== ($astNode = $param->getAstNode()) && null !== $astNode->default) {
         $defaultType = $astNode->default->getAttribute('type');
         // The default type might be null for example if a constant is assigned
         // as a default value, and we could not determine the value of that constant.
         if (null !== $defaultType) {
             $types[] = $defaultType;
         }
     }
     return $this->refineTypeForAnnotation($this->registry->createUnionType($types));
 }