/**
  * Declares a variable.
  *
  * @param string $name
  * @param array $types
  * @param boolean $typesInferred
  */
 private function declareVar($name, PhpType $type = null, $typeInferred = true, \PHPParser_Node $nameNode = null)
 {
     if ($this->scope->isDeclared($name)) {
         return $this->scope->getVar($name);
     }
     $var = $this->scope->declareVar($name, $type, $typeInferred);
     if ($nameNode) {
         $var->setNameNode($nameNode);
     }
     return $var;
 }
 private function checkParameterAssignment(\PHPParser_Node_Param $node)
 {
     $builder = new UnionTypeBuilder($this->typeRegistry);
     if (null !== $node->default) {
         $this->attachLiteralTypes($node->default);
         $type = $node->default->getAttribute('type');
         if ($type) {
             $builder->addAlternate($type);
         }
     }
     if ('array' === $node->type) {
         $type = $this->typeRegistry->getNativeType('array');
         // If the annotated type also contains the array type, we use the annotated
         // type as it is potentially more specific, e.g. "array<string>" or "array|null".
         $annotatedType = $this->commentParser->getTypeFromParamAnnotation($node->getAttribute('parent'), $node->name);
         if (null !== ($containedArrayType = $this->getContainedArrayType($annotatedType))) {
             $type = $containedArrayType;
         }
         $builder->addAlternate($type);
     } else {
         if ($node->type instanceof \PHPParser_Node_Name) {
             $builder->addAlternate($this->typeRegistry->getClassOrCreate(implode("\\", $node->type->parts)));
         }
     }
     $type = $builder->build();
     if ($type->isNoType()) {
         $type = $this->commentParser->getTypeFromParamAnnotation($node->getAttribute('parent'), $node->name);
     } else {
         if ($type->isNullType()) {
             $commentType = $this->commentParser->getTypeFromParamAnnotation($node->getAttribute('parent'), $node->name);
             if ($commentType) {
                 $type = $this->typeRegistry->createNullableType($commentType);
             } else {
                 $type = null;
             }
         } else {
             if ($type->isBooleanType()) {
                 $commentType = $this->commentParser->getTypeFromParamAnnotation($node->getAttribute('parent'), $node->name);
                 if ($commentType) {
                     $type = $this->typeRegistry->createUnionType(array($type, $commentType));
                 }
             }
         }
     }
     if (null === $type) {
         $type = $this->typeRegistry->getNativeType('unknown');
     }
     $node->setAttribute('type', $type);
     // This could be the case if the same name is used twice as parameter.
     if (false === $this->scope->isDeclared($node->name)) {
         $var = $this->scope->declareVar($node->name, $type, null === $type);
         $var->setNameNode($node);
         $var->setReference($node->byRef);
     } else {
         $var = $this->scope->getVar($node->name);
         if ($varType = $var->getType()) {
             $var->setType($this->typeRegistry->createUnionType(array($varType, $type)));
         } else {
             if (null !== $type) {
                 $var->setType($type);
                 $var->setTypeInferred(true);
             }
         }
         $var->setReference($node->byRef);
     }
 }