Skip to content

Commit 18de8b8

Browse files
committed
pattern: collect symbols for efficient call expression matching
Updates: dominikhgh-1652
1 parent de2104d commit 18de8b8

File tree

1 file changed

+66
-4
lines changed

1 file changed

+66
-4
lines changed

pattern/parser.go

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
147207
func 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

Comments
 (0)