Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
liuyong
committed
Sep 6, 2018
1 parent
eed87e2
commit 8f98b3b
Showing
11 changed files
with
453 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,9 +26,9 @@ | |
|
||
## class | ||
|
||
- [ ] class | ||
- [ ] trait | ||
- [ ] interface | ||
- [x] class | ||
- [x] trait | ||
- [x] interface | ||
|
||
## method | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
<?php | ||
|
||
namespace PhpCTags\Finder\Position; | ||
|
||
class Class_ implements Finder | ||
{ | ||
public $root; | ||
public $namespace; | ||
public $name; | ||
public $file; | ||
public $autoload; | ||
|
||
public function validate() | ||
{ | ||
if (! $this->getRoot()) { | ||
throw new \Exception('Class Finder root is invalid'); | ||
} | ||
if (! $this->name) { | ||
throw new \Exception('Class Finder name is invalid'); | ||
} | ||
} | ||
|
||
public function getRoot() | ||
{ | ||
if (! file_exists($this->file)) { | ||
throw new \Exception("Class Finder file not found: {$this->file}"); | ||
} | ||
if ($this->root) { | ||
return $this->root; | ||
} | ||
if (! $this->autoload) { | ||
throw new \Exception('Class Finder autoload is invalid'); | ||
} | ||
|
||
$parser = new \PhpCTags\Parser\Root(); | ||
$this->root = $parser->parse($this->file, $this->autoload); | ||
if (! $this->root) { | ||
throw new \Exception('Class Finder root is invalid'); | ||
} | ||
|
||
return $this->root; | ||
} | ||
|
||
public function getAutoloadFile() | ||
{ | ||
$autoload = realpath($this->getRoot().DIRECTORY_SEPARATOR.$this->autoload); | ||
if (! file_exists($autoload)) { | ||
throw new \Exception('Class Finder autoload file is not exist'); | ||
} | ||
|
||
return $autoload; | ||
} | ||
|
||
public function find() | ||
{ | ||
$this->validate(); | ||
|
||
require_once $this->getAutoloadFile(); | ||
|
||
$class = $this->namespace ? $this->namespace.'\\'.$this->name : $this->name; | ||
try { | ||
$refClass = new \ReflectionClass($class); | ||
} catch (\Exception $e) { | ||
throw new \Exception('Reflection Class: '.$e->getMessage()); | ||
} | ||
|
||
$file = $refClass->getFileName(); | ||
if (! file_exists($file)) { | ||
throw new \Exception("Class Finder file not found: $file"); | ||
} | ||
$line = $refClass->getStartLine(); | ||
if ($line <= 0) { | ||
throw new \Exception("Class Finder line is invalid: $line"); | ||
} | ||
|
||
$rows = file($file); | ||
$raw = isset($rows[$line - 1]) ? $rows[$line - 1] : null; | ||
|
||
return new \PhpCTags\Position($file, $line, stripos($raw, $this->name) + 1); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
<?php | ||
|
||
namespace PhpCTags\Parser\Type; | ||
|
||
class Class_ implements Parser | ||
{ | ||
public function parse($tokens, $idx, $content, $line) | ||
{ | ||
$name = is_array($tokens[$idx]) ? $tokens[$idx][0] : null; | ||
if (T_STRING !== $name && T_STATIC !== $name) { | ||
return [false, null, null]; | ||
} | ||
|
||
$isClass = false; | ||
$class = null; | ||
$l = count($tokens); | ||
|
||
for ($i = $idx; $i >= 0; --$i) { | ||
$token = $tokens[$i]; | ||
$name = is_array($token) ? $token[0] : null; | ||
$data = is_array($token) ? $token[1] : $token; | ||
|
||
if ('' === trim($data)) { | ||
continue; | ||
} | ||
|
||
if (T_NEW == $name || T_INSTANCEOF == $name || | ||
T_USE == $name || T_CLASS == $name || | ||
T_TRAIT == $name || T_INTERFACE == $name || | ||
T_EXTENDS == $name || T_IMPLEMENTS === $name) { | ||
$isClass = true; | ||
if (T_USE == $name) { | ||
$class = '\\'.$class; | ||
} | ||
break; | ||
} | ||
|
||
if ('\\' == $data || preg_match('/^[A-Za-z_]+[A-Za-z0-9_]*$/', $data)) { | ||
$class = $data.$class; | ||
} else { | ||
break; | ||
} | ||
} | ||
|
||
if (! $isClass) { | ||
$raws = []; | ||
for (; $i >= 0; --$i) { | ||
$token = $tokens[$i]; | ||
$name = is_array($token) ? $token[0] : null; | ||
$data = is_array($token) ? $token[1] : $token; | ||
|
||
if (T_COMMENT == $name || T_DOC_COMMENT == $name) { | ||
continue; | ||
} | ||
|
||
if (T_CLASS == $name) { | ||
break; | ||
} | ||
|
||
if (T_IMPLEMENTS == $name) { | ||
$raw = implode('', $raws); | ||
if (preg_match('/^\s*([A-Za-z_][A-Za-z0-9_]*\s*\,?\s*)+$/s', $raw)) { | ||
$isClass = true; | ||
} | ||
break; | ||
} | ||
|
||
$raws[] = $data; | ||
} | ||
} | ||
|
||
for ($i = $idx + 1; $i < $l; ++$i) { | ||
$token = $tokens[$i]; | ||
$name = is_array($token) ? $token[0] : null; | ||
$data = is_array($token) ? $token[1] : $token; | ||
|
||
if ('' === trim($data)) { | ||
continue; | ||
} | ||
|
||
if (T_PAAMAYIM_NEKUDOTAYIM == $name || T_EXTENDS == $name || T_IMPLEMENTS == $name) { | ||
$isClass = true; | ||
break; | ||
} | ||
|
||
if ('\\' == $data || preg_match('/^[A-Za-z_]+[A-Za-z0-9_]*$/', $data)) { | ||
$class = $class.$data; | ||
} else { | ||
break; | ||
} | ||
} | ||
|
||
if (! $isClass || ! $class) { | ||
return [false, null, null]; | ||
} | ||
|
||
return $this->parseNamespace($class, $content, $line); | ||
} | ||
|
||
public function parseNamespace($name, $content, $line) | ||
{ | ||
$class = null; | ||
$classes = \PhpCTags\Pool\Class_::getInstance()->fromContent($content); | ||
for ($j = count($classes) - 1; $j >= 0; --$j) { | ||
if ($classes[$j][2] <= $line) { | ||
$class = $classes[$j]; | ||
break; | ||
} | ||
} | ||
|
||
if ('self' == $name || 'static' == $name || 'parent' == $name) { | ||
if ($class) { | ||
return [true, $class[0], $class[1]]; | ||
} | ||
|
||
return [false, null, null]; | ||
} | ||
|
||
$nsParser = new \PhpCTags\Parser\Namespace_(); | ||
|
||
return $nsParser->parseClass($name, $content, $class ? $class[2] : $line); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.