@@ -3,24 +3,28 @@ const locator = require('ruby-method-locate'),
33 minimatch = require ( 'minimatch' ) ;
44const fs = require ( 'fs' ) ,
55 path = require ( 'path' ) ;
6+ const _ = require ( 'lodash' ) ;
67
7- function flatten ( tree , result ) {
8- let t ;
9- for ( let a in tree ) {
10- t = tree [ a ] ;
11- if ( typeof t === 'string' || typeof t === 'number' ) continue ;
12- if ( t . posn ) {
13- if ( a in result ) result [ a ] . push ( {
14- line : t . posn . line ,
15- char : t . posn . char
16- } ) ;
17- else result [ a ] = [ {
18- line : t . posn . line ,
19- char : t . posn . char
20- } ] ;
21- }
22- flatten ( t , result ) ;
23- }
8+ function flatten ( locateInfo , file , parentName ) {
9+ return _ . flatMap ( locateInfo , ( symbols , type ) => {
10+ // TODO: return accessor or other types.
11+ // TODO: parse include and inherit to find inherited symbols.
12+ if ( ! _ . includes ( [ 'module' , 'class' , 'method' , 'classMethod' ] , type ) ) return [ ] ;
13+ return _ . flatMap ( symbols , ( children , name ) => {
14+ const sep = { method : '#' , classMethod : '.' } [ type ] || '::' ;
15+ const posn = children . posn || { line : 0 , char : 0 } ;
16+ const fullName = parentName ? `${ parentName } ${ sep } ${ name } ` : name ;
17+ const symbolInfo = {
18+ // TODO: parse names like 'ActiveRecord::Base'
19+ name : name ,
20+ file : file ,
21+ line : posn . line ,
22+ char : posn . char ,
23+ fullName : fullName
24+ } ;
25+ return [ symbolInfo ] . concat ( flatten ( children , file , fullName ) ) ;
26+ } ) ;
27+ } ) ;
2428}
2529module . exports = class Locate {
2630 constructor ( root , settings ) {
@@ -34,26 +38,16 @@ module.exports = class Locate {
3438 // add lookup hooks
3539 }
3640 find ( name ) {
37- let result = [ ] ;
38- let tree ;
39- for ( let file in this . tree ) {
40- tree = this . tree [ file ] ;
41- //jshint -W083
42- const extract = obj => ( {
43- file : file ,
44- line : obj . line ,
45- char : obj . char
46- } ) ;
47- //jshint +W083
48- for ( let n in tree ) {
49- // because our word pattern is designed to match symbols
50- // things like Gem::RequestSet may request a search for ':RequestSet'
51- if ( n === name || n === name + '=' || ':' + n === name ) {
52- result = result . concat ( tree [ n ] . map ( extract ) ) ;
53- }
54- }
55- }
56- return result ;
41+ // because our word pattern is designed to match symbols
42+ // things like Gem::RequestSet may request a search for ':RequestSet'
43+ const escapedName = _ . escapeRegExp ( _ . trimStart ( name , ':' ) ) ;
44+ const regexp = new RegExp ( `^${ escapedName } =?\$` ) ;
45+ return _ ( this . tree )
46+ . values ( )
47+ . flatten ( )
48+ . filter ( symbol => regexp . test ( symbol . name ) )
49+ . map ( _ . clone )
50+ . value ( ) ;
5751 }
5852 rm ( absPath ) {
5953 if ( absPath in this . tree ) delete this . tree [ absPath ] ;
@@ -66,8 +60,7 @@ module.exports = class Locate {
6660 locator ( absPath )
6761 . then ( result => {
6862 if ( ! result ) return ;
69- this . tree [ absPath ] = { } ;
70- flatten ( result , this . tree [ absPath ] ) ;
63+ this . tree [ absPath ] = flatten ( result , absPath ) ;
7164 } , err => {
7265 if ( err . code === 'EMFILE' ) {
7366 // if there are too many open files
@@ -97,4 +90,4 @@ module.exports = class Locate {
9790 } ) ;
9891 } ) ;
9992 }
100- } ;
93+ } ;
0 commit comments