@@ -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.
1852func ParseCheck (input string , config * conf.Config ) (* parser.Tree , error ) {
@@ -22,25 +56,11 @@ func ParseCheck(input string, config *conf.Config) (*parser.Tree, error) {
2256 }
2357
2458 if len (config .Visitors ) > 0 {
25- for i := 0 ; i < 1000 ; i ++ {
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- ast .Walk (& tree .Node , v )
33-
34- if v , ok := v .(interface {
35- ShouldRepeat () bool
36- }); ok {
37- more = more || v .ShouldRepeat ()
38- }
39- }
40- if ! more {
41- break
42- }
43- }
59+ // Run all patchers that dont support being run repeatedly first
60+ runVisitors (tree , config , false )
61+
62+ // Run patchers that require multiple passes next (currently only Operator patching)
63+ runVisitors (tree , config , true )
4464 }
4565 _ , err = Check (tree , config )
4666 if err != nil {
0 commit comments