1
1
<?php
2
2
3
3
class Tokenizer {
4
- private $ tokens ;
4
+ private $ filename ;
5
5
private $ linesOfCode = array ('loc ' => 0 , 'cloc ' => 0 , 'ncloc ' => 0 );
6
6
7
+ /**
8
+ * @var array
9
+ */
10
+ protected static $ customTokens = array (
11
+ '( ' => 'PHP_Token_OPEN_BRACKET ' ,
12
+ ') ' => 'PHP_Token_CLOSE_BRACKET ' ,
13
+ '[ ' => 'PHP_Token_OPEN_SQUARE ' ,
14
+ '] ' => 'PHP_Token_CLOSE_SQUARE ' ,
15
+ '{ ' => 'PHP_Token_OPEN_CURLY ' ,
16
+ '} ' => 'PHP_Token_CLOSE_CURLY ' ,
17
+ '; ' => 'PHP_Token_SEMICOLON ' ,
18
+ '. ' => 'PHP_Token_DOT ' ,
19
+ ', ' => 'PHP_Token_COMMA ' ,
20
+ '= ' => 'PHP_Token_EQUAL ' ,
21
+ '< ' => 'PHP_Token_LT ' ,
22
+ '> ' => 'PHP_Token_GT ' ,
23
+ '+ ' => 'PHP_Token_PLUS ' ,
24
+ '- ' => 'PHP_Token_MINUS ' ,
25
+ '* ' => 'PHP_Token_MULT ' ,
26
+ '/ ' => 'PHP_Token_DIV ' ,
27
+ '? ' => 'PHP_Token_QUESTION_MARK ' ,
28
+ '! ' => 'PHP_Token_EXCLAMATION_MARK ' ,
29
+ ': ' => 'PHP_Token_COLON ' ,
30
+ '" ' => 'PHP_Token_DOUBLE_QUOTES ' ,
31
+ '@ ' => 'PHP_Token_AT ' ,
32
+ '& ' => 'PHP_Token_AMPERSAND ' ,
33
+ '% ' => 'PHP_Token_PERCENT ' ,
34
+ '| ' => 'PHP_Token_PIPE ' ,
35
+ '$ ' => 'PHP_Token_DOLLAR ' ,
36
+ '^ ' => 'PHP_Token_CARET ' ,
37
+ '~ ' => 'PHP_Token_TILDE ' ,
38
+ '` ' => 'PHP_Token_BACKTICK '
39
+ );
40
+
7
41
public function __construct ($ filename ) {
8
- $ this ->tokens = token_get_all ( $ filename) ;
42
+ $ this ->filename = $ filename ;
9
43
}
10
44
11
45
public function next () {
12
- $ numTokens = count ($ this ->tokens );
46
+ $ sourceCode = file_get_contents ($ this ->filename );
47
+ $ tokens = token_get_all ($ sourceCode );
48
+ $ numTokens = count ($ tokens );
13
49
14
50
for ($ i = 0 ; $ i < $ numTokens ; ++$ i ) {
51
+ $ token = $ tokens [$ i ];
15
52
if (is_array ($ token )) {
16
53
$ name = substr (token_name ($ token [0 ]), 2 );
17
54
$ text = $ token [1 ];
@@ -27,6 +64,122 @@ public function next() {
27
64
$ tokenClass = self ::$ customTokens [$ token ];
28
65
}
29
66
67
+ $ token = new $ tokenClass ($ text , $ line , $ this , $ i );
68
+ switch ($ tokenClass ) {
69
+ case 'PHP_Token_HALT_COMPILER ' :
70
+ break ;
71
+
72
+ case 'PHP_Token_INTERFACE ' :
73
+ $ interface = $ token ->getName ();
74
+ $ interfaceEndLine = $ token ->getEndLine ();
75
+
76
+ $ this ->interfaces [$ interface ] = array (
77
+ 'methods ' => array (),
78
+ 'parent ' => $ token ->getParent (),
79
+ 'keywords ' => $ token ->getKeywords (),
80
+ 'docblock ' => $ token ->getDocblock (),
81
+ 'startLine ' => $ token ->getLine (),
82
+ 'endLine ' => $ interfaceEndLine ,
83
+ 'package ' => $ token ->getPackage (),
84
+ 'file ' => $ this ->filename
85
+ );
86
+ break ;
87
+
88
+ case 'PHP_Token_CLASS ' :
89
+ case 'PHP_Token_TRAIT ' :
90
+ $ tmp = array (
91
+ 'methods ' => array (),
92
+ 'parent ' => $ token ->getParent (),
93
+ 'interfaces ' => $ token ->getInterfaces (),
94
+ 'keywords ' => $ token ->getKeywords (),
95
+ 'docblock ' => $ token ->getDocblock (),
96
+ 'startLine ' => $ token ->getLine (),
97
+ 'endLine ' => $ token ->getEndLine (),
98
+ 'package ' => $ token ->getPackage (),
99
+ 'file ' => $ this ->filename
100
+ );
101
+
102
+ if ($ token instanceof PHP_Token_CLASS) {
103
+ $ class = $ token ->getName ();
104
+ $ classEndLine = $ token ->getEndLine ();
105
+ $ this ->classes [$ class ] = $ tmp ;
106
+ } else {
107
+ $ trait = $ token ->getName ();
108
+ $ traitEndLine = $ token ->getEndLine ();
109
+ $ this ->traits [$ trait ] = $ tmp ;
110
+ }
111
+ break ;
112
+
113
+ case 'PHP_Token_FUNCTION ' :
114
+ $ name = $ token ->getName ();
115
+ $ tmp = array (
116
+ 'docblock ' => $ token ->getDocblock (),
117
+ 'keywords ' => $ token ->getKeywords (),
118
+ 'visibility ' => $ token ->getVisibility (),
119
+ 'signature ' => $ token ->getSignature (),
120
+ 'startLine ' => $ token ->getLine (),
121
+ 'endLine ' => $ token ->getEndLine (),
122
+ 'ccn ' => $ token ->getCCN (),
123
+ 'file ' => $ this ->filename
124
+ );
125
+
126
+ if ($ class === false &&
127
+ $ trait === false &&
128
+ $ interface === false ) {
129
+ $ this ->functions [$ name ] = $ tmp ;
130
+
131
+ for ($ line = $ tmp ['startLine ' ]; $ line <= $ tmp ['endLine ' ]; $ line ++) {
132
+ $ this ->lineToFunctionMap [$ line ] = $ name ;
133
+ }
134
+ } elseif ($ class !== false ) {
135
+ $ this ->classes [$ class ]['methods ' ][$ name ] = $ tmp ;
136
+
137
+ for ($ line = $ tmp ['startLine ' ]; $ line <= $ tmp ['endLine ' ]; $ line ++) {
138
+ $ this ->lineToFunctionMap [$ line ] = $ class . ':: ' . $ name ;
139
+ }
140
+ } elseif ($ trait !== false ) {
141
+ $ this ->traits [$ trait ]['methods ' ][$ name ] = $ tmp ;
142
+
143
+ for ($ line = $ tmp ['startLine ' ]; $ line <= $ tmp ['endLine ' ]; $ line ++) {
144
+ $ this ->lineToFunctionMap [$ line ] = $ trait . ':: ' . $ name ;
145
+ }
146
+ } else {
147
+ $ this ->interfaces [$ interface ]['methods ' ][$ name ] = $ tmp ;
148
+ }
149
+ break ;
150
+
151
+ case 'PHP_Token_CLOSE_CURLY ' :
152
+ if ($ classEndLine !== false &&
153
+ $ classEndLine == $ token ->getLine ()) {
154
+ $ class = false ;
155
+ $ classEndLine = false ;
156
+ } elseif ($ traitEndLine !== false &&
157
+ $ traitEndLine == $ token ->getLine ()) {
158
+ $ trait = false ;
159
+ $ traitEndLine = false ;
160
+ } elseif ($ interfaceEndLine !== false &&
161
+ $ interfaceEndLine == $ token ->getLine ()) {
162
+ $ interface = false ;
163
+ $ interfaceEndLine = false ;
164
+ }
165
+ break ;
166
+
167
+ case 'PHP_Token_COMMENT ' :
168
+ // fall through
169
+ case 'PHP_Token_DOC_COMMENT ' :
170
+ $ this ->linesOfCode ['cloc ' ] += $ lines + 1 ;
171
+ break ;
172
+ }
173
+
174
+ $ lines = substr_count ($ text , "\n" );
175
+ $ line += $ lines ;
176
+
177
+ if ($ name == 'DOUBLE_COLON ' ) {
178
+ $ lastNonWhitespaceTokenWasDoubleColon = true ;
179
+ } elseif ($ name != 'WHITESPACE ' ) {
180
+ $ lastNonWhitespaceTokenWasDoubleColon = false ;
181
+ }
182
+
30
183
if (false ) {
31
184
yield "class " => [];
32
185
} else if (false ) {
@@ -35,6 +188,10 @@ public function next() {
35
188
yield "function " => [];
36
189
}
37
190
}
191
+
192
+ $ this ->linesOfCode ['loc ' ] = substr_count ($ sourceCode , "\n" );
193
+ $ this ->linesOfCode ['ncloc ' ] = $ this ->linesOfCode ['loc ' ] -
194
+ $ this ->linesOfCode ['cloc ' ];
38
195
}
39
196
40
197
public function getLinesOfCode () {
0 commit comments