private function verifyReturnType(PhpType $type, \PHPParser_Node $node)
 {
     if (null === ($commentType = $this->parser->getTypeFromReturnAnnotation($node))) {
         if ($this->getSetting('ask_for_return_if_not_inferrable') && $type->isUnknownType()) {
             $this->phpFile->addComment($node->getLine(), Comment::warning('php_doc.return_type_not_inferrable', 'Please add a ``@return`` annotation.'));
         }
         return;
     }
     if (!$this->getSetting('return')) {
         return;
     }
     if (!$type->isSubtypeOf($commentType)) {
         if ($this->getSetting('suggest_more_specific_types') && $this->typeRegistry->getNativeType('array')->isSubtypeOf($type)) {
             $this->phpFile->addComment($this->getLineOfReturn($node), Comment::warning('php_doc.return_type_mismatch_with_generic_array', 'Should the return type not be ``%expected_type%``? Also, consider making the array more specific, something like ``array<String>``, or ``String[]``.', array('expected_type' => $type->getDocType($this->importedNamespaces))));
         } else {
             $this->phpFile->addComment($this->getLineOfReturn($node), Comment::warning('php_doc.return_type_mismatch', 'Should the return type not be ``%expected_type%``?', array('expected_type' => $type->getDocType($this->importedNamespaces))));
         }
         return;
     }
     if (!$this->getSetting('suggest_more_specific_types')) {
         return;
     }
     if (!$this->isMoreSpecificType($type, $commentType)) {
         if ($type->isAllType()) {
             $this->phpFile->addComment($this->getLineOfReturn($node), Comment::warning('php_doc.return_type_all_type_more_specific', 'Please define a more specific return type; maybe using a union like ``null|Object``, or ``string|array``.'));
         } else {
             if ($this->typeRegistry->getNativeType('array')->isSubtypeOf($type)) {
                 $this->phpFile->addComment($this->getLineOfReturn($node), Comment::warning('php_doc.return_type_array_element_type', 'Please define the element type for the returned array (using ``array<SomeType>``, or ``SomeType[]``).'));
             }
         }
         return;
     }
     $this->phpFile->addComment($this->getLineOfReturn($node), Comment::warning('php_doc.return_type_more_specific', 'Consider making the return type a bit more specific; maybe use ``%actual_type%``.', array('actual_type' => $type->getDocType($this->importedNamespaces))));
 }
 private function traverseAssignList(\PHPParser_Node_Expr_AssignList $node, LinkedFlowScope $scope)
 {
     $scope = $this->traverse($node->expr, $scope);
     $exprType = $this->getType($node->expr);
     $isArray = $exprType->isArrayType();
     $checkedUnknown = $this->typeRegistry->getNativeType('unknown_checked');
     $castTypes = $this->commentParser->getTypesFromInlineComment($node->getDocComment());
     foreach ($node->vars as $i => $var) {
         if (null === $var) {
             continue;
         }
         $newType = $isArray ? $exprType->getItemType($i)->getOrElse($checkedUnknown) : $checkedUnknown;
         $this->updateScopeForTypeChange($scope, $var, null, $newType, $castTypes);
     }
     return $scope;
 }
 private function enterNode(\PHPParser_Node $node)
 {
     if (NodeUtil::isMethodContainer($node)) {
         $this->commentParser->setCurrentClassName(implode("\\", $node->namespacedName->parts));
         $this->commentParser->setImportedNamespaces($this->importedNamespaces);
         $this->classParser->setImportedNamespaces($this->importedNamespaces);
         $class = $this->classParser->parse($node);
         $this->classFiles[$class] = $this->phpFile;
         if ($this->typeRegistry->hasClass($class->getName(), TypeRegistry::LOOKUP_NO_CACHE)) {
             $this->analyzer->logger->warning(sprintf('The class "%s" has been defined more than once (maybe as a fixture for code generation). Ignoring the second definition.', $class->getName()));
             return;
         }
         $this->typeRegistry->registerClass($class);
     } else {
         if ($node instanceof \PHPParser_Node_Stmt_Function) {
             $this->functionParser->setImportedNamespaces($this->importedNamespaces);
             $function = $this->functionParser->parse($node);
             if ($this->typeRegistry->hasFunction($functionName = $function->getName(), false)) {
                 $this->analyzer->logger->warning(sprintf('The function "%s" has been defined more than once (probably conditionally). Ignoring the second definition.', $functionName));
                 return;
             }
             $this->typeRegistry->registerFunction($function);
         } else {
             if (NodeUtil::isConstantDefinition($node)) {
                 assert($node instanceof \PHPParser_Node_Expr_FuncCall);
                 if (!$node->args[0]->value instanceof \PHPParser_Node_Scalar_String) {
                     return;
                 }
                 $constant = new GlobalConstant($node->args[0]->value->value);
                 $constant->setAstNode($node);
                 $constant->setPhpType($this->typeRegistry->getNativeType('unknown'));
                 if (null !== ($type = $node->args[1]->value->getAttribute('type'))) {
                     $constant->setPhpType($type);
                 }
                 if ($this->typeRegistry->hasConstant($constant->getName(), false)) {
                     $this->analyzer->logger->warning(sprintf('The constant "%s" was defined more than once. Ignoring all but first definition.', $constant->getName()));
                     return;
                 }
                 $this->typeRegistry->registerConstant($constant);
             }
         }
     }
 }