/**
  * @param \PHPStan\Reflection\ClassReflection $classReflection
  * @return \PHPStan\Reflection\MethodReflection[]
  */
 private function createMethods(ClassReflection $classReflection) : array
 {
     $methods = [];
     foreach ($classReflection->getNativeReflection()->getMethods() as $methodReflection) {
         $declaringClass = $this->broker->getClass($methodReflection->getDeclaringClass()->getName());
         $phpDocParameters = $this->getPhpDocParamsFromMethod($methodReflection);
         $phpDocParameterTypes = [];
         if (!$declaringClass->getNativeReflection()->isAnonymous() && $declaringClass->getNativeReflection()->getFileName() !== false) {
             $typeMap = $this->fileTypeMapper->getTypeMap($declaringClass->getNativeReflection()->getFileName());
             foreach ($methodReflection->getParameters() as $parameterReflection) {
                 $typeString = $this->getMethodParameterAnnotationTypeString($phpDocParameters, $parameterReflection);
                 if ($typeString === null || !isset($typeMap[$typeString])) {
                     continue;
                 }
                 $type = $typeMap[$typeString];
                 $phpDocParameterTypes[$parameterReflection->getName()] = $type;
             }
         }
         $phpDocReturnType = null;
         $returnTypeString = $this->getReturnTypeStringFromMethod($methodReflection);
         if ($returnTypeString !== null && isset($typeMap[$returnTypeString])) {
             $phpDocReturnType = $typeMap[$returnTypeString];
         }
         $methods[strtolower($methodReflection->getName())] = $this->methodReflectionFactory->create($declaringClass, $methodReflection, $phpDocParameterTypes, $phpDocReturnType);
     }
     return $methods;
 }
예제 #2
0
 private function enterClassMethod(Scope $scope, Node\Stmt\ClassMethod $classMethod) : Scope
 {
     $fileTypeMap = $this->fileTypeMapper->getTypeMap($scope->getFile());
     $phpDocParameterTypes = [];
     $phpDocReturnType = null;
     if ($classMethod->getDocComment() !== null) {
         $docComment = $classMethod->getDocComment()->getText();
         $phpDocParameterTypes = TypehintHelper::getPhpDocParameterTypesFromMethod($fileTypeMap, array_map(function (Param $parameter) : string {
             return $parameter->name;
         }, $classMethod->params), $docComment);
         $phpDocReturnType = TypehintHelper::getPhpDocReturnTypeFromMethod($fileTypeMap, $docComment);
     }
     return $scope->enterClassMethod($classMethod, $phpDocParameterTypes, $phpDocReturnType);
 }
예제 #3
0
 private function updateScopeForVariableAssign(Scope $scope, \PhpParser\Node $node) : Scope
 {
     if ($node instanceof Assign || $node instanceof AssignRef || $node instanceof Isset_) {
         if ($node instanceof Assign || $node instanceof AssignRef) {
             $vars = [$node->var];
         } elseif ($node instanceof Isset_) {
             $vars = $node->vars;
         } else {
             throw new \PHPStan\ShouldNotHappenException();
         }
         foreach ($vars as $var) {
             $scope = $this->assignVariable($scope, $var, $node instanceof Assign || $node instanceof AssignRef ? $scope->getType($node->expr) : null);
         }
         if ($node instanceof Assign || $node instanceof AssignRef) {
             $scope = $this->lookForAssigns($scope, $node->expr);
             $comment = CommentHelper::getDocComment($node);
             if ($comment !== null && $node->var instanceof Variable && is_string($node->var->name)) {
                 $variableName = $node->var->name;
                 $processVarAnnotation = function (string $matchedType, string $matchedVariableName) use($scope, $variableName) : Scope {
                     $fileTypeMap = $this->fileTypeMapper->getTypeMap($scope->getFile());
                     if (isset($fileTypeMap[$matchedType]) && $matchedVariableName === $variableName) {
                         return $scope->assignVariable($matchedVariableName, $fileTypeMap[$matchedType]);
                     }
                     return $scope;
                 };
                 if (preg_match('#@var\\s+' . FileTypeMapper::TYPE_PATTERN . '\\s+\\$([a-zA-Z0-9_]+)#', $comment, $matches)) {
                     $scope = $processVarAnnotation($matches[1], $matches[2]);
                 } elseif (preg_match('#@var\\s+\\$([a-zA-Z0-9_]+)\\s+' . FileTypeMapper::TYPE_PATTERN . '#', $comment, $matches)) {
                     $scope = $processVarAnnotation($matches[2], $matches[1]);
                 }
             }
         }
         if ($node instanceof Isset_) {
             foreach ($vars as $var) {
                 if ($var instanceof PropertyFetch) {
                     $scope = $scope->specifyFetchedPropertyFromIsset($var);
                 }
             }
         }
     }
     return $scope;
 }
 /**
  * @param \PHPStan\Reflection\ClassReflection $classReflection
  * @return \PHPStan\Reflection\MethodReflection[]
  */
 private function createMethods(ClassReflection $classReflection) : array
 {
     $methods = [];
     foreach ($classReflection->getNativeReflection()->getMethods() as $methodReflection) {
         $declaringClass = $this->broker->getClass($methodReflection->getDeclaringClass()->getName());
         $phpDocParameterTypes = [];
         $phpDocReturnType = null;
         if (!$declaringClass->getNativeReflection()->isAnonymous() && $declaringClass->getNativeReflection()->getFileName() !== false) {
             $typeMap = $this->fileTypeMapper->getTypeMap($declaringClass->getNativeReflection()->getFileName());
             if ($methodReflection->getDocComment() !== false) {
                 $phpDocParameterTypes = TypehintHelper::getPhpDocParameterTypesFromMethod($typeMap, array_map(function (\ReflectionParameter $parameterReflection) : string {
                     return $parameterReflection->getName();
                 }, $methodReflection->getParameters()), $methodReflection->getDocComment());
             }
             if ($methodReflection->getDocComment() !== false) {
                 $phpDocReturnType = TypehintHelper::getPhpDocReturnTypeFromMethod($typeMap, $methodReflection->getDocComment());
             }
         }
         $methods[strtolower($methodReflection->getName())] = $this->methodReflectionFactory->create($declaringClass, $methodReflection, $phpDocParameterTypes, $phpDocReturnType);
     }
     return $methods;
 }