71174f6626
It's been a while since the last time, so quite a lot of stuff has accumulated here. Change-Id: I0762827c197b30a917ff470fd8ae8f220f6ba247 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7597 Reviewed-by: grfn <grfn@gws.fyi> Autosubmit: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI
468 lines
17 KiB
Rust
468 lines
17 KiB
Rust
//! Pretty-printed format for the rnix AST representation.
|
|
//!
|
|
//! The AST is serialised into a JSON structure that can then be
|
|
//! printed in either minimised or well-formatted style.
|
|
|
|
use rnix::ast::{self, AstToken, HasEntry};
|
|
use serde::{ser::SerializeMap, Serialize, Serializer};
|
|
|
|
pub fn pretty_print_expr(expr: &ast::Expr) -> String {
|
|
serde_json::ser::to_string_pretty(&SerializeAST(expr))
|
|
.expect("serializing AST should always succeed")
|
|
}
|
|
|
|
#[repr(transparent)]
|
|
struct SerializeAST<S>(S);
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::Apply> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(3))?;
|
|
map.serialize_entry("kind", "apply")?;
|
|
map.serialize_entry("fn", &SerializeAST(&self.0.lambda().unwrap()))?;
|
|
map.serialize_entry("arg", &SerializeAST(&self.0.argument().unwrap()))?;
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::Assert> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(3))?;
|
|
map.serialize_entry("kind", "assert")?;
|
|
map.serialize_entry("condition", &SerializeAST(&self.0.condition().unwrap()))?;
|
|
map.serialize_entry("body", &SerializeAST(&self.0.body().unwrap()))?;
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::Error> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(2))?;
|
|
map.serialize_entry("kind", "error")?;
|
|
map.serialize_entry("node", &self.0.to_string())?;
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::IfElse> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(4))?;
|
|
map.serialize_entry("kind", "if_else")?;
|
|
map.serialize_entry("condition", &SerializeAST(&self.0.condition().unwrap()))?;
|
|
map.serialize_entry("then_body", &SerializeAST(&self.0.body().unwrap()))?;
|
|
map.serialize_entry("else_body", &SerializeAST(&self.0.else_body().unwrap()))?;
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::Select> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let size = match self.0.default_expr() {
|
|
Some(_) => 4,
|
|
None => 3,
|
|
};
|
|
|
|
let mut map = serializer.serialize_map(Some(size))?;
|
|
map.serialize_entry("kind", "select")?;
|
|
map.serialize_entry("set", &SerializeAST(&self.0.expr().unwrap()))?;
|
|
map.serialize_entry("path", &SerializeAST(self.0.attrpath().unwrap()))?;
|
|
|
|
if let Some(default) = self.0.default_expr() {
|
|
map.serialize_entry("default", &SerializeAST(&default))?;
|
|
}
|
|
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl Serialize for SerializeAST<ast::InterpolPart<String>> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
match &self.0 {
|
|
ast::InterpolPart::Literal(s) => Serialize::serialize(s, serializer),
|
|
ast::InterpolPart::Interpolation(node) => {
|
|
Serialize::serialize(&SerializeAST(&node.expr().unwrap()), serializer)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::Str> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(2))?;
|
|
map.serialize_entry("kind", "string")?;
|
|
|
|
map.serialize_entry(
|
|
"parts",
|
|
&self
|
|
.0
|
|
.normalized_parts()
|
|
.into_iter()
|
|
.map(SerializeAST)
|
|
.collect::<Vec<_>>(),
|
|
)?;
|
|
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl Serialize for SerializeAST<ast::InterpolPart<ast::PathContent>> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
match &self.0 {
|
|
ast::InterpolPart::Literal(p) => Serialize::serialize(p.syntax().text(), serializer),
|
|
ast::InterpolPart::Interpolation(node) => {
|
|
Serialize::serialize(&SerializeAST(&node.expr().unwrap()), serializer)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::Path> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(2))?;
|
|
map.serialize_entry("kind", "path")?;
|
|
|
|
map.serialize_entry(
|
|
"parts",
|
|
&self.0.parts().map(SerializeAST).collect::<Vec<_>>(),
|
|
)?;
|
|
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::Literal> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(2))?;
|
|
map.serialize_entry("kind", "literal")?;
|
|
|
|
match self.0.kind() {
|
|
ast::LiteralKind::Float(val) => map.serialize_entry("float", &val.value().unwrap()),
|
|
ast::LiteralKind::Integer(val) => map.serialize_entry("int", &val.value().unwrap()),
|
|
ast::LiteralKind::Uri(val) => map.serialize_entry("uri", val.syntax().text()),
|
|
}?;
|
|
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl Serialize for SerializeAST<ast::PatEntry> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(None)?;
|
|
map.serialize_entry("ident", &SerializeAST(&self.0.ident().unwrap()))?;
|
|
|
|
if let Some(default) = self.0.default() {
|
|
map.serialize_entry("default", &SerializeAST(&default))?;
|
|
}
|
|
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl Serialize for SerializeAST<ast::Param> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
match &self.0 {
|
|
ast::Param::Pattern(pat) => {
|
|
let mut map = serializer.serialize_map(None)?;
|
|
map.serialize_entry("kind", "formals")?;
|
|
|
|
map.serialize_entry(
|
|
"entries",
|
|
&pat.pat_entries().map(SerializeAST).collect::<Vec<_>>(),
|
|
)?;
|
|
|
|
if let Some(bind) = pat.pat_bind() {
|
|
map.serialize_entry("bind", &SerializeAST(&bind.ident().unwrap()))?;
|
|
}
|
|
|
|
map.serialize_entry("ellipsis", &pat.ellipsis_token().is_some())?;
|
|
|
|
map.end()
|
|
}
|
|
|
|
ast::Param::IdentParam(node) => {
|
|
Serialize::serialize(&SerializeAST(&node.ident().unwrap()), serializer)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::Lambda> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(3))?;
|
|
map.serialize_entry("kind", "lambda")?;
|
|
map.serialize_entry("param", &SerializeAST(self.0.param().unwrap()))?;
|
|
map.serialize_entry("body", &SerializeAST(self.0.body().unwrap()))?;
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::LegacyLet> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(3))?;
|
|
map.serialize_entry("kind", "legacy_let")?;
|
|
|
|
map.serialize_entry(
|
|
"entries",
|
|
&self
|
|
.0
|
|
.attrpath_values()
|
|
.map(SerializeAST)
|
|
.collect::<Vec<_>>(),
|
|
)?;
|
|
|
|
map.serialize_entry(
|
|
"inherits",
|
|
&self.0.inherits().map(SerializeAST).collect::<Vec<_>>(),
|
|
)?;
|
|
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::LetIn> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(3))?;
|
|
map.serialize_entry("kind", "let")?;
|
|
|
|
map.serialize_entry(
|
|
"entries",
|
|
&self
|
|
.0
|
|
.attrpath_values()
|
|
.map(SerializeAST)
|
|
.collect::<Vec<_>>(),
|
|
)?;
|
|
|
|
map.serialize_entry(
|
|
"inherits",
|
|
&self.0.inherits().map(SerializeAST).collect::<Vec<_>>(),
|
|
)?;
|
|
|
|
map.serialize_entry("body", &SerializeAST(&self.0.body().unwrap()))?;
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::List> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let list = self.0.items().map(SerializeAST).collect::<Vec<_>>();
|
|
|
|
let mut map = serializer.serialize_map(Some(2))?;
|
|
map.serialize_entry("kind", "list")?;
|
|
map.serialize_entry("items", &list)?;
|
|
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::BinOp> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(4))?;
|
|
map.serialize_entry("kind", "binary_op")?;
|
|
|
|
map.serialize_entry(
|
|
"operator",
|
|
match self.0.operator().unwrap() {
|
|
ast::BinOpKind::Concat => "concat",
|
|
ast::BinOpKind::Update => "update",
|
|
ast::BinOpKind::Add => "add",
|
|
ast::BinOpKind::Sub => "sub",
|
|
ast::BinOpKind::Mul => "mul",
|
|
ast::BinOpKind::Div => "div",
|
|
ast::BinOpKind::And => "and",
|
|
ast::BinOpKind::Equal => "equal",
|
|
ast::BinOpKind::Implication => "implication",
|
|
ast::BinOpKind::Less => "less",
|
|
ast::BinOpKind::LessOrEq => "less_or_eq",
|
|
ast::BinOpKind::More => "more",
|
|
ast::BinOpKind::MoreOrEq => "more_or_eq",
|
|
ast::BinOpKind::NotEqual => "not_equal",
|
|
ast::BinOpKind::Or => "or",
|
|
},
|
|
)?;
|
|
|
|
map.serialize_entry("lhs", &SerializeAST(&self.0.lhs().unwrap()))?;
|
|
map.serialize_entry("rhs", &SerializeAST(&self.0.rhs().unwrap()))?;
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::Paren> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(2))?;
|
|
map.serialize_entry("kind", "paren")?;
|
|
map.serialize_entry("expr", &SerializeAST(&self.0.expr().unwrap()))?;
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::Root> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(2))?;
|
|
map.serialize_entry("kind", "root")?;
|
|
map.serialize_entry("expr", &SerializeAST(&self.0.expr().unwrap()))?;
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl Serialize for SerializeAST<ast::AttrpathValue> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(2))?;
|
|
map.serialize_entry("name", &SerializeAST(self.0.attrpath().unwrap()))?;
|
|
map.serialize_entry("value", &SerializeAST(self.0.value().unwrap()))?;
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl Serialize for SerializeAST<ast::Inherit> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(None)?;
|
|
|
|
if let Some(from) = self.0.from() {
|
|
map.serialize_entry("namespace", &SerializeAST(&from.expr().unwrap()))?;
|
|
}
|
|
|
|
map.serialize_entry(
|
|
"names",
|
|
&self.0.attrs().map(SerializeAST).collect::<Vec<_>>(),
|
|
)?;
|
|
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::AttrSet> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(None)?;
|
|
map.serialize_entry("kind", "attrset")?;
|
|
map.serialize_entry("recursive", &self.0.rec_token().is_some())?;
|
|
|
|
map.serialize_entry(
|
|
"entries",
|
|
&self
|
|
.0
|
|
.attrpath_values()
|
|
.map(SerializeAST)
|
|
.collect::<Vec<_>>(),
|
|
)?;
|
|
|
|
map.serialize_entry(
|
|
"inherits",
|
|
&self.0.inherits().map(SerializeAST).collect::<Vec<_>>(),
|
|
)?;
|
|
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::UnaryOp> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(3))?;
|
|
map.serialize_entry("kind", "unary_op")?;
|
|
|
|
map.serialize_entry(
|
|
"operator",
|
|
match self.0.operator().unwrap() {
|
|
ast::UnaryOpKind::Invert => "invert",
|
|
ast::UnaryOpKind::Negate => "negate",
|
|
},
|
|
)?;
|
|
|
|
map.serialize_entry("expr", &SerializeAST(&self.0.expr().unwrap()))?;
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::Ident> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(2))?;
|
|
map.serialize_entry("kind", "ident")?;
|
|
map.serialize_entry("ident", self.0.ident_token().unwrap().text())?;
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::With> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(3))?;
|
|
map.serialize_entry("kind", "with")?;
|
|
map.serialize_entry("with", &SerializeAST(&self.0.namespace().unwrap()))?;
|
|
map.serialize_entry("body", &SerializeAST(&self.0.body().unwrap()))?;
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::Dynamic> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(2))?;
|
|
map.serialize_entry("kind", "dynamic")?;
|
|
map.serialize_entry("expr", &SerializeAST(&self.0.expr().unwrap()))?;
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl Serialize for SerializeAST<ast::Attr> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
match &self.0 {
|
|
ast::Attr::Ident(ident) => Serialize::serialize(&SerializeAST(ident), serializer),
|
|
ast::Attr::Dynamic(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Attr::Str(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Serialize for SerializeAST<ast::Attrpath> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(2))?;
|
|
map.serialize_entry("kind", "attrpath")?;
|
|
|
|
map.serialize_entry(
|
|
"path",
|
|
&self.0.attrs().map(SerializeAST).collect::<Vec<_>>(),
|
|
)?;
|
|
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::HasAttr> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let mut map = serializer.serialize_map(Some(3))?;
|
|
map.serialize_entry("kind", "has_attr")?;
|
|
map.serialize_entry("expr", &SerializeAST(&self.0.expr().unwrap()))?;
|
|
map.serialize_entry("attrpath", &SerializeAST(self.0.attrpath().unwrap()))?;
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
impl<'a> Serialize for SerializeAST<&'a ast::Expr> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
match self.0 {
|
|
ast::Expr::Apply(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::Assert(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::Error(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::IfElse(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::Select(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::Str(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::Path(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::Literal(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::Lambda(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::LegacyLet(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::LetIn(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::List(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::BinOp(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::Paren(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::Root(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::AttrSet(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::UnaryOp(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::Ident(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::With(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
ast::Expr::HasAttr(node) => Serialize::serialize(&SerializeAST(node), serializer),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Serialize for SerializeAST<ast::Expr> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
SerializeAST(&self.0).serialize(serializer)
|
|
}
|
|
}
|