@@ -5,57 +5,79 @@ class PHPCtags
55
66 private $ mParser ;
77
8- public function __construct ($ file )
8+ private static $ mKinds = array (
9+ 'c ' => 'class ' ,
10+ 'm ' => 'method ' ,
11+ 'f ' => 'function ' ,
12+ 'p ' => 'property ' ,
13+ 'd ' => 'constant ' ,
14+ 'v ' => 'variable ' ,
15+ 'i ' => 'interface ' ,
16+ );
17+
18+ public function __construct ()
919 {
10- //@todo Check for existence
11- $ this ->mFile = $ file ;
1220 $ this ->mParser = new PHPParser_Parser (new PHPParser_Lexer );
1321 }
1422
15- private function getAccess ($ node )
23+ public static function getMKinds ()
24+ {
25+ return self ::$ mKinds ;
26+ }
27+
28+ private function getNodeAccess ($ node )
1629 {
1730 if ($ node ->isPrivate ()) return 'private ' ;
1831 if ($ node ->isProtected ()) return 'protected ' ;
1932 return 'public ' ;
2033 }
2134
22- private function struct ($ node , $ class_name = NULL , $ function_name = NULL )
35+ private static function helperSortByLine ($ a , $ b ) {
36+ return $ a ['line ' ] > $ b ['line ' ] ? 1 : 0 ;
37+ }
38+
39+ private function struct ($ node , $ reset =FALSE , $ parent =array ())
2340 {
41+ static $ scope = array ();
2442 static $ structs = array ();
2543
26- $ kind = $ name = $ line = $ scope = $ access = '' ;
44+ if ($ reset ) {
45+ $ structs = array ();
46+ }
47+
48+ $ kind = $ name = $ line = $ access = '' ;
49+
50+ if (!empty ($ parent )) array_push ($ scope , $ parent );
51+
2752 if (is_array ($ node )) {
2853 foreach ($ node as $ subNode ) {
29- $ this ->struct ($ subNode, $ class_name , $ function_name );
54+ $ this ->struct ($ subNode );
3055 }
3156 } elseif ($ node instanceof PHPParser_Node_Stmt_Class) {
3257 $ kind = 'c ' ;
3358 $ name = $ node ->name ;
3459 $ line = $ node ->getLine ();
3560 foreach ($ node as $ subNode ) {
36- $ this ->struct ($ subNode , $ name );
61+ $ this ->struct ($ subNode , FALSE , array ( ' class ' => $ name) );
3762 }
3863 } elseif ($ node instanceof PHPParser_Node_Stmt_Property) {
39- $ kind = 'v ' ;
64+ $ kind = 'p ' ;
4065 $ prop = $ node ->props [0 ];
4166 $ name = $ prop ->name ;
4267 $ line = $ prop ->getLine ();
43- $ scope = "class: " . $ class_name ;
44- $ access = $ this ->getAccess ($ node );
68+ $ access = $ this ->getNodeAccess ($ node );
4569 } elseif ($ node instanceof PHPParser_Node_Stmt_ClassConst) {
4670 $ kind = 'd ' ;
4771 $ cons = $ node ->consts [0 ];
4872 $ name = $ cons ->name ;
4973 $ line = $ cons ->getLine ();
50- $ scope = "class: " . $ class_name ;
5174 } elseif ($ node instanceof PHPParser_Node_Stmt_ClassMethod) {
52- $ kind = 'f ' ;
75+ $ kind = 'm ' ;
5376 $ name = $ node ->name ;
5477 $ line = $ node ->getLine ();
55- $ scope = "class: " . $ class_name ;
56- $ access = $ this ->getAccess ($ node );
78+ $ access = $ this ->getNodeAccess ($ node );
5779 foreach ($ node as $ subNode ) {
58- $ this ->struct ($ subNode , $ class_name , $ name );
80+ $ this ->struct ($ subNode , FALSE , array ( ' method ' => $ name) );
5981 }
6082 } elseif ($ node instanceof PHPParser_Node_Stmt_Const) {
6183 $ kind = 'd ' ;
@@ -76,7 +98,7 @@ private function struct($node, $class_name = NULL, $function_name = NULL)
7698 $ name = $ node ->name ;
7799 $ line = $ node ->getLine ();
78100 foreach ($ node as $ subNode ) {
79- $ this ->struct ($ subNode , $ class_name , $ name );
101+ $ this ->struct ($ subNode , FALSE , array ( ' function ' => $ name) );
80102 }
81103 } elseif ($ node instanceof PHPParser_Node_Stmt_Trait) {
82104 //@todo
@@ -85,19 +107,19 @@ private function struct($node, $class_name = NULL, $function_name = NULL)
85107 $ name = $ node ->name ;
86108 $ line = $ node ->getLine ();
87109 foreach ($ node as $ subNode ) {
88- $ this ->struct ($ subNode , $ name );
110+ $ this ->struct ($ subNode , FALSE , array ( ' interface ' => $ name) );
89111 }
90112 } elseif ($ node instanceof PHPParser_Node_Stmt_Namespace) {
91113 //@todo
114+ foreach ($ node as $ subNode ) {
115+ $ this ->struct ($ subNode );
116+ }
92117 } elseif ($ node instanceof PHPParser_Node_Expr_Assign) {
93- $ kind = 'v ' ;
94- $ node = $ node ->var ;
95- $ name = $ node ->name ;
96- $ line = $ node ->getLine ();
97- if (!empty ($ class_name ) && !empty ($ function_name )) {
98- $ scope = "function: " . $ class_name . ':: ' . $ function_name ;
99- } elseif (!empty ($ function_name )) {
100- $ scope = "function: " . $ function_name ;
118+ if (is_string ($ node ->var ->name )) {
119+ $ kind = 'v ' ;
120+ $ node = $ node ->var ;
121+ $ name = $ node ->name ;
122+ $ line = $ node ->getLine ();
101123 }
102124 } elseif ($ node instanceof PHPParser_Node_Expr_FuncCall) {
103125 switch ($ node ->name ) {
@@ -122,38 +144,90 @@ private function struct($node, $class_name = NULL, $function_name = NULL)
122144 );
123145 }
124146
147+ if (!empty ($ parent )) array_pop ($ scope );
148+
149+ usort ($ structs , 'self::helperSortByLine ' );
150+
125151 return $ structs ;
126152 }
127153
128- private function render ($ structs )
154+ private function render ($ structs, $ options )
129155 {
130156 $ str = '' ;
131157 $ lines = file ($ this ->mFile );
132- foreach ($ structs as $ stuct ) {
133- if (empty ($ stuct ['name ' ]) || empty ($ stuct ['line ' ]) || empty ($ stuct ['kind ' ]))
158+ foreach ($ structs as $ struct ) {
159+ if (empty ($ struct ['name ' ]) || empty ($ struct ['line ' ]) || empty ($ struct ['kind ' ]))
134160 return ;
135161
136- if ($ stuct ['kind ' ] == 'v ' ) {
137- $ str .= "$ " . $ stuct ['name ' ];
162+ if ($ struct ['kind ' ] == 'v ' ) {
163+ $ str .= "$ " . $ struct ['name ' ];
138164 } else {
139- $ str .= $ stuct ['name ' ];
165+ $ str .= $ struct ['name ' ];
140166 }
167+
141168 $ str .= "\t" . $ this ->mFile ;
142- $ str .= "\t" . "/^ " . rtrim ($ lines [$ stuct ['line ' ] - 1 ], "\n" ) . "$/; \"" ;
143- $ str .= "\t" . $ stuct ['kind ' ];
144- $ str .= "\t" . "line: " . $ stuct ['line ' ];
145- !empty ($ stuct ['scope ' ]) && $ str .= "\t" . $ stuct ['scope ' ];
146- !empty ($ stuct ['access ' ]) && $ str .= "\t" . "access: " . $ stuct ['access ' ];
169+
170+ if ($ options ['excmd ' ] == 'number ' ) {
171+ $ str .= "\t" . $ struct ['line ' ];
172+ } else { //excmd == 'mixed' or 'pattern', default behavior
173+ $ str .= "\t" . "/^ " . rtrim ($ lines [$ struct ['line ' ] - 1 ], "\n" ) . "$/ " ;
174+ }
175+
176+ if ($ options ['format ' ] == 1 ) {
177+ $ str .= "\n" ;
178+ continue ;
179+ }
180+
181+ $ str .= "; \"" ;
182+
183+ #field=k, kind of tag as single letter
184+ if (in_array ('k ' , $ options ['fields ' ])) {
185+ in_array ('z ' , $ options ['fields ' ]) && $ str .= "kind: " ;
186+ $ str .= "\t" . $ struct ['kind ' ];
187+ } else
188+ #field=K, kind of tag as fullname
189+ if (in_array ('K ' , $ options ['fields ' ])) {
190+ in_array ('z ' , $ options ['fields ' ]) && $ str .= "kind: " ;
191+ $ str .= "\t" . self ::$ mKinds [$ struct ['kind ' ]];
192+ }
193+
194+ #field=n
195+ if (in_array ('n ' , $ options ['fields ' ])) {
196+ $ str .= "\t" . "line: " . $ struct ['line ' ];
197+ }
198+
199+ #field=s
200+ if (in_array ('s ' , $ options ['fields ' ]) && !empty ($ struct ['scope ' ])) {
201+ $ scope = array_pop ($ struct ['scope ' ]);
202+ list ($ type ,$ name ) = each ($ scope );
203+ switch ($ type ) {
204+ case 'method ' :
205+ $ scope = array_pop ($ struct ['scope ' ]);
206+ list ($ p_type ,$ p_name ) = each ($ scope );
207+ $ scope = 'method: ' . $ p_name . ':: ' . $ name ;
208+ break ;
209+ default :
210+ $ scope = $ type . ': ' . $ name ;
211+ break ;
212+ }
213+ $ str .= "\t" . $ scope ;
214+ }
215+
216+ #field=a
217+ if (in_array ('a ' , $ options ['fields ' ]) && !empty ($ struct ['access ' ])) {
218+ $ str .= "\t" . "access: " . $ struct ['access ' ];
219+ }
220+
147221 $ str .= "\n" ;
148222 }
149223 return $ str ;
150224 }
151225
152- public function export ()
226+ public function export ($ file , $ options )
153227 {
154- $ code = file_get_contents ( $ this -> mFile );
155- $ stmts = $ this -> mParser -> parse ( $ code ) ;
156- $ structs = $ this ->struct ($ stmts );
157- echo $ this ->render ($ structs );
228+ //@todo Check for existence
229+ $ this -> mFile = $ file ;
230+ $ structs = $ this ->struct ($ this -> mParser -> parse ( file_get_contents ( $ this -> mFile )), TRUE );
231+ echo $ this ->render ($ structs, $ options );
158232 }
159233}
0 commit comments