Skip to content

Commit 6f3eff4

Browse files
committed
Do separate patcher phase for those that require multiple passes (Currently only need for Operator overloading). This patcher phase is run after other patchers.
1 parent bbea51f commit 6f3eff4

File tree

1 file changed

+38
-26
lines changed

1 file changed

+38
-26
lines changed

checker/checker.go

+38-26
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,40 @@ import (
1313
"github.com/expr-lang/expr/parser"
1414
)
1515

16+
// Run visitors in a given config over the given tree
17+
// runRepeatable controls whether to filter for only vistors that require multiple passes or not
18+
func runVisitors(tree *parser.Tree, config *conf.Config, runRepeatable bool) {
19+
for {
20+
more := false
21+
for _, v := range config.Visitors {
22+
// We need to perform types check, because some visitors may rely on
23+
// types information available in the tree.
24+
_, _ = Check(tree, config)
25+
26+
r, repeatable := v.(interface {
27+
Reset()
28+
ShouldRepeat() bool
29+
})
30+
31+
if repeatable {
32+
if runRepeatable {
33+
r.Reset()
34+
ast.Walk(&tree.Node, v)
35+
more = more || r.ShouldRepeat()
36+
}
37+
} else {
38+
if !runRepeatable {
39+
ast.Walk(&tree.Node, v)
40+
}
41+
}
42+
}
43+
44+
if !more {
45+
break
46+
}
47+
}
48+
}
49+
1650
// ParseCheck parses input expression and checks its types. Also, it applies
1751
// all provided patchers. In case of error, it returns error with a tree.
1852
func ParseCheck(input string, config *conf.Config) (*parser.Tree, error) {
@@ -22,33 +56,11 @@ func ParseCheck(input string, config *conf.Config) (*parser.Tree, error) {
2256
}
2357

2458
if len(config.Visitors) > 0 {
25-
for {
26-
more := false
27-
for _, v := range config.Visitors {
28-
// We need to perform types check, because some visitors may rely on
29-
// types information available in the tree.
30-
_, _ = Check(tree, config)
31-
32-
r, repeatable := v.(interface {
33-
Reset()
34-
ShouldRepeat() bool
35-
});
36-
37-
if repeatable {
38-
r.Reset()
39-
}
40-
41-
ast.Walk(&tree.Node, v)
42-
43-
if repeatable {
44-
more = more || r.ShouldRepeat()
45-
}
46-
}
59+
// Run all patchers that dont support being run repeatedly first
60+
runVisitors(tree, config, false)
4761

48-
if !more {
49-
break
50-
}
51-
}
62+
// Run patchers that require multiple passes next (currently only Operator patching)
63+
runVisitors(tree, config, true)
5264
}
5365
_, err = Check(tree, config)
5466
if err != nil {

0 commit comments

Comments
 (0)