Skip to content

Commit ecd9701

Browse files
author
Martin Hoch hoch@fidion.de
committed
Merge remote-tracking branch 'github/master'
2 parents d672bac + 58ed3e2 commit ecd9701

File tree

5 files changed

+102
-15
lines changed

5 files changed

+102
-15
lines changed

ChangeLog.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
Version 0.5.1
2+
-------------
3+
4+
* Fix building compatiblity with PHP 5.3.*
5+
thanks to grep-awesome@github
6+
7+
Version 0.5
8+
-----------
9+
10+
* Add trait support
11+
thanks to Mark Wu
12+
* Add inherits support
13+
thanks to Mark Wu
14+
* Add namespace support
15+
thanks to Mark Wu
16+
* Add instruction to enable phar extension in README
17+
118
Version 0.4.2
219
-------------
320

PHPCtags.class.php

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
<?php
22
class PHPCtags
33
{
4-
const VERSION = '0.4.2';
4+
const VERSION = '0.5.1';
55

66
private $mFile;
77

88
private $mFiles;
99

1010
private static $mKinds = array(
11+
't' => 'trait',
1112
'c' => 'class',
1213
'm' => 'method',
1314
'f' => 'function',
1415
'p' => 'property',
1516
'd' => 'constant',
1617
'v' => 'variable',
1718
'i' => 'interface',
19+
'n' => 'namespace',
1820
);
1921

2022
private $mParser;
@@ -111,7 +113,8 @@ private function struct($node, $reset=FALSE, $parent=array())
111113
$structs = array();
112114
}
113115

114-
$kind = $name = $line = $access = '';
116+
$kind = $name = $line = $access = $extends = '';
117+
$implements = array();
115118

116119
if (!empty($parent)) array_push($scope, $parent);
117120

@@ -122,6 +125,8 @@ private function struct($node, $reset=FALSE, $parent=array())
122125
} elseif ($node instanceof PHPParser_Node_Stmt_Class) {
123126
$kind = 'c';
124127
$name = $node->name;
128+
$extends = $node->extends;
129+
$implements = $node->implements;
125130
$line = $node->getLine();
126131
foreach ($node as $subNode) {
127132
$this->struct($subNode, FALSE, array('class' => $name));
@@ -181,10 +186,19 @@ private function struct($node, $reset=FALSE, $parent=array())
181186
foreach ($node as $subNode) {
182187
$this->struct($subNode, FALSE, array('interface' => $name));
183188
}
189+
} elseif ($node instanceof PHPParser_Node_Stmt_Trait ) {
190+
$kind = 't';
191+
$name = $node->name;
192+
$line = $node->getLine();
193+
foreach ($node as $subNode) {
194+
$this->struct($subNode, FALSE, array('trait' => $name));
195+
}
184196
} elseif ($node instanceof PHPParser_Node_Stmt_Namespace) {
185-
//@todo
197+
$kind = 'n';
198+
$name = $node->name;
199+
$line = $node->getLine();
186200
foreach ($node as $subNode) {
187-
$this->struct($subNode);
201+
$this->struct($subNode, FALSE, array('namespace' => $name));
188202
}
189203
} elseif ($node instanceof PHPParser_Node_Expr_Assign) {
190204
if (is_string($node->var->name)) {
@@ -218,6 +232,8 @@ private function struct($node, $reset=FALSE, $parent=array())
218232
'file' => $this->mFile,
219233
'kind' => $kind,
220234
'name' => $name,
235+
'extends' => $extends,
236+
'implements' => $implements,
221237
'line' => $line,
222238
'scope' => $scope,
223239
'access' => $access,
@@ -287,19 +303,54 @@ private function render()
287303

288304
#field=s
289305
if (in_array('s', $this->mOptions['fields']) && !empty($struct['scope'])) {
306+
// $scope, $type, $name are current scope variables
290307
$scope = array_pop($struct['scope']);
291308
list($type, $name) = each($scope);
292309
switch ($type) {
310+
case 'class':
311+
// n_* stuffs are namespace related scope variables
312+
// current > class > namespace
313+
$n_scope = array_pop($struct['scope']);
314+
if(!empty($n_scope)) {
315+
list($n_type, $n_name) = each($n_scope);
316+
$s_str = 'class:' . $n_name . '\\' . $name;
317+
} else {
318+
$s_str = 'class:' . $name;
319+
}
320+
break;
293321
case 'method':
294-
$scope = array_pop($struct['scope']);
295-
list($p_type, $p_name) = each($scope);
296-
$scope = 'method:' . $p_name . '::' . $name;
322+
// c_* stuffs are class related scope variables
323+
// current > method > class > namespace
324+
$c_scope = array_pop($struct['scope']);
325+
list($c_type, $c_name) = each($c_scope);
326+
$n_scope = array_pop($struct['scope']);
327+
if(!empty($n_scope)) {
328+
list($n_type, $n_name) = each($n_scope);
329+
$s_str = 'method:' . $n_name . '\\' . $c_name . '::' . $name;
330+
} else {
331+
$s_str = 'method:' . $c_name . '::' . $name;
332+
}
297333
break;
298334
default:
299-
$scope = $type . ':' . $name;
335+
$s_str = $type . ':' . $name;
300336
break;
301337
}
302-
$str .= "\t" . $scope;
338+
$str .= "\t" . $s_str;
339+
}
340+
341+
#field=i
342+
if(in_array('i', $this->mOptions['fields'])) {
343+
$inherits = array();
344+
if(!empty($struct['extends'])) {
345+
$inherits[] = $struct['extends']->toString();
346+
}
347+
if(!empty($struct['implements'])) {
348+
foreach($struct['implements'] as $interface) {
349+
$inherits[] = $interface->toString();
350+
}
351+
}
352+
if(!empty($inherits))
353+
$str .= "\t" . 'inherits:' . implode(',', $inherits);
303354
}
304355

305356
#field=a

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ phpctags
44
An enhanced php [ctags](http://ctags.sourceforge.net/) index file generator
55
compatible with http://ctags.sourceforge.net/FORMAT.
66

7-
Using [PHP_Parse](https://github.com/nikic/PHP-Parser) as PHP syntax parsing
7+
Using [PHP_Parser](https://github.com/nikic/PHP-Parser) as PHP syntax parsing
88
backend, written in pure PHP. The generated ctags index file contains scope
99
and access information about class's methods and properties.
1010

@@ -25,9 +25,10 @@ should be easy though (Apologize for not being able to provide any help for
2525
this, I am really not a Windows guy), it also would be great if someone could
2626
provide a patch for this.
2727

28-
Installation is simple, just run `make` in the root directory of the source,
29-
you will get a `phpctags` PHAR executable, add it to your `$PATH`, then you
30-
can invoke `phpcatgs` directly from anywhere.
28+
Installation is simple, make sure you have PHP's PHAR extension enabled, then
29+
just run `make` in the root directory of the source, you will get a `phpctags`
30+
PHAR executable, add it to your `$PATH`, then you can invoke `phpcatgs`
31+
directly from anywhere.
3132

3233
See [phpctags on packagist](http://packagist.org/packages/techlivezheng/phpctags)
3334
for more details.

bootstrap.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@
146146
$options['memory'] = '128M';
147147

148148
if (!isset($options['fields'])) {
149-
$options['fields'] = array('n', 'k', 's', 'a');
149+
$options['fields'] = array('n', 'k', 's', 'a','i');
150150
} else {
151151
$options['fields'] = str_split($options['fields']);
152152
}

buildPHAR.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,24 @@
22

33
$phar = new Phar('build/phpctags.phar', 0, 'phpctags.phar');
44

5+
if (version_compare(PHP_VERSION, '5.4.0') < 0) {
6+
class RecursiveCallbackFilterIterator extends RecursiveFilterIterator {
7+
public function __construct ( RecursiveIterator $iterator, $callback ) {
8+
$this->callback = $callback;
9+
parent::__construct($iterator);
10+
}
11+
12+
public function accept () {
13+
$callback = $this->callback;
14+
return $callback(parent::current(), parent::key(), parent::getInnerIterator());
15+
}
16+
17+
public function getChildren () {
18+
return new self($this->getInnerIterator()->getChildren(), $this->callback);
19+
}
20+
}
21+
}
22+
523
$phar->buildFromIterator(
624
new RecursiveIteratorIterator(
725
new RecursiveCallbackFilterIterator(
@@ -22,7 +40,7 @@ function ($current) {
2240

2341
foreach($excludes as $exclude) {
2442
if (fnmatch(getcwd().'/'.$exclude, $current->getPathName())) {
25-
return false;
43+
return false;
2644
}
2745
}
2846

0 commit comments

Comments
 (0)