-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathReflector.php
executable file
·140 lines (108 loc) · 4.23 KB
/
Reflector.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<?php
class Wave_Reflector {
const SCAN_DIRECTORY = 1;
const SCAN_FILE = 2;
const VISIBILITY_PUBLIC = 'public';
const VISIBILITY_PROTECTED = 'protected';
const VISIBILITY_PRIVATE = 'private';
const DEFAULT_FILE_FILTER = '.php';
private $_classes = null;
public function __construct($handle, $type = self::SCAN_DIRECTORY, $filter = self::DEFAULT_FILE_FILTER, $recursive = true){
if(!file_exists($handle))
throw new Wave_Exception('Directory '.$handle.' cannot be resolved in Wave_Refector', 0);
$this->_classes = array();
if($type == self::SCAN_FILE && is_file($handle)){
$class = self::fileIsClass($handle);
if($class !== false)
$this->_classes[] = $class;
}
else if($type == self::SCAN_DIRECTORY && is_dir($handle)){
if($recursive === true){
$dir_iterator = new RecursiveDirectoryIterator($handle);
$iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST);
}
else {
$dir_iterator = new FilesystemIterator($handle);
$iterator = new IteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST);
}
foreach ($iterator as $file) {
$class = self::fileIsClass($file);
if($class !== false)
$this->_classes[] = $class;
}
}
}
public function execute(){
if(!isset($this->_classes[0]))
throw new Wave_Exception('No files to reflect on');
$classes = array();
foreach($this->_classes as $class){
$reflector = new ReflectionClass($class['classname']);
$class_annotations = Wave_Annotation::parse($reflector->getDocComment(), $class['classname']);
$parent_class = $reflector->getParentClass();
$c = array(
'name' => $class['classname'],
'subclasses' => $parent_class instanceof ReflectionClass ? $parent_class->getName() : '',
'implements' => $reflector->getInterfaceNames(),
'annotations' => $class_annotations
);
$methods = array();
foreach($reflector->getMethods() as $method){
$annotations = Wave_Annotation::parse($method->getDocComment(), $class['classname']);
$method_annotations = array();
foreach($annotations as $annotation){
$method_annotations[] = $annotation;
}
$method_name = $method->getName();
$visibility = $method->isPublic() ? self::VISIBILITY_PUBLIC : ($method->isPrivate() ? self::VISIBILITY_PRIVATE : self::VISIBILITY_PROTECTED);
$methods[$method_name] = array(
'name' => $method_name,
'visibility' => $visibility,
'static' => $method->isStatic(),
'annotations' => $method_annotations,
'declaring_class' => $method->getDeclaringClass()->getName()
);
}
$properties = array();
foreach($reflector->getProperties() as $property){
$annotations = Wave_Annotation::parse($property->getDocComment(), $class['classname']);
$property_annotations = array();
foreach($annotations as $annotation){
$property_annotations[] = $annotation;
}
$property_name = $property->getName();
$visibility = $property->isPublic() ? self::VISIBILITY_PUBLIC : ($property->isPrivate() ? self::VISIBILITY_PRIVATE : self::VISIBILITY_PROTECTED);
$properties[$property_name] = array(
'name' => $property_name,
'visibility' => $visibility,
'static' => $property->isStatic(),
'annotations' => $property_annotations,
'declaring_class' => $property->getDeclaringClass()->getName()
);
}
$classes[$class['classname']] = array('class' => $c, 'methods' => $methods, 'properties' => $properties);
}
return $classes;
}
private static function fileIsClass($file){
if(!is_file($file)) return false;
$contents = file_get_contents($file);
preg_match('/class[ ]+(?<classname>[A-Za-z0-9_]+)([ ]+extends[ ]+(?<extends>[A-Za-z0-9_]+))?([ ]+implements[ ]+(?<implements>[A-Za-z0-9_, ]+))?[ ]+{/', $contents, $matches);
unset($contents);
if(isset($matches['classname'])){
$class = array(
'classname' => $matches['classname'],
'path' => $file
);
if(isset($matches['extends']))
$class['extends'] = $matches['extends'];
if(isset($matches['implements'])){
$class['implements'] = explode(',', str_replace(' ', '', $matches['implements']));
}
return $class;
}
else
return false;
}
}
?>