Skip to content

Commit e6b3f62

Browse files
committed
Merge branch 'develop' into feature/improved-console-support
2 parents ca54c94 + f06415d commit e6b3f62

12 files changed

+164
-78
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
vendor
12
composer.lock
23
composer.phar
3-
vendor
4+
tests/*.expect
5+
tests/*.result

PHPCtags.class.php

Lines changed: 67 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,40 @@ class PHPCtags
33
{
44
private $mFile;
55

6+
private static $mKinds = array(
7+
'c' => 'class',
8+
'm' => 'method',
9+
'f' => 'function',
10+
'p' => 'property',
11+
'd' => 'constant',
12+
'v' => 'variable',
13+
'i' => 'interface',
14+
);
15+
616
private $mParser;
717

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()
18+
private $mStructs;
19+
20+
private $mOptions;
21+
22+
public function __construct($options)
1923
{
2024
$this->mParser = new PHPParser_Parser(new PHPParser_Lexer);
25+
$this->mStructs = array();
26+
$this->mOptions = $options;
2127
}
2228

23-
public function setMFile($file) {
24-
if(empty($file)) {
29+
public function setMFile($file)
30+
{
31+
if (empty($file)) {
2532
throw new PHPCtagsException('No File specified.');
2633
}
2734

28-
if(!file_exists($file)) {
35+
if (!file_exists($file)) {
2936
throw new PHPCtagsException('Warning: cannot open source file "' . $file . '" : No such file');
3037
}
3138

32-
if(!is_readable($file)) {
39+
if (!is_readable($file)) {
3340
throw new PHPCtagsException('Warning: cannot open source file "' . $file . '" : File is not readable');
3441
}
3542

@@ -74,7 +81,8 @@ public static function stringSortByLine($str, $foldcase=FALSE)
7481
return $str;
7582
}
7683

77-
private static function helperSortByLine($a, $b) {
84+
private static function helperSortByLine($a, $b)
85+
{
7886
return $a['line'] > $b['line'] ? 1 : 0;
7987
}
8088

@@ -89,7 +97,7 @@ private function struct($node, $reset=FALSE, $parent=array())
8997

9098
$kind = $name = $line = $access = '';
9199

92-
if(!empty($parent)) array_push($scope, $parent);
100+
if (!empty($parent)) array_push($scope, $parent);
93101

94102
if (is_array($node)) {
95103
foreach ($node as $subNode) {
@@ -121,6 +129,10 @@ private function struct($node, $reset=FALSE, $parent=array())
121129
foreach ($node as $subNode) {
122130
$this->struct($subNode, FALSE, array('method' => $name));
123131
}
132+
} elseif ($node instanceof PHPParser_Node_Stmt_If) {
133+
foreach ($node as $subNode) {
134+
$this->struct($subNode);
135+
}
124136
} elseif ($node instanceof PHPParser_Node_Stmt_Const) {
125137
$kind = 'd';
126138
$cons = $node->consts[0];
@@ -135,15 +147,17 @@ private function struct($node, $reset=FALSE, $parent=array())
135147
//@todo
136148
} elseif ($node instanceof PHPParser_Node_Stmt_Declare) {
137149
//@todo
150+
} elseif ($node instanceof PHPParser_Node_Stmt_TryCatch) {
151+
foreach ($node as $subNode) {
152+
$this->struct($subNode);
153+
}
138154
} elseif ($node instanceof PHPParser_Node_Stmt_Function) {
139155
$kind = 'f';
140156
$name = $node->name;
141157
$line = $node->getLine();
142158
foreach ($node as $subNode) {
143159
$this->struct($subNode, FALSE, array('function' => $name));
144160
}
145-
} elseif ($node instanceof PHPParser_Node_Stmt_Trait) {
146-
//@todo
147161
} elseif ($node instanceof PHPParser_Node_Stmt_Interface) {
148162
$kind = 'i';
149163
$name = $node->name;
@@ -157,7 +171,7 @@ private function struct($node, $reset=FALSE, $parent=array())
157171
$this->struct($subNode);
158172
}
159173
} elseif ($node instanceof PHPParser_Node_Expr_Assign) {
160-
if(is_string($node->var->name)) {
174+
if (is_string($node->var->name)) {
161175
$kind = 'v';
162176
$node = $node->var;
163177
$name = $node->name;
@@ -187,20 +201,20 @@ private function struct($node, $reset=FALSE, $parent=array())
187201
);
188202
}
189203

190-
if(!empty($parent)) array_pop($scope);
204+
if (!empty($parent)) array_pop($scope);
191205

192206
// if no --sort is given, sort by occurrence
193-
if (!isset($options['sort']) || $options['sort'] == 'no') {
207+
if (!isset($this->mOptions['sort']) || $this->mOptions['sort'] == 'no') {
194208
usort($structs, 'self::helperSortByLine');
195209
}
196210

197211
return $structs;
198212
}
199213

200-
private function render($structs, $options)
214+
private function render()
201215
{
202216
$str = '';
203-
foreach ($structs as $struct) {
217+
foreach ($this->mStructs as $struct) {
204218
$file = $struct['file'];
205219

206220
if (!isset($files[$file]))
@@ -211,51 +225,47 @@ private function render($structs, $options)
211225
if (empty($struct['name']) || empty($struct['line']) || empty($struct['kind']))
212226
return;
213227

214-
if ($struct['kind'] == 'v') {
215-
$str .= "$" . $struct['name'];
216-
} else {
217-
$str .= $struct['name'];
218-
}
228+
$str .= $struct['name'];
219229

220230
$str .= "\t" . $file;
221231

222-
if ($options['excmd'] == 'number') {
232+
if ($this->mOptions['excmd'] == 'number') {
223233
$str .= "\t" . $struct['line'];
224234
} else { //excmd == 'mixed' or 'pattern', default behavior
225235
$str .= "\t" . "/^" . rtrim($lines[$struct['line'] - 1], "\n") . "$/";
226236
}
227237

228-
if ($options['format'] == 1) {
238+
if ($this->mOptions['format'] == 1) {
229239
$str .= "\n";
230240
continue;
231241
}
232242

233243
$str .= ";\"";
234244

235245
#field=k, kind of tag as single letter
236-
if (in_array('k', $options['fields'])) {
237-
in_array('z', $options['fields']) && $str .= "kind:";
246+
if (in_array('k', $this->mOptions['fields'])) {
247+
in_array('z', $this->mOptions['fields']) && $str .= "kind:";
238248
$str .= "\t" . $struct['kind'];
239249
} else
240250
#field=K, kind of tag as fullname
241-
if (in_array('K', $options['fields'])) {
242-
in_array('z', $options['fields']) && $str .= "kind:";
251+
if (in_array('K', $this->mOptions['fields'])) {
252+
in_array('z', $this->mOptions['fields']) && $str .= "kind:";
243253
$str .= "\t" . self::$mKinds[$struct['kind']];
244254
}
245255

246256
#field=n
247-
if (in_array('n', $options['fields'])) {
257+
if (in_array('n', $this->mOptions['fields'])) {
248258
$str .= "\t" . "line:" . $struct['line'];
249259
}
250260

251261
#field=s
252-
if (in_array('s', $options['fields']) && !empty($struct['scope'])) {
262+
if (in_array('s', $this->mOptions['fields']) && !empty($struct['scope'])) {
253263
$scope = array_pop($struct['scope']);
254-
list($type,$name) = each($scope);
264+
list($type, $name) = each($scope);
255265
switch ($type) {
256266
case 'method':
257267
$scope = array_pop($struct['scope']);
258-
list($p_type,$p_name) = each($scope);
268+
list($p_type, $p_name) = each($scope);
259269
$scope = 'method:' . $p_name . '::' . $name;
260270
break;
261271
default:
@@ -266,25 +276,27 @@ private function render($structs, $options)
266276
}
267277

268278
#field=a
269-
if (in_array('a', $options['fields']) && !empty($struct['access'])) {
279+
if (in_array('a', $this->mOptions['fields']) && !empty($struct['access'])) {
270280
$str .= "\t" . "access:" . $struct['access'];
271281
}
272282

273283
$str .= "\n";
274284
}
275285

286+
// remove the last line ending
287+
$str = trim($str);
288+
276289
// sort the result as instructed
277-
if (isset($options['sort']) && ($options['sort'] == 'yes' || $options['sort'] == 'foldcase')) {
278-
$str = self::stringSortByLine($str, $options['sort'] == 'foldcase');
290+
if (isset($this->mOptions['sort']) && ($this->mOptions['sort'] == 'yes' || $this->mOptions['sort'] == 'foldcase')) {
291+
$str = self::stringSortByLine($str, $this->mOptions['sort'] == 'foldcase');
279292
}
280293

281294
return $str;
282295
}
283296

284-
public function export($file, $options)
297+
public function export($file)
285298
{
286-
$structs = array();
287-
if (is_dir($file) && isset($options['R'])) {
299+
if (is_dir($file) && isset($this->mOptions['R'])) {
288300
$iterator = new RecursiveIteratorIterator(
289301
new RecursiveDirectoryIterator(
290302
$file,
@@ -300,18 +312,24 @@ public function export($file, $options)
300312
continue;
301313
}
302314

303-
if (isset($options['exclude']) && false !== strpos($filename, $options['exclude'])) {
315+
if (isset($this->mOptions['exclude']) && false !== strpos($filename, $this->mOptions['exclude'])) {
304316
continue;
305317
}
306318

307319
$this->setMFile((string) $filename);
308-
$structs += $this->struct($this->mParser->parse(file_get_contents($this->mFile)), TRUE);
320+
$this->mStructs = array_merge(
321+
$this->mStructs,
322+
$this->struct($this->mParser->parse(file_get_contents($this->mFile)), TRUE)
323+
);
309324
}
310325
} else {
311326
$this->setMFile($file);
312-
$structs += $this->struct($this->mParser->parse(file_get_contents($this->mFile)), TRUE);
327+
$this->mStructs = array_merge(
328+
$this->mStructs,
329+
$this->struct($this->mParser->parse(file_get_contents($this->mFile)), TRUE)
330+
);
313331
}
314-
return $this->render($structs, $options);
332+
return $this->render();
315333
}
316334
}
317335

phpctags

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ if (file_exists($autoload = __DIR__ . '/vendor/autoload.php')) {
1212
);
1313
}
1414

15-
$options = getopt('af:Nno:RuV',array(
15+
$options = getopt('af:Nno:RuV', array(
1616
'append::',
1717
'debug',
1818
'exclude:',
@@ -30,11 +30,11 @@ if (isset($options['V'])) {
3030
$options['version'] = FALSE;
3131
}
3232

33-
if(!isset($options['debug'])) {
33+
if (!isset($options['debug'])) {
3434
error_reporting(0);
3535
}
3636

37-
if(isset($options['version'])) {
37+
if (isset($options['version'])) {
3838
echo <<<'EOF'
3939
Version: 0.2
4040
@@ -73,14 +73,14 @@ if (isset($options['N']) && !isset($options['n'])) {
7373
$options['excmd'] = 'pattern';
7474
}
7575

76-
if(!isset($options['excmd']))
76+
if (!isset($options['excmd']))
7777
$options['excmd'] = 'pattern';
78-
if(!isset($options['format']))
78+
if (!isset($options['format']))
7979
$options['format'] = 2;
80-
if(!isset($options['memory']))
80+
if (!isset($options['memory']))
8181
$options['memory'] = '128M';
82-
if(!isset($options['fields'])) {
83-
$options['fields'] = array('n', 'k','s', 'a');
82+
if (!isset($options['fields'])) {
83+
$options['fields'] = array('n', 'k', 's', 'a');
8484
} else {
8585
$options['fields'] = str_split($options['fields']);
8686
}
@@ -115,15 +115,15 @@ if (isset($options['memory'])) {
115115
}
116116
}
117117

118-
if(isset($options['append'])) {
118+
if (isset($options['append'])) {
119119
if ($options['append'] === FALSE || yes_or_no($options['append']) == 'yes') {
120120
$options['a'] = FALSE;
121121
} else if (yes_or_no($options['append']) != 'no') {
122122
die('phpctags: Invalid value for "append" option');
123123
}
124124
}
125125

126-
if(isset($options['recurse'])) {
126+
if (isset($options['recurse'])) {
127127
if ($options['recurse'] === FALSE || yes_or_no($options['recurse']) == 'yes') {
128128
$options['R'] = FALSE;
129129
} else if (yes_or_no($options['recurse']) != 'no') {
@@ -132,8 +132,8 @@ if(isset($options['recurse'])) {
132132
}
133133

134134
try {
135-
$ctags = new PHPCtags();
136-
$result = $ctags->export($file, $options);
135+
$ctags = new PHPCtags($options);
136+
$result = $ctags->export($file);
137137
} catch (Exception $e) {
138138
die("phpctags: {$e->getMessage()}");
139139
}

tests/PHPCtagsTest.php

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ class PHPCtagsTest extends PHPUnit_Framework_TestCase
1717
*/
1818
protected function setUp()
1919
{
20-
$this->object = new PHPCtags();
2120
}
2221

2322
/**
@@ -52,18 +51,17 @@ public function provider()
5251
public function testExport($testcase)
5352
{
5453
require_once __DIR__ . '/testcases/' . $testcase;
54+
5555
$testcase_id = strstr($testcase, '.', true);
5656
$testcase_class = 't_' . $testcase_id;
5757
$testcase_object = new $testcase_class;
58-
5958
$testcase_expect = $testcase_object->getExpectResult();
60-
61-
ob_start();
62-
$testcase_example = $testcase_object->getExample();
63-
$testcase_options = $testcase_object->getOptions();
64-
echo $this->object->export($testcase_example, $testcase_options);
65-
$testcase_result = ob_get_contents();
66-
ob_end_clean();
59+
$phpctags_object = new PHPCtags(
60+
$testcase_object->getOptions()
61+
);
62+
$testcase_result = $phpctags_object->export(
63+
$testcase_object->getExample()
64+
);
6765

6866
$expected_result = __DIR__ . '/' . $testcase_id . '.testcase.expect';
6967
$acctural_result = __DIR__ . '/' . $testcase_id . '.testcase.result';

tests/PHPCtagsTestCase.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ public function getExpectResult()
7575
$testcase_expect .= $line;
7676
}
7777

78+
// remove the last line ending
79+
$testcase_expect = trim($testcase_expect);
80+
7881
return $testcase_expect;
7982

8083
}

0 commit comments

Comments
 (0)