/** @test */ public function can_parse_var_docblocks() { $docblock = '/** blah blah */'; $this->assertEquals(null, DocblockParser::getPropertyType($docblock)); $docblock = '/** @var Foo */'; $this->assertEquals('Foo', DocblockParser::getPropertyType($docblock)); $docblock = '/** @var Foo $foo */'; $this->assertEquals('Foo', DocblockParser::getPropertyType($docblock)); $docblock = '/** * blah blah * @var Bar */'; $this->assertEquals('Bar', DocblockParser::getPropertyType($docblock)); }
private function guessType(Node $node) { // used for $this if ($node instanceof \PhpParser\Node\Stmt\Class_) { $className = $this->getNamespace() . '\\' . $node->name; $className = ltrim($className, '\\'); return $className; } if ($node instanceof \PhpParser\Node\Param) { $docblockType = $hintType = null; $reflFunc = $this->getReflectionFunction(); if ($reflFunc) { $docblock = $reflFunc->getDocComment(); } if (isset($docblock) && $docblock) { $docblockType = DocblockParser::getParamType($docblock, $node->name); if ($docblockType) { $docblockType = $this->parseDocblockType($docblockType); } } if ($node->type instanceof \PhpParser\Node\Name) { $hintType = $this->getClassName($node->type); } if ($hintType && $docblockType && !in_array($hintType, $docblockType)) { $msg = "@param docblock and type-hint mismatch for argument \${$node->name}"; $this->addError(new Error($msg, $node)); } return $hintType ?: $docblockType; } if ($node instanceof \PhpParser\Node\Expr\New_) { if ($node->class instanceof \PhpParser\Node\Name) { return $this->getClassName($node->class); } else { return 'object'; } } if ($node instanceof \PhpParser\Node\Expr\Variable) { $var = $this->getVariable($node->name); return $var ? $var->getType() : null; } if ($node instanceof \PhpParser\Node\Scalar\String_ || $node instanceof \PhpParser\Node\Scalar\Encapsed) { return 'string'; } if ($node instanceof \PhpParser\Node\Scalar\DNumber) { return 'float'; } if ($node instanceof \PhpParser\Node\Scalar\LNumber) { return 'integer'; } }
private function getType($node) { $type = null; if ($node->hasAttribute('comments')) { foreach ($node->getAttribute('comments') as $comment) { $type = DocblockParser::getVariableType($comment->getText()); } } if ($type) { return $type; } if ($node->expr instanceof New_) { $className = $this->getContext()->getClassName($node->expr->class); if (!$className) { return null; } if (!class_exists($className)) { $this->addError($this->createClassNotFoundError($className, $node->expr)); return null; } return new ReflectionClass($className); } }
private function getReflectionType($reflector) { if ($reflector instanceof ReflectionMethod && $reflector->isConstructor()) { $className = $reflector->getDeclaringClass()->getName(); return [$className]; } $docstr = $reflector->getDocComment(); if (!$docstr) { return false; } if ($reflector instanceof ReflectionMethod) { $file = $reflector->getFileName(); $type = DocblockParser::getMethodType($docstr); } elseif ($reflector instanceof ReflectionProperty) { $file = $reflector->getDeclaringClass()->getFileName(); $type = DocblockParser::getPropertyType($docstr); } else { if (PHINT_DEBUG) { var_dump(__METHOD__ . ':' . __LINE__); var_dump($reflector); throw new \RuntimeException(); } return null; } if (!$type) { return null; } if ($file == $this->context->getFileName()) { $context = $this->context; } else { $context = $this->getExternalFileContext($file); } $types = $context->parseDocblockType($type); return $types; }