1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Automattic\Jetpack\Analyzer; |
4
|
|
|
|
5
|
|
|
use PhpParser\Error; |
6
|
|
|
use PhpParser\NodeDumper; |
7
|
|
|
use PhpParser\ParserFactory; |
8
|
|
|
use PhpParser\Node; |
9
|
|
|
use PhpParser\Node\Stmt\Function_; |
10
|
|
|
use PhpParser\Node\Stmt\ClassMethod_; |
11
|
|
|
use PhpParser\NodeTraverser; |
12
|
|
|
use PhpParser\NodeVisitorAbstract; |
13
|
|
|
|
14
|
|
|
// const STATE_NONE = 0; |
15
|
|
|
// const STATE_CLASS_DECLARATION = 1; |
16
|
|
|
|
17
|
|
|
const VIS_PUBLIC = 0; |
18
|
|
|
const VIS_PRIVATE = 1; |
19
|
|
|
|
20
|
|
|
class Analyzer extends NodeVisitorAbstract { |
21
|
|
|
private $declarations; |
22
|
|
|
private $base_path; |
23
|
|
|
private $current_path; |
24
|
|
|
private $parser; |
25
|
|
|
|
26
|
|
|
function __construct( $base_path ) { |
27
|
|
|
$this->parser = ( new ParserFactory() )->create( ParserFactory::PREFER_PHP7 ); |
28
|
|
|
$this->declarations = array(); |
29
|
|
|
$this->base_path = $this->slashit( $base_path ); |
30
|
|
|
} |
31
|
|
|
|
32
|
|
|
private function slashit( $path ) { |
33
|
|
|
$path .= ( substr( $path, -1 ) == '/' ? '' : '/' ); |
34
|
|
|
return $path; |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
protected function add_declaration( $declaration ) { |
38
|
|
|
$this->declarations[] = $declaration; |
39
|
|
|
} |
40
|
|
|
|
41
|
|
|
private function print_declarations() { |
42
|
|
|
print_r( $this->declarations ); |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
public function file( $file_path ) { |
46
|
|
|
$this->current_path = $file_path; |
47
|
|
|
$source = file_get_contents( $file_path ); |
48
|
|
|
try { |
49
|
|
|
$ast = $this->parser->parse( $source ); |
50
|
|
|
} catch ( Error $error ) { |
|
|
|
|
51
|
|
|
echo "Parse error: {$error->getMessage()}\n"; |
52
|
|
|
return; |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
// $dumper = new NodeDumper; |
56
|
|
|
// echo $dumper->dump($ast) . "\n"; |
57
|
|
|
|
58
|
|
|
$traverser = new NodeTraverser(); |
59
|
|
|
$traverser->addVisitor( $this ); |
60
|
|
|
$ast = $traverser->traverse( $ast ); |
|
|
|
|
61
|
|
|
$this->print_declarations(); |
62
|
|
|
return; |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
public function enterNode( Node $node ) { |
66
|
|
|
// print_r($node); |
67
|
|
|
if ( $node instanceof Node\Stmt\Class_ ) { |
|
|
|
|
68
|
|
|
$this->add_declaration( new Class_Declaration( $this->current_path, $node->getLine(), $node->name->name ) ); |
69
|
|
|
} |
70
|
|
|
if ( $node instanceof Node\Stmt\Property && $node->isPublic() ) { |
|
|
|
|
71
|
|
|
$this->add_declaration( new Class_Property_Declaration( $this->current_path, $node->getLine(), $node->props[0]->name->name ) ); |
72
|
|
|
} |
73
|
|
|
if ( $node instanceof Node\Stmt\ClassMethod && $node->isPublic() ) { |
|
|
|
|
74
|
|
|
$method = new Class_Method_Declaration( $this->current_path, $node->getLine(), $node->name->name, $node->isStatic() ); |
75
|
|
|
foreach ( $node->getParams() as $param ) { |
76
|
|
|
$method->add_param( $node->var->name, $node->default, $node->type, $node->byRef, $node->variadic ); |
77
|
|
|
} |
78
|
|
|
$this->add_declaration( $method ); |
79
|
|
|
} |
80
|
|
|
} |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
class Declaration { |
84
|
|
|
public $path; |
85
|
|
|
public $line; |
86
|
|
|
public $name; |
87
|
|
|
|
88
|
|
|
function __construct( $path, $line, $name ) { |
89
|
|
|
$this->path = $path; |
90
|
|
|
$this->line = $line; |
91
|
|
|
$this->name = $name; |
92
|
|
|
} |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
class Class_Declaration extends Declaration { |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* We only log public class methods, whether they are static, and their parameters |
100
|
|
|
*/ |
101
|
|
|
class Class_Method_Declaration extends Declaration { |
102
|
|
|
public $static; |
103
|
|
|
|
104
|
|
|
function __construct( $path, $line, $name, $static ) { |
105
|
|
|
$this->static = $static; |
106
|
|
|
$this->params = array(); |
|
|
|
|
107
|
|
|
parent::__construct( $path, $line, $name ); |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
function add_param( $name, $default, $type, $byRef, $variadic ) { |
111
|
|
|
$this->params[] = (object) compact( 'name', 'default', 'type', 'byRef', 'variadic' ); |
112
|
|
|
} |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* We only log public class variables |
117
|
|
|
*/ |
118
|
|
|
class Class_Property_Declaration extends Declaration { |
119
|
|
|
} |
120
|
|
|
|
Scrutinizer analyzes your
composer.json
/composer.lock
file if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.