Coverage Report

Created: 2026-05-27 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/common/ast_rewrite.h
Line
Count
Source
1
// Copyright 2024 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#ifndef THIRD_PARTY_CEL_CPP_COMMON_AST_REWRITE_H_
16
#define THIRD_PARTY_CEL_CPP_COMMON_AST_REWRITE_H_
17
18
#include "absl/base/nullability.h"
19
#include "absl/types/span.h"
20
#include "common/ast_visitor.h"
21
#include "common/constant.h"
22
#include "common/expr.h"
23
24
namespace cel {
25
26
// Traversal options for AstRewrite.
27
struct RewriteTraversalOptions {
28
  // If enabled, use comprehension specific callbacks instead of the general
29
  // arguments callbacks.
30
  bool use_comprehension_callbacks;
31
32
0
  RewriteTraversalOptions() : use_comprehension_callbacks(false) {}
33
};
34
35
// Interface for AST rewriters.
36
// Extends AstVisitor interface with update methods.
37
// see AstRewrite for more details on usage.
38
class AstRewriter : public AstVisitor {
39
 public:
40
0
  ~AstRewriter() override {}
41
42
  // Rewrite a sub expression before visiting.
43
  // Occurs before visiting Expr. If expr is modified, it the new value will be
44
  // visited.
45
  virtual bool PreVisitRewrite(Expr& expr) = 0;
46
47
  // Rewrite a sub expression after visiting.
48
  // Occurs after visiting expr and it's children. If expr is modified, the old
49
  // sub expression is visited.
50
  virtual bool PostVisitRewrite(Expr& expr) = 0;
51
52
  // Notify the visitor of updates to the traversal stack.
53
  virtual void TraversalStackUpdate(
54
      absl::Span<const Expr* absl_nonnull> path) = 0;
55
};
56
57
// Trivial implementation for AST rewriters.
58
// Virtual methods are overridden with no-op callbacks.
59
class AstRewriterBase : public AstRewriter {
60
 public:
61
0
  ~AstRewriterBase() override {}
62
63
0
  void PreVisitExpr(const Expr&) override {}
64
65
0
  void PostVisitExpr(const Expr&) override {}
66
67
0
  void PostVisitConst(const Expr&, const Constant&) override {}
68
69
0
  void PostVisitIdent(const Expr&, const IdentExpr&) override {}
70
71
0
  void PreVisitSelect(const Expr&, const SelectExpr&) override {}
72
73
0
  void PostVisitSelect(const Expr&, const SelectExpr&) override {}
74
75
0
  void PreVisitCall(const Expr&, const CallExpr&) override {}
76
77
0
  void PostVisitCall(const Expr&, const CallExpr&) override {}
78
79
0
  void PreVisitComprehension(const Expr&, const ComprehensionExpr&) override {}
80
81
0
  void PostVisitComprehension(const Expr&, const ComprehensionExpr&) override {}
82
83
0
  void PostVisitArg(const Expr&, int) override {}
84
85
0
  void PostVisitTarget(const Expr&) override {}
86
87
0
  void PostVisitList(const Expr&, const ListExpr&) override {}
88
89
0
  void PostVisitStruct(const Expr&, const StructExpr&) override {}
90
91
0
  void PostVisitMap(const Expr&, const MapExpr&) override {}
92
93
0
  bool PreVisitRewrite(Expr& expr) override { return false; }
94
95
0
  bool PostVisitRewrite(Expr& expr) override { return false; }
96
97
  void TraversalStackUpdate(
98
0
      absl::Span<const Expr* absl_nonnull> path) override {}
99
};
100
101
// Traverses the AST representation in an expr proto. Returns true if any
102
// rewrites occur.
103
//
104
// Rewrites may happen before and/or after visiting an expr subtree. If a
105
// change happens during the pre-visit rewrite, the updated subtree will be
106
// visited. If a change happens during the post-visit rewrite, the old subtree
107
// will be visited.
108
//
109
// expr: root node of the tree.
110
// source_info: optional additional parse information about the expression
111
// visitor: the callback object that receives the visitation notifications
112
// options: options for traversal. see RewriteTraversalOptions. Defaults are
113
//     used if not sepecified.
114
//
115
// Traversal order follows the pattern:
116
// PreVisitRewrite
117
// PreVisitExpr
118
// ..PreVisit{ExprKind}
119
// ....PreVisit{ArgumentIndex}
120
// .......PreVisitExpr (subtree)
121
// .......PostVisitExpr (subtree)
122
// ....PostVisit{ArgumentIndex}
123
// ..PostVisit{ExprKind}
124
// PostVisitExpr
125
// PostVisitRewrite
126
//
127
// Example callback order for fn(1, var):
128
// PreVisitExpr
129
// ..PreVisitCall(fn)
130
// ......PreVisitExpr
131
// ........PostVisitConst(1)
132
// ......PostVisitExpr
133
// ....PostVisitArg(fn, 0)
134
// ......PreVisitExpr
135
// ........PostVisitIdent(var)
136
// ......PostVisitExpr
137
// ....PostVisitArg(fn, 1)
138
// ..PostVisitCall(fn)
139
// PostVisitExpr
140
141
bool AstRewrite(Expr& expr, AstRewriter& visitor,
142
                RewriteTraversalOptions options = RewriteTraversalOptions());
143
144
}  // namespace cel
145
146
#endif  // THIRD_PARTY_CEL_CPP_COMMON_AST_REWRITE_H_