@@ -41,16 +41,33 @@ var repository = function(directory, options) {
4141 this . files = { } ;
4242 // options
4343 this . options = {
44- exclude : [ '.git' , '.svn' ] ,
44+ // list of excluded directory names
45+ exclude : [ '.git' , '.svn' , 'node_modules' ] ,
46+ // list of included directories
4547 include : [ './' ] ,
48+ // list of php extension files
4649 ext : [
4750 '*.php' , '*.php3' , '*.php5' , '*.phtml' ,
4851 '*.inc' , '*.class' , '*.req'
4952 ] ,
53+ // extract vars from each scope (functions, classes)
54+ // may use memory but could be usefull for resolving
55+ // their type (on autocompletion)
5056 scanVars : true ,
57+ // extract scopes from
5158 scanExpr : true ,
59+ // default parsing encoding
5260 encoding : 'utf8' ,
53- cacheByFileSize : true
61+ // should spawn a worker process to avoir blocking
62+ // the main loop (may be slower with small projects or single cpu)
63+ forkWorker : require ( 'os' ) . cpus ( ) . length > 1 ,
64+ // use the file mtime property to check changes
65+ cacheByFileDate : true ,
66+ // use the file size to detect changes
67+ cacheByFileSize : false ,
68+ // use an hash algorithm to detect changes
69+ // if low cache hit, may slow down the parsing
70+ cacheByFileHash : true
5471 } ;
5572 // extends options
5673 if ( options && typeof options === 'object' ) {
@@ -136,7 +153,10 @@ repository.prototype.scan = function(directory) {
136153 // handle in-memory cache
137154 if ( self . files . hasOwnProperty ( filename ) ) {
138155 // check if need to parse again
139- if ( self . files [ filename ] . version > stat . mtime ) {
156+ if (
157+ self . options . cacheByFileDate &&
158+ self . files [ filename ] . mtime === stat . mtime
159+ ) {
140160 return done ( self . files [ filename ] ) ;
141161 }
142162 // same size and
@@ -172,47 +192,65 @@ repository.prototype.parse = function(filename, encoding) {
172192 this . files [ filename ] = new Promise ( function ( done , reject ) {
173193 self . counter . total ++ ;
174194 self . counter . loading ++ ;
175- fs . readFile (
176- path . resolve ( self . directory , filename ) ,
177- encoding , function ( err , data ) {
178- self . counter . loading -- ;
179- if ( ! err ) {
180- try {
181- var reader = new parser ( {
182- parser : {
183- locations : true ,
184- extractDoc : true ,
185- suppressErrors : true
186- }
187- } ) ;
188- data = data . toString ( encoding ) ;
189- var ast = reader . parseCode ( data ) ;
190- } catch ( e ) {
191- err = e ;
192- }
193- }
194- if ( err ) {
195+ if ( self . options . forkWorker ) {
196+ // reads from a forked process
197+ require ( './worker' ) ( ) . then ( function ( cache ) {
198+ self . counter . loading -- ;
199+ self . files [ filename ] = file . import ( self , cache ) ;
200+ self . files [ filename ] . refresh ( ) ;
201+ self . counter . loaded ++ ;
202+ self . emit ( 'progress' , self . counter ) ;
203+ } , function ( e ) {
204+ self . counter . loading -- ;
195205 self . counter . total -- ;
206+ self . counter . error ++ ;
196207 delete self . files [ filename ] ;
197- self . emit ( 'error' , err ) ;
198- return reject ( err ) ;
199- } else {
200- try {
201- self . files [ filename ] = new file ( self , filename , ast ) ;
202- self . files [ filename ] . size = data . length ;
203- self . counter . loaded ++ ;
204- self . emit ( 'progress' , self . counter ) ;
205- return done ( self . files [ filename ] ) ;
206- } catch ( e ) {
208+ self . emit ( 'error' , e ) ;
209+ return reject ( e ) ;
210+ } ) ;
211+ } else {
212+ // reads from the main process
213+ fs . readFile (
214+ path . resolve ( self . directory , filename ) ,
215+ encoding , function ( err , data ) {
216+ self . counter . loading -- ;
217+ if ( ! err ) {
218+ try {
219+ var reader = new parser ( {
220+ parser : {
221+ locations : true ,
222+ extractDoc : true ,
223+ suppressErrors : true
224+ }
225+ } ) ;
226+ data = data . toString ( encoding ) ;
227+ var ast = reader . parseCode ( data ) ;
228+ } catch ( e ) {
229+ err = e ;
230+ }
231+ }
232+ if ( err ) {
207233 self . counter . total -- ;
208- self . counter . error ++ ;
209234 delete self . files [ filename ] ;
210- self . emit ( 'error' , e ) ;
211- return reject ( e ) ;
235+ self . emit ( 'error' , err ) ;
236+ return reject ( err ) ;
237+ } else {
238+ try {
239+ self . files [ filename ] = new file ( self , filename , ast ) ;
240+ self . files [ filename ] . size = data . length ;
241+ self . counter . loaded ++ ;
242+ self . emit ( 'progress' , self . counter ) ;
243+ return done ( self . files [ filename ] ) ;
244+ } catch ( e ) {
245+ self . counter . total -- ;
246+ self . counter . error ++ ;
247+ delete self . files [ filename ] ;
248+ self . emit ( 'error' , e ) ;
249+ return reject ( e ) ;
250+ }
212251 }
213-
214- }
215- } ) ;
252+ } ) ;
253+ }
216254 } ) ;
217255 return this . files [ filename ] ;
218256 } else {
@@ -227,13 +265,15 @@ repository.prototype.parse = function(filename, encoding) {
227265 * @return {node[] } {@link NODE.md|:link: }
228266 */
229267repository . prototype . getByType = function ( type , limit ) {
230- if ( ! limit ) limit = 100 ;
268+ if ( ! limit || limit < 1 ) limit = 100 ;
231269 var result = [ ] ;
232270 for ( var k in this . files ) {
233- result = result . concat ( this . files [ k ] . getByType ( type ) ) ;
234- if ( result . length > limit ) {
235- result = result . slice ( 0 , limit ) ;
236- break ;
271+ if ( this . files [ k ] instanceof file ) {
272+ result = result . concat ( this . files [ k ] . getByType ( type ) ) ;
273+ if ( result . length > limit ) {
274+ result = result . slice ( 0 , limit ) ;
275+ break ;
276+ }
237277 }
238278 }
239279 return result ;
@@ -248,9 +288,11 @@ repository.prototype.getByType = function(type, limit) {
248288repository . prototype . getByName = function ( type , name , limit ) {
249289 var result = [ ] ;
250290 for ( var k in this . files ) {
251- var items = this . files [ k ] . getByName ( type , name , limit ) ;
252- if ( items . length > 0 ) {
253- result = result . concat ( items ) ;
291+ if ( this . files [ k ] instanceof file ) {
292+ var items = this . files [ k ] . getByName ( type , name , limit ) ;
293+ if ( items . length > 0 ) {
294+ result = result . concat ( items ) ;
295+ }
254296 }
255297 }
256298 return result ;
@@ -265,8 +307,10 @@ repository.prototype.getByName = function(type, name, limit) {
265307repository . prototype . getFirstByName = function ( type , name ) {
266308 var result = null ;
267309 for ( var k in this . files ) {
268- result = this . files [ k ] . getFirstByName ( type , name ) ;
269- if ( result ) return result ;
310+ if ( this . files [ k ] instanceof file ) {
311+ result = this . files [ k ] . getFirstByName ( type , name ) ;
312+ if ( result ) return result ;
313+ }
270314 }
271315 return null ;
272316} ;
@@ -336,7 +380,7 @@ repository.prototype.remove = function(filename) {
336380 if ( this . files [ filename ] instanceof file ) {
337381 this . files [ filename ] . remove ( ) ;
338382 }
339- delete files [ filename ] ;
383+ delete this . files [ filename ] ;
340384 }
341385 return this ;
342386} ;
@@ -362,7 +406,10 @@ repository.prototype.each = function(cb) {
362406 * @return {scope }
363407 */
364408repository . prototype . scope = function ( filename , offset ) {
365- if ( this . files . hasOwnProperty ( filename ) ) {
409+ if (
410+ this . files . hasOwnProperty ( filename ) &&
411+ this . files [ filename ] instanceof file
412+ ) {
366413 return this . files [ filename ] . getScope ( offset ) ;
367414 } else {
368415 return null ;
@@ -376,7 +423,10 @@ repository.prototype.scope = function(filename, offset) {
376423 * @return {file|null } Returns the file if exists, or null if not defined
377424 */
378425repository . prototype . get = function ( filename ) {
379- if ( this . files . hasOwnProperty ( filename ) ) {
426+ if (
427+ this . files . hasOwnProperty ( filename ) &&
428+ this . files [ filename ] instanceof file
429+ ) {
380430 return this . files [ filename ] ;
381431 } else {
382432 return null ;
@@ -398,11 +448,11 @@ repository.prototype.cache = function(data) {
398448 this . directory = data . directory ;
399449 // creating files from structure
400450 for ( var name in data . files ) {
401- this . files [ name ] = file . import ( data [ name ] ) ;
451+ this . files [ name ] = file . import ( this , data [ name ] ) ;
402452 }
403- // update object links
453+ // rebuild object links
404454 for ( var name in this . files ) {
405- this . files [ name ] . import ( ) ;
455+ this . files [ name ] . refresh ( ) ;
406456 }
407457 }
408458 return this ;
0 commit comments