@@ -13,6 +13,40 @@ import (
13
13
"github.com/expr-lang/expr/parser"
14
14
)
15
15
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
+
16
50
// ParseCheck parses input expression and checks its types. Also, it applies
17
51
// all provided patchers. In case of error, it returns error with a tree.
18
52
func ParseCheck (input string , config * conf.Config ) (* parser.Tree , error ) {
@@ -22,33 +56,11 @@ func ParseCheck(input string, config *conf.Config) (*parser.Tree, error) {
22
56
}
23
57
24
58
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 )
47
61
48
- if ! more {
49
- break
50
- }
51
- }
62
+ // Run patchers that require multiple passes next (currently only Operator patching)
63
+ runVisitors (tree , config , true )
52
64
}
53
65
_ , err = Check (tree , config )
54
66
if err != nil {
0 commit comments