Exemplo n.º 1
0
 public function getFormattedText(XRef_IParsedFile $pf, $root)
 {
     $filename = $pf->getFileName();
     $links = $this->xref->getSourceFileLinks($filename);
     $tokens = $pf->getTokens();
     $lineNumber = 1;
     $ret = '';
     $ret .= sprintf(self::LINE_NUMBER_FORMAT, $lineNumber, $lineNumber);
     for ($i = 0; $i < count($tokens); ++$i) {
         $token = $tokens[$i];
         if ($links && array_key_exists($i, $links)) {
             // TODO: ugly, redo
             if (is_array($links[$i])) {
                 list($reportName, $objectId) = $links[$i];
                 $link = $this->xref->getHtmlLinkFor($reportName, $objectId, $root);
                 $ret .= "<a href='{$link}'>";
             } else {
                 $ret .= "</a>";
             }
         }
         $text = htmlspecialchars($token->text);
         if ($token->kind == XRef::T_ONE_CHAR) {
             $ret .= $text;
         } else {
             $span_class = array_key_exists($token->kind, XRef::$tokenNames) ? XRef::$tokenNames[$token->kind] : token_name($token->kind);
             if ($span_class == 'UNKNOWN') {
                 $span_class = $token->kind;
             }
             // special classes for php predefined constants
             if ($token->kind == T_STRING) {
                 $str_upper = strtoupper($token->text);
                 switch (strtoupper($token->text)) {
                     case "NULL":
                         $span_class == 'T_NULL';
                         break;
                     case "TRUE":
                         $span_class == 'T_TRUE';
                         break;
                     case "FALSE":
                         $span_class == 'T_FALSE';
                         break;
                 }
             }
             if (strpos($text, "\n") === false) {
                 // no new lines, simple
                 $ret .= "<span class='{$span_class}'>{$text}</span>";
             } else {
                 // ugly code that does the following:
                 // input:
                 //      some \n multiline text \n startig at line 10
                 // output:
                 //      <span class="text">some</span>
                 //      11 <span class="text">multiline text </span>
                 //      12  <span class="text"> starting at line 10 </span>
                 $parts = explode("\n", $text);
                 for ($j = 0; $j < count($parts); $j++) {
                     if ($j != 0) {
                         $lineNumber++;
                         $ret .= sprintf(self::LINE_NUMBER_FORMAT, $lineNumber, $lineNumber);
                     }
                     $ret .= "<span class='{$span_class}'>{$parts[$j]}</span>";
                     if ($j != count($parts) - 1) {
                         $ret .= "\n";
                     }
                 }
             }
         }
     }
     return $ret;
 }
Exemplo n.º 2
0
 /** methods to use when parsed files are already available */
 public function addParsedFile(XRef_IParsedFile $pf)
 {
     $this->report[$pf->getFileName()] = $this->getFileReport($pf);
 }
Exemplo n.º 3
0
 public function __construct(XRef_IParsedFile $pf, $startIndex, $endIndex = 0)
 {
     $this->fileName = $pf->getFileName();
     $this->lineNumber = $pf->getLineNumberAt($startIndex);
     $this->startIndex = $startIndex;
     $this->endIndex = $endIndex ? $endIndex : $startIndex;
     $class = $pf->getClassAt($startIndex);
     $method = $pf->getMethodAt($startIndex);
     $this->inClass = $class ? $class->name : null;
     $this->inMethod = $method ? $method->name : null;
 }
Exemplo n.º 4
0
 public function generateFileReport(XRef_IParsedFile $pf)
 {
     if ($pf->getFileType() != $this->supportedFileType) {
         return;
     }
     $tokens = $pf->getTokens();
     for ($i = 0; $i < count($tokens); ++$i) {
         $t = $tokens[$i];
         // Const declared:
         // const FOO = 10;
         if ($t->kind == T_CONST) {
             $n = $t->nextNS();
             $class = $pf->getClassAt($n->index);
             if ($class) {
                 $name = $class->name . "::" . $n->text;
             } else {
                 $name = $n->text;
             }
             $c = $this->getOrCreate($name);
             $filePos = new XRef_FilePosition($pf, $n->index);
             $c->declaredAt[] = $filePos;
             // link from source file HTML page to report page "reportId/objectId"
             $this->xref->addSourceFileLink($filePos, $this->reportId, $c->id);
         }
         // Const used:
         // foo::bar, but not foo::bar() or foo::$bar\
         if ($t->kind == T_DOUBLE_COLON) {
             $p = $t->prevNS();
             if ($p->kind == T_STRING) {
                 $n = $t->nextNS();
                 if ($n->kind == T_VARIABLE) {
                     // static field
                     continue;
                 } elseif ($n->kind == T_STRING) {
                     $nn = $n->nextNS();
                     if ($nn->kind == XRef::T_ONE_CHAR && $nn->text == '(') {
                         // method call
                         continue;
                     }
                 } elseif ($n->text == '$') {
                     // rare case: Class::$$static_field_name
                     continue;
                 } else {
                     error_log("What's this: {$n->text}");
                     continue;
                 }
                 $className = $p->text;
                 if ($className == 'self') {
                     $class = $pf->getClassAt($p->index);
                     if (!$class) {
                         error_log("Reference to self:: class not inside a class method at " . $pf->getFileName() . ":{$p->lineNumber}");
                         continue;
                     }
                     $className = $class->name;
                 }
                 $name = $className . "::" . $n->text;
                 $c = $this->getOrCreate($name);
                 $filePos = new XRef_FilePosition($pf, $n->index);
                 $c->usedAt[] = $filePos;
                 // link from source file HTML page to report page "reportId/objectId"
                 $this->xref->addSourceFileLink($filePos, $this->reportId, $c->id);
             }
         }
     }
     // foreach token
 }
Exemplo n.º 5
0
 public function generateFileReport(XRef_IParsedFile $pf)
 {
     if ($pf->getFileType() != $this->supportedFileType) {
         return;
     }
     // collect all declared classes
     foreach ($pf->getClasses() as $pfc) {
         $c = $this->getOrCreate($pfc->name);
         $c->isInterface = $pfc->kind == T_INTERFACE;
         $definedAt = new XRef_FilePosition($pf, $pfc->nameIndex);
         $c->definedAt[] = $definedAt;
         // link from source file HTML page to report page "reportId/objectId"
         $this->xref->addSourceFileLink($definedAt, $this->reportId, $c->id);
         // extended classes/interfaces
         foreach ($pfc->extends as $ext_name) {
             $c->extends[] = $ext_name;
             $ext_class = $this->getOrCreate($ext_name);
             $ext_class->inheritedBy[] = $pfc->name;
             $extendsIndex = $pfc->extendsIndex[$ext_name];
             $filePos = new XRef_FilePosition($pf, $extendsIndex[0], $extendsIndex[1]);
             $ext_class->usedAt[] = $filePos;
             // link from source file HTML page to report page "reportId/objectId"
             $this->xref->addSourceFileLink($filePos, $this->reportId, $ext_class->id);
         }
         // extended classes/interfaces
         foreach ($pfc->implements as $imp_name) {
             $c->implements[] = $imp_name;
             $imp_class = $this->getOrCreate($imp_name);
             $imp_class->inheritedBy[] = $pfc->name;
             $extendsIndex = $pfc->implementsIndex[$imp_name];
             $filePos = new XRef_FilePosition($pf, $extendsIndex[0], $extendsIndex[1]);
             $imp_class->usedAt[] = $filePos;
             // link from source file HTML page to report page "reportId/objectId"
             $this->xref->addSourceFileLink($filePos, $this->reportId, $imp_class->id);
         }
     }
     // foreach declared class
     // collect all places where this class is instantiated or mentioned:
     $tokens = $pf->getTokens();
     $tokens_count = count($tokens);
     for ($i = 0; $i < $tokens_count; ++$i) {
         $t = $tokens[$i];
         // "new" <name>
         // "new" $className
         // "new" "(" <callable-name> ")"  // AS3
         // "new" "<" <int> ">"            // AS3
         if ($t->kind == T_NEW) {
             $t = $t->nextNS();
             if ($t->kind != T_STRING) {
                 continue;
             }
             // TODO: scan for namespaced name, e.g. new \Foo\Bar()
             $name = $pf->qualifyName($t->text, $t->index);
             $new = $this->getOrCreate($name);
             $filePos = new XRef_FilePosition($pf, $t->index);
             $new->instantiatedAt[] = $filePos;
             // link from source file HTML page to report page "reportId/objectId"
             $this->xref->addSourceFileLink($filePos, $this->reportId, $new->id);
             continue;
         }
         // T_NEW
         //
         // Class :: $foo
         // Class :: foo()
         // but not Class :: CONST
         if ($t->kind == T_DOUBLE_COLON) {
             $p = $t->prevNS();
             if ($p->kind == T_STRING) {
                 $n = $t->nextNS();
                 if ($n->kind == T_VARIABLE) {
                     // ok, static field
                 } elseif ($n->kind == T_STRING) {
                     // method or constant
                     $nn = $n->nextNS();
                     if ($nn->text != '(') {
                         continue;
                     }
                 } elseif ($n->text == '$') {
                     // rare case: Class::$$static_field_name
                     continue;
                 } else {
                     throw new XRef_ParseException($n);
                 }
                 $className = $pf->qualifyName($p->text, $p->index);
                 if ($pf->getFileType() == XRef::FILETYPE_PHP) {
                     if ($className == 'self') {
                         $class = $pf->getClassAt($p->index);
                         if (!$class) {
                             error_log("Reference to self:: class not inside a class method at " . $pf->getFileName() . ":{$t->lineNumber}");
                             continue;
                         }
                         $className = $class->name;
                     }
                     // TODO: super:: class resolution needs 2-pass parser
                 }
                 $c = $this->getOrCreate($className);
                 $filePos = new XRef_FilePosition($pf, $p->index);
                 $c->usedAt[] = $filePos;
                 $this->xref->addSourceFileLink($filePos, $this->reportId, $c->id);
             } else {
                 error_log("Unexpected token {$t->text} at " . $pf->getFileName() . ":{$t->lineNumber}");
             }
         }
         // $foo isinstanceof Bar
         // $foo isinstanceof $bar
         if ($t->kind == T_INSTANCEOF) {
             $n = $t->nextNS();
             if ($n->kind == T_STRING) {
                 $className = $pf->qualifyName($n->text, $n->index);
                 $c = $this->getOrCreate($className);
                 $filePos = new XRef_FilePosition($pf, $n->index);
                 $c->usedAt[] = $filePos;
                 $this->xref->addSourceFileLink($filePos, $this->reportId, $c->id);
             }
         }
         // is_a($foo, "Bar")
         if ($t->kind == T_STRING && $t->text == "is_a") {
             $n = $t->nextNS();
             if ($n->text != '(') {
                 continue;
             }
             // TODO: add more checks below
             $n = $n->nextNS();
             // var name. Actually, should skip any expression, e.g.: is_a($user->world, "World")
             $n = $n->nextNS();
             // comma
             $n = $n->nextNS();
             // class name literal?
             $className = $pf->qualifyName(preg_replace("#[\\'\"]#", '', $n->text), $n->index);
             $c = $this->getOrCreate($className);
             $filePos = new XRef_FilePosition($pf, $n->index);
             $c->usedAt[] = $filePos;
             $this->xref->addSourceFileLink($filePos, $this->reportId, $c->id);
         }
     }
     // foreach $token
 }