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);
     }
 }
 public function getMismatchedArgumentTypes(\Scrutinizer\PhpAnalyzer\Model\AbstractFunction $function, array $argTypes, \Scrutinizer\PhpAnalyzer\Model\MethodContainer $clazz = null)
 {
     if ($function->hasVariableParameters()) {
         return $this->nextGetMismatchedArgumentTypes($function, $argTypes);
     }
     $mismatchedTypes = array();
     foreach ($function->getParameters() as $param) {
         /** @var $param Parameter */
         $index = $param->getIndex();
         if (!isset($argTypes[$index])) {
             continue;
         }
         if (!$this->typeChecker->mayBePassed($param->getPhpType(), $argTypes[$index])) {
             $mismatchedTypes[$index] = $param->getPhpType();
         }
     }
     return $mismatchedTypes;
 }
 public function __construct($name)
 {
     parent::__construct($name);
     $this->parameters = new ArrayCollection();
     $this->inMethodCallSites = new ArrayCollection();
     $this->inFunctionCallSites = new ArrayCollection();
     $this->outMethodCallSites = new ArrayCollection();
     $this->outFunctionCallSites = new ArrayCollection();
 }
 private function assertOutCallSites(AbstractFunction $function, array $outMethods, array $outFunctions)
 {
     $this->assertSame(count($outMethods) + count($outFunctions), count($function->getOutCallSites()));
     $this->assertSame(count($outMethods), count($function->getOutMethodCallSites()));
     $this->assertSame(count($outFunctions), count($function->getOutFunctionCallSites()));
     $i = 0;
     foreach ($function->getOutMethodCallSites() as $site) {
         $this->assertTrue(isset($outMethods[$i]));
         $this->assertSame($function, $site->getSource());
         $this->assertSame($outMethods[$i], $site->getTarget());
         $i += 1;
     }
     $i = 0;
     foreach ($function->getOutFunctionCallSites() as $site) {
         $this->assertTrue(isset($outFunctions[$i]));
         $this->assertSame($function, $site->getSource());
         $this->assertSame($outFunctions[$i], $site->getTarget());
         $i += 1;
     }
 }
 private function inferTypesForMethodOrFunction(AbstractFunction $function, Clazz $clazz = null)
 {
     if ($function instanceof GlobalFunction) {
         $this->parser->setImportedNamespaces($function->getImportedNamespaces());
     }
     foreach ($function->getParameters() as $param) {
         $this->inferTypesForParameter($param, $function, $clazz);
     }
     if (($type = $function->getReturnType()) && !$type->isUnknownType()) {
         return;
     }
     if (null !== ($node = $function->getAstNode())) {
         $type = $this->parser->getTypeFromReturnAnnotation($node);
         if (null === $type && $function instanceof Method && null !== $clazz) {
             foreach ($this->findOverriddenMethodsForDocInheritance($function->getName(), $clazz) as $parentMethod) {
                 if (null !== ($docType = $parentMethod->getReturnDocType())) {
                     $type = $this->parser->getType($docType);
                     break;
                 }
             }
         }
     }
     if (null === $type) {
         $type = $this->registry->getNativeType('unknown');
     }
     $function->setReturnType($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));
 }
 private function removeOutCallSites(AbstractFunction $function)
 {
     foreach ($function->getOutCallSites() as $site) {
         $site->getTarget()->removeCallSite($site);
     }
 }