85 lines
1.4 KiB
Go
85 lines
1.4 KiB
Go
// Copyright 2018 The OPA Authors. All rights reserved.
|
|
// Use of this source code is governed by an Apache2
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package ir
|
|
|
|
// Visitor defines the interface for visiting IR nodes.
|
|
type Visitor interface {
|
|
Before(x interface{})
|
|
Visit(x interface{}) (Visitor, error)
|
|
After(x interface{})
|
|
}
|
|
|
|
// Walk invokes the visitor for nodes under x.
|
|
func Walk(vis Visitor, x interface{}) error {
|
|
impl := walkerImpl{
|
|
vis: vis,
|
|
}
|
|
impl.walk(x)
|
|
return impl.err
|
|
}
|
|
|
|
type walkerImpl struct {
|
|
vis Visitor
|
|
err error
|
|
}
|
|
|
|
func (w *walkerImpl) walk(x interface{}) {
|
|
|
|
if x == nil {
|
|
return
|
|
}
|
|
|
|
prev := w.vis
|
|
w.vis.Before(x)
|
|
defer w.vis.After(x)
|
|
w.vis, w.err = w.vis.Visit(x)
|
|
if w.err != nil {
|
|
return
|
|
} else if w.vis == nil {
|
|
w.vis = prev
|
|
return
|
|
}
|
|
|
|
switch x := x.(type) {
|
|
case *Policy:
|
|
w.walk(x.Static)
|
|
w.walk(x.Plan)
|
|
w.walk(x.Funcs)
|
|
case *Static:
|
|
for _, s := range x.Strings {
|
|
w.walk(s)
|
|
}
|
|
for _, f := range x.BuiltinFuncs {
|
|
w.walk(f)
|
|
}
|
|
case *Funcs:
|
|
for _, fn := range x.Funcs {
|
|
w.walk(fn)
|
|
}
|
|
case *Func:
|
|
for _, b := range x.Blocks {
|
|
w.walk(b)
|
|
}
|
|
case *Plan:
|
|
for _, b := range x.Blocks {
|
|
w.walk(b)
|
|
}
|
|
case *Block:
|
|
for _, s := range x.Stmts {
|
|
w.walk(s)
|
|
}
|
|
case *BlockStmt:
|
|
for _, b := range x.Blocks {
|
|
w.walk(b)
|
|
}
|
|
case *ScanStmt:
|
|
w.walk(x.Block)
|
|
case *NotStmt:
|
|
w.walk(x.Block)
|
|
case *WithStmt:
|
|
w.walk(x.Block)
|
|
}
|
|
}
|