コード例 #1
0
ファイル: Parser.php プロジェクト: mfn/php-analyzer
 /**
  * @param Project $project
  */
 public function analyze(Project $project)
 {
     $logger = $project->getLogger();
     foreach ($project->getSplFileInfos() as $splFileInfo) {
         try {
             $source = file($splFileInfo->getRealPath());
             $code = join('', $source);
         } catch (\RuntimeException $e) {
             $project->addReport(new StringReport($e->getMessage()));
             continue;
         }
         try {
             $logger->info('Parsing ' . $splFileInfo->getRealPath());
             $tree = $this->parser->parse($code);
             $project->addFile(new File($splFileInfo, $source, $tree));
         } catch (Error $e) {
             $project->getLogger()->warning('[' . $this->getName() . '] ' . 'Error while parsing ' . $splFileInfo->getRealPath() . ' : ' . $e->getMessage());
             $project->addReport(new FileParserErrorReport($splFileInfo, $e));
         }
     }
 }
コード例 #2
0
 /**
  * Called when entering a node.
  *
  * Return value semantics:
  *  * null:      $node stays as-is
  *  * otherwise: $node is set to the return value
  *
  * @param Node $node Node
  *
  * @return null|Node Node
  */
 public function enterNode(Node $node)
 {
     if ($node instanceof Node\Stmt\Catch_) {
         $this->subNodeTraverser->traverse($node->stmts);
         $nonComments = $this->nonCommentCounterVisitor->getNonCommentStatements();
         if (0 === $nonComments) {
             $report = new StringReport('Empty catch block found');
             $line = $node->getAttribute('startLine') - 1;
             $report->setSourceFragment(new SourceFragment($this->currentFile, new Lines($line - $this->sourceContext, $line + $this->sourceContext, $line)));
             $this->project->addReport($report);
         }
     }
 }
コード例 #3
0
 /**
  * @param Project $project
  */
 public function analyze(Project $project)
 {
     foreach ($this->graph->getObjects() as $object) {
         if ($object instanceof ParsedInterface) {
             foreach ($object->getMethods() as $method) {
                 if ($method->getMethod()->isAbstract()) {
                     $report = new StringReport('Access type for interface method ' . $object->getName() . '::' . $method->getNameAndParamsSignature() . ' must be ommmited in ' . $object->getFile()->getSplFile()->getRealPath() . ':' . $object->getInterface()->getLine());
                     $report->setSourceFragment(new SourceFragment($object->getFile(), new Lines($method->getMethod()->getAttribute('startLine') - 1 - $this->sourceContext, $method->getMethod()->getAttribute('endLine') - 1 + $this->sourceContext, $method->getMethod()->getAttribute('startLine') - 1)));
                     $project->addReport($report);
                 }
             }
         }
     }
 }
コード例 #4
0
 /**
  * @param Project $project
  */
 public function analyze(Project $project)
 {
     foreach ($this->graph->getObjects() as $object) {
         if ($object instanceof ParsedInterface) {
             foreach ($object->getMethods() as $method) {
                 $methodCompare = new MethodSignatureCompare($method);
                 foreach ($this->checkInterfaceMethods($methodCompare, $this->helper->findInterfaceImplements($object)) as $brokenInterfaceAndMethod) {
                     $report = new Report($brokenInterfaceAndMethod, $method);
                     $report->setSourceFragment(new SourceFragment($object->getFile(), new Lines($method->getMethod()->getAttribute('startLine') - 1 - $this->sourceContext, $method->getMethod()->getAttribute('endLine') - 1 + $this->sourceContext, $method->getMethod()->getAttribute('startLine') - 1)));
                     $project->addReport($report);
                 }
             }
         }
     }
 }
コード例 #5
0
 /**
  * Called when entering a node.
  *
  * Return value semantics:
  *  * null:      $node stays as-is
  *  * otherwise: $node is set to the return value
  *
  * @param Node $node Node
  *
  * @return null|Node Node
  */
 public function enterNode(Node $node)
 {
     if ($node instanceof New_) {
         if ($node->class instanceof Variable) {
             $msg = 'Dynamic class instantiation with variable ';
             if ($node->class->name instanceof Variable) {
                 $msg .= 'variable $' . $node->class->name->name;
             } else {
                 $msg .= '$' . $node->class->name;
             }
             $report = new StringReport($msg . ' in ' . $this->currentFile->getSplFile()->getFilename() . ':' . $node->class->getLine());
             $report->setSourceFragment(new SourceFragment($this->currentFile, new Lines($node->class->getAttribute('startLine') - 1 - $this->sourceContext, $node->class->getAttribute('endLine') - 1 + $this->sourceContext, $node->class->getAttribute('startLine') - 1)));
             $this->project->addReport($report);
         }
     }
 }
コード例 #6
0
ファイル: InterfaceMissing.php プロジェクト: mfn/php-analyzer
 /**
  * @param Project $project
  * @return \string[]
  */
 public function analyze(Project $project)
 {
     $graph = $this->objectGraph;
     /** @var ParsedClass[] $classesMissingMethod */
     $classesMissingMethods = new Map(function ($key) {
         if ($key instanceof ParsedClass) {
             return;
         }
         throw new MapException('Only keys of type Class_ are accepted');
     }, function ($value) {
         if (is_array($value)) {
             return;
         }
         throw new MapException('Only values of type array are accepted');
     });
     # scan all objects (we're actually only interested in interfaces)
     foreach ($graph->getObjects() as $object) {
         if ($object instanceof ParsedInterface) {
             foreach ($object->getMethods() as $method) {
                 # now find all classes and class from interfaces extending this
                 # interface
                 $classesMissingMethod = $this->findSubtypeUntilMethodMatchesRecursive($method, $this->helper->findImplements($object));
                 # in case we found ones, store them for reporting later
                 # note: we may find other methods in the same class later too
                 foreach ($classesMissingMethod as $classMissingMethod) {
                     $methods = [];
                     if ($classesMissingMethods->exists($classMissingMethod)) {
                         $methods = $classesMissingMethods->get($classMissingMethod);
                     }
                     $methods[] = $method;
                     $classesMissingMethods->set($classMissingMethod, $methods);
                 }
             }
         }
     }
     /** @var ParsedClass $class */
     foreach ($classesMissingMethods->keys() as $class) {
         $project->addReport(new InterfaceMissingReport($class, $classesMissingMethods->get($class)));
     }
 }
コード例 #7
0
 /**
  * @param Project $project
  */
 public function analyze(Project $project)
 {
     $this->project = $project;
     $traverser = new NodeTraverser();
     $traverser->addVisitor($this);
     foreach ($project->getFiles() as $file) {
         $this->currentFile = $file;
         $traverser->traverse($file->getTree());
         foreach ($this->variables as $variable) {
             $report = new StringReport('Variable used in constructing raw SQL, is it escaped?');
             $line = $variable->getAttribute('startLine') - 1;
             $report->setSourceFragment(new SourceFragment($file, new Lines($line - $this->sourceContext, $line + $this->sourceContext, $line)));
             $project->addReport($report);
         }
     }
 }
コード例 #8
0
ファイル: AbstractMissing.php プロジェクト: mfn/php-analyzer
 /**
  * @param Project $project
  * @return \string[]
  */
 public function analyze(Project $project)
 {
     $graph = $this->objectGraph;
     /** @var ParsedClass[] $classesMissingMethod */
     $classesMissingMethods = new Map(function ($key) {
         if ($key instanceof ParsedClass) {
             return;
         }
         throw new MapException('Only keys of type Class_ are accepted');
     }, function ($value) {
         if (is_array($value)) {
             return;
         }
         throw new MapException('Only values of type array are accepted');
     });
     # scan all objects (we're actually only interested in classes)
     foreach ($graph->getObjects() as $object) {
         if ($object instanceof ParsedClass) {
             foreach ($object->getMethods() as $method) {
                 # and see if they've abstract methods
                 if ($method->getMethod()->isAbstract()) {
                     $methodName = $method->getNormalizedName();
                     # now find all descendant classes and see if they've implemented it
                     $classesMissingMethod = $this->findSubtypeUntilMethodMatchesRecursive($methodName, $this->helper->findExtends($object));
                     # in case we found ones, store them for reporting later
                     # note: we may find other methods in the same class later too
                     foreach ($classesMissingMethod as $classMissingMethod) {
                         $methods = [];
                         if ($classesMissingMethods->exists($classMissingMethod)) {
                             $methods = $classesMissingMethods->get($classMissingMethod);
                         }
                         $methods[] = $method;
                         $classesMissingMethods->set($classMissingMethod, $methods);
                     }
                 }
             }
         }
     }
     /** @var ParsedClass $class */
     foreach ($classesMissingMethods->keys() as $class) {
         $project->addReport(new AbstractMissingReport($class, $classesMissingMethods->get($class)));
     }
 }