@@ -20,6 +20,10 @@ type Pattern struct {
2020 // typeindex.
2121 SymbolsPattern Node
2222
23+ // If non-empty, all possible candidate nodes for this pattern can be found
24+ // by finding all call expressions for this list of symbols.
25+ RootCallSymbols []IndexSymbol
26+
2327 // Mapping from binding index to binding name
2428 Bindings []string
2529}
@@ -144,6 +148,62 @@ func collectSymbols(node Node, inSymbol bool) Node {
144148 }
145149}
146150
151+ func collectRootCallSymbols (node Node ) []IndexSymbol {
152+ root , ok := node .(CallExpr )
153+ if ! ok {
154+ return nil
155+ }
156+
157+ var names []String
158+ var handleSymName func (name Node ) bool
159+ handleSymName = func (name Node ) bool {
160+ switch name := name .(type ) {
161+ case String :
162+ names = append (names , name )
163+ case Or :
164+ for _ , node := range name .Nodes {
165+ if name , ok := node .(String ); ok {
166+ names = append (names , name )
167+ } else {
168+ return false
169+ }
170+ }
171+ case Binding :
172+ return handleSymName (name .Node )
173+ default :
174+ return false
175+ }
176+ return true
177+ }
178+ var handleRootFun func (node Node ) bool
179+ handleRootFun = func (node Node ) bool {
180+ switch fun := node .(type ) {
181+ case Binding :
182+ return handleRootFun (fun .Node )
183+ case Symbol :
184+ return handleSymName (fun .Name )
185+ case Or :
186+ for _ , node := range fun .Nodes {
187+ if sym , ok := node .(Symbol ); ! ok || ! handleSymName (sym .Name ) {
188+ return false
189+ }
190+ }
191+ return true
192+ default :
193+ return false
194+ }
195+ }
196+ if ! handleRootFun (root .Fun ) {
197+ return nil
198+ }
199+
200+ out := make ([]IndexSymbol , len (names ))
201+ for i , name := range names {
202+ out [i ] = symbolToIndexSymbol (string (name ))
203+ }
204+ return out
205+ }
206+
147207func collectEntryNodes (node Node , m map [reflect.Type ]struct {}) {
148208 switch node := node .(type ) {
149209 case Or :
@@ -336,11 +396,13 @@ func (p *Parser) Parse(s string) (Pattern, error) {
336396 collectEntryNodes (root , relevant )
337397 _ , isSymbol := root .(Symbol )
338398 sym := collectSymbols (root , isSymbol )
399+ rootSyms := collectRootCallSymbols (root )
339400 return Pattern {
340- Root : root ,
341- EntryNodes : relevant ,
342- SymbolsPattern : sym ,
343- Bindings : bindings ,
401+ Root : root ,
402+ EntryNodes : relevant ,
403+ SymbolsPattern : sym ,
404+ RootCallSymbols : rootSyms ,
405+ Bindings : bindings ,
344406 }, nil
345407}
346408
0 commit comments