Пример #1
0
 /**
  * @param  array   $files
  * @param  boolean $recursive
  * @return array
  */
 public function detectDeadCode(array $files, $recursive = false)
 {
     // Analyse files and collect declared and called functions
     $analyser = new Analyser();
     foreach ($files as $file) {
         $analyser->analyseFile($file);
     }
     // Get info on declared and called functions.
     $declared = $analyser->getFunctionDeclarations();
     $called = $analyser->getFunctionCalls();
     $classDescendants = $analyser->getClassDescendants();
     // Search for declared, unused functions.
     $result = array();
     foreach ($declared as $name => $source) {
         if (!isset($called[$name])) {
             // Unused function/method at first sight.
             $used = false;
             // For methods: check calls from subclass instances as well
             $parts = explode('::', $name);
             if (count($parts) == 2) {
                 $class = $parts[0];
                 $subclasses = isset($classDescendants[$class]) ? $classDescendants[$class] : array();
                 foreach ($subclasses as $subclass) {
                     if (isset($called[$subclass . '::' . $parts[1]])) {
                         $used = true;
                         break;
                     }
                 }
             }
             if (!$used) {
                 $result[$name] = $source;
             }
         }
     }
     if ($recursive) {
         $done = false;
         while (!$done) {
             $done = true;
             foreach ($called as $callee => $callers) {
                 $_called = false;
                 foreach ($callers as $caller) {
                     if (!isset($result[$caller])) {
                         $_called = true;
                         break;
                     }
                 }
                 if (!$_called) {
                     if (isset($declared[$callee])) {
                         $result[$callee] = $declared[$callee];
                     }
                     $done = false;
                     unset($called[$callee]);
                 }
             }
         }
     }
     ksort($result);
     return $result;
 }
Пример #2
0
 /**
  * FileAnalyser constructor
  *
  * Validates the given file path and calls the parent's constructor.     *
  *
  * @param string $file The code to analyse
  * @param bool $registerNameResolver If set to true `PhpParser\NodeVisitor\NameResolver` will be added as the first
  *     visitor. This may negatively affect performance, some Visitors depend on resolved names, however.
  * @see \Pvra\RequirementAnalyser::__construct() Base constructor
  */
 public function __construct($file, $registerNameResolver = true)
 {
     if (!$this->isFileValid($file)) {
         throw new \RuntimeException(sprintf('The file "%s" could not be found or accessed.', $file));
     }
     $this->filePath = realpath($file);
     parent::__construct($registerNameResolver);
 }
		public function __construct($options) {
			$this->browser = new Browser();
			$this->engine = new Engine();
			$this->os = new Os();
			$this->device = new Device();

			parent::__construct($options);
		}
 /**
  * Short description of method createConditionExpressionFromString
  *
  * @access public
  * @author Joel Bout, <*****@*****.**>
  * @param  string string
  * @return core_kernel_rules_Expression
  */
 public function createConditionExpressionFromString($string)
 {
     $returnValue = null;
     //test: "IF    (11+B_Q01a*3)>=2 AND (B_Q01c=2 OR B_Q01c=7)    	THEN ^variable := 2*(B_Q01a+7)-^variable";
     $question = "if " . $string;
     // str_replace taken from the MsReader class
     $question = str_replace("�", "'", $question);
     // utf8...
     $question = str_replace("�", "'", $question);
     // utf8...
     $question = str_replace("�", "\"", $question);
     $question = str_replace("�", "\"", $question);
     try {
         $analyser = new Analyser();
         common_Logger::i('analysing expression \'' . $question . '\'');
         $tokens = $analyser->analyse($question);
     } catch (Exception $e) {
         throw new common_Exception("CapiXML error: {$e->getMessage()}");
     }
     $returnValue = $this->createConditionExpressionFromXML($tokens->getXml());
     return $returnValue;
 }
Пример #5
0
 /**
  * Shared implementation for parseFile() & parseContents().
  *
  * @param array $tokens The result of a token_get_all()
  * @param Context $parseContext
  * @return Analysis
  */
 protected function fromTokens($tokens, $parseContext)
 {
     $analyser = new Analyser();
     $analysis = new Analysis();
     reset($tokens);
     $token = '';
     $imports = ['swg' => 'Swagger\\Annotations'];
     // Use @SWG\* for swagger annotations (unless overwritten by a use statement)
     $parseContext->uses = [];
     $classContext = $parseContext;
     // Use the parseContext until a classContext is created.
     $classDefinition = false;
     $comment = false;
     $line = 0;
     $lineOffset = $parseContext->line ?: 0;
     while ($token !== false) {
         $previousToken = $token;
         $token = $this->nextToken($tokens, $parseContext);
         if (is_array($token) === false) {
             // Ignore tokens like "{", "}", etc
             continue;
         }
         if ($token[0] === T_DOC_COMMENT) {
             if ($comment) {
                 // 2 Doc-comments in succession?
                 $analysis->addAnnotations($analyser->fromComment($comment, new Context(['line' => $line], $classContext)));
             }
             $comment = $token[1];
             $line = $token[2] + $lineOffset;
             continue;
         }
         if ($token[0] === T_ABSTRACT) {
             $token = $this->nextToken($tokens, $parseContext);
             // Skip "abstract" keyword
         }
         if ($token[0] === T_CLASS) {
             // Doc-comment before a class?
             if (is_array($previousToken) && $previousToken[0] === T_DOUBLE_COLON) {
                 //php 5.5 class name resolution (i.e. ClassName::class)
                 continue;
             }
             $token = $this->nextToken($tokens, $parseContext);
             $classContext = new Context(['class' => $token[1], 'line' => $token[2]], $parseContext);
             if ($classDefinition) {
                 $analysis->addClassDefinition($classDefinition);
             }
             $classDefinition = ['class' => $token[1], 'extends' => null, 'properties' => [], 'methods' => [], 'context' => $classContext];
             // @todo detect end-of-class and reset $classContext
             $token = $this->nextToken($tokens, $parseContext);
             if ($token[0] === T_EXTENDS) {
                 $classContext->extends = $this->parseNamespace($tokens, $token, $parseContext);
                 $classDefinition['extends'] = $classContext->fullyQualifiedName($classContext->extends);
             }
             if ($comment) {
                 $classContext->line = $line;
                 $analysis->addAnnotations($analyser->fromComment($comment, $classContext));
                 $comment = false;
                 continue;
             }
         }
         if ($token[0] == T_STATIC) {
             $token = $this->nextToken($tokens, $parseContext);
             if ($token[0] === T_VARIABLE) {
                 // static property
                 $propertyContext = new Context(['property' => substr($token[1], 1), 'static' => true, 'line' => $line], $classContext);
                 if ($classDefinition) {
                     $classDefinition['properties'][$propertyContext->property] = $propertyContext;
                 }
                 if ($comment) {
                     $analysis->addAnnotations($analyser->fromComment($comment, $propertyContext));
                     $comment = false;
                 }
                 continue;
             }
         }
         if (in_array($token[0], [T_PRIVATE, T_PROTECTED, T_PUBLIC, T_VAR])) {
             // Scope
             $token = $this->nextToken($tokens, $parseContext);
             if ($token[0] == T_STATIC) {
                 $token = $this->nextToken($tokens, $parseContext);
             }
             if ($token[0] === T_VARIABLE) {
                 // instance property
                 $propertyContext = new Context(['property' => substr($token[1], 1), 'line' => $line], $classContext);
                 if ($classDefinition) {
                     $classDefinition['properties'][$propertyContext->property] = $propertyContext;
                 }
                 if ($comment) {
                     $analysis->addAnnotations($analyser->fromComment($comment, $propertyContext));
                     $comment = false;
                 }
             } elseif ($token[0] === T_FUNCTION) {
                 $token = $this->nextToken($tokens, $parseContext);
                 if ($token[0] === T_STRING) {
                     $methodContext = new Context(['method' => $token[1], 'line' => $line], $classContext);
                     if ($classDefinition) {
                         $classDefinition['methods'][$token[1]] = $methodContext;
                     }
                     if ($comment) {
                         $analysis->addAnnotations($analyser->fromComment($comment, $methodContext));
                         $comment = false;
                     }
                 }
             }
             continue;
         } elseif ($token[0] === T_FUNCTION) {
             $token = $this->nextToken($tokens, $parseContext);
             if ($token[0] === T_STRING) {
                 $methodContext = new Context(['method' => $token[1], 'line' => $line], $classContext);
                 if ($classDefinition) {
                     $classDefinition['methods'][$token[1]] = $methodContext;
                 }
                 if ($comment) {
                     $analysis->addAnnotations($analyser->fromComment($comment, $methodContext));
                     $comment = false;
                 }
             }
         }
         if (in_array($token[0], [T_NAMESPACE, T_USE]) === false) {
             // Skip "use" & "namespace" to prevent "never imported" warnings)
             // Not a doc-comment for a class, property or method?
             if ($comment) {
                 $analysis->addAnnotations($analyser->fromComment($comment, new Context(['line' => $line], $classContext)));
                 $comment = false;
             }
         }
         if ($token[0] === T_NAMESPACE) {
             $parseContext->namespace = $this->parseNamespace($tokens, $token, $parseContext);
             continue;
         }
         if ($token[0] === T_USE) {
             $statements = $this->parseUseStatement($tokens, $token, $parseContext);
             foreach ($statements as $alias => $target) {
                 if ($target[0] === '\\') {
                     $target = substr($target, 1);
                 }
                 $parseContext->uses[$alias] = $target;
                 foreach (Analyser::$whitelist as $namespace) {
                     if (strcasecmp(substr($target, 0, strlen($namespace)), $namespace) === 0) {
                         $imports[strtolower($alias)] = $target;
                         break;
                     }
                 }
             }
             $analyser->docParser->setImports($imports);
             continue;
         }
     }
     if ($comment) {
         // File ends with a T_DOC_COMMENT
         $analysis->addAnnotations($analyser->fromComment($comment, new Context(['line' => $line], $classContext)));
     }
     if ($classDefinition) {
         $analysis->addClassDefinition($classDefinition);
     }
     return $analysis;
 }
 function reduce(&$tokens)
 {
     $level = 1;
     $tokenCloseParenthesis = new TokenCloseParenthesis();
     $begin = 1 + $tokens->pos($this);
     // first token after the parenthesis
     // echo "REDUCE $tokens @$begin\n";
     /*
      * echo "call\n"; print_r($tokens);
      */
     for ($cursor = $begin; $cursor < $tokens->count(); $cursor++) {
         $token = $tokens->get($cursor);
         // echo "@ '$token'\n";
         // echo "@ ".get_class($token)." - '".get_class($this)."'\n";
         if ($token->typeOf($this)) {
             $level++;
             // echo "i+\n";
         } else {
             if ($token->typeOf($tokenCloseParenthesis)) {
                 $level--;
                 // echo "i-\n";
             }
         }
         if (0 == $level) {
             $begin--;
             // $begin is at the position of the opening parenthesis
             $end = $cursor;
             // $end is at the position of the closing parenthesis
             // echo "'$begin' '$end'\n";
             // $toto = $tokens->subSet($begin, $end);
             /*
              * print_r($toto); exit();
              */
             $analyser = new Analyser();
             $subReduce = $analyser->analyse($tokens->subSet($begin + 1, $end - 1));
             // exit();
             $tokens->delSet($begin, $end, $subReduce);
             return;
         }
     }
     // TODO: tell which was the opening parenthesis
     throw new Exception("Closing parenthesis not found");
 }
Пример #7
0
 /**
  *
  * @param Analysis $analysis
  * @param Analyser $analyser
  * @param string $comment
  * @param Context $context
  */
 private function analyseComment($analysis, $analyser, $comment, $context)
 {
     $analysis->addAnnotations($analyser->fromComment($comment, $context), $context);
 }
 /**
  * Short description of method analyseExpression
  *
  * @access public
  * @author Joel Bout, <*****@*****.**>
  * @param  string expressionInput
  * @param  boolean isCondition
  * @return DomDocument
  */
 public function analyseExpression($expressionInput, $isCondition = false)
 {
     $returnValue = null;
     //place the following bloc in a helper
     if (!empty($expressionInput)) {
         $question = $expressionInput;
     } else {
         $question = "";
     }
     //question test:
     //$question = "IF    (11+B_Q01a*3)>=2 AND (B_Q01c=2 OR B_Q01c=7)    	THEN ^variable := 2*(B_Q01a+7)-^variable";
     //analyse the expressionInput string and convert to an XML document:
     if (get_magic_quotes_gpc()) {
         $question = stripslashes($question);
         // Magic quotes are deprecated
     }
     //TODO: check if the variables exists and are associated to the process definition
     $returnValue = null;
     if (!empty($question)) {
         // something to parse
         // str_replace taken from the MsReader class
         $question = str_replace("�", "'", $question);
         // utf8...
         $question = str_replace("�", "'", $question);
         // utf8...
         $question = str_replace("�", "\"", $question);
         $question = str_replace("�", "\"", $question);
         if ($isCondition) {
             $question = "if " . $question;
         }
         try {
             $analyser = new Analyser();
             common_Logger::i('analysing expression \'' . $question . '\'');
             $tokens = $analyser->analyse($question);
             // $xml = htmlspecialchars($tokens->getXmlString(true));
             // $xml = $tokens->getXmlString(true);
             $returnValue = $tokens->getXml();
         } catch (Exception $e) {
             throw new common_Exception("CapiXML error: {$e->getMessage()}");
         }
     }
     return $returnValue;
 }
Пример #9
0
 /**
  * @covers Puml\Analyser::getObject
  */
 public function testGetObject()
 {
     $this->assertInstanceOf('\\Puml\\Model\\Object', $this->object->getObject());
 }
Пример #10
0
 /**
  * StringAnalyser constructor
  *
  * @param string $string The code to analyse
  * @param bool $registerNameResolver Inherited from the base class `Analyser`
  * @see Analyser::__construct() Base Constructor
  */
 public function __construct($string, $registerNameResolver = true)
 {
     $this->string = $string;
     parent::__construct($registerNameResolver);
 }