Files
Курнат Андрей 2315f25754 Initial QSfera import
2026-06-07 10:20:04 +03:00

83 lines
1.5 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 ast
import (
"fmt"
"io"
"strings"
)
// Pretty writes a pretty representation of the AST rooted at x to w.
//
// This is function is intended for debug purposes when inspecting ASTs.
func Pretty(w io.Writer, x any) {
pp := &prettyPrinter{
depth: -1,
w: w,
}
NewBeforeAfterVisitor(pp.Before, pp.After).Walk(x)
}
type prettyPrinter struct {
depth int
w io.Writer
}
func (pp *prettyPrinter) Before(x any) bool {
switch x.(type) {
case *Term:
default:
pp.depth++
}
switch x := x.(type) {
case *Term:
return false
case Args:
if len(x) == 0 {
return false
}
pp.writeType(x)
case *Expr:
extras := []string{}
if x.Negated {
extras = append(extras, "negated")
}
extras = append(extras, fmt.Sprintf("index=%d", x.Index))
pp.writeIndent("%v %v", TypeName(x), strings.Join(extras, " "))
case Null, Boolean, Number, String, Var:
pp.writeValue(x)
default:
pp.writeType(x)
}
return false
}
func (pp *prettyPrinter) After(x any) {
switch x.(type) {
case *Term:
default:
pp.depth--
}
}
func (pp *prettyPrinter) writeValue(x any) {
pp.writeIndent(fmt.Sprint(x))
}
func (pp *prettyPrinter) writeType(x any) {
pp.writeIndent(TypeName(x))
}
func (pp *prettyPrinter) writeIndent(f string, a ...any) {
pad := strings.Repeat(" ", pp.depth)
pp.write(pad+f, a...)
}
func (pp *prettyPrinter) write(f string, a ...any) {
fmt.Fprintf(pp.w, f+"\n", a...)
}