use crate::ast::*;
use crate::error::Result;
use crate::gen_sexp::gen::Generator;
use crate::gen_sexp::helpers::*;
use crate::sexp::SExp;
impl Generator {
pub fn generate_item(&self, item: &Item) -> Result<SExp> {
let fields = kwargs(vec![
kwarg("attrs", self.generate_attr_vec(&item.attrs)?),
kwarg("id", self.generate_node_id(item.id)),
kwarg("span", self.generate_span(item.span)),
kwarg("vis", self.generate_visibility(&item.vis)),
kwarg("ident", self.generate_ident(&item.ident)),
kwarg("kind", self.generate_item_kind(&item.kind)?),
]);
let fields = if item.tokens.is_some() {
let mut f = fields;
f.extend(kwarg("tokens", sym("nil")));
f
} else {
fields
};
Ok(typed_node("Item", fields))
}
pub fn generate_visibility(&self, vis: &Visibility) -> SExp {
match vis {
Visibility::Public => list(vec![sym("Public")]),
Visibility::Inherited => list(vec![sym("Inherited")]),
Visibility::Restricted { path, shorthand, span } => {
let fields = kwargs(vec![
kwarg("path", self.generate_path(path)),
kwarg("shorthand", self.generate_vis_restriction_kind(*shorthand)),
kwarg("span", self.generate_span(*span)),
]);
typed_node("Restricted", fields)
}
}
}
pub fn generate_ident(&self, ident: &Ident) -> SExp {
let fields = kwargs(vec![
kwarg("name", string(&ident.name)),
kwarg("span", self.generate_span(ident.span)),
]);
typed_node("Ident", fields)
}
fn generate_item_kind(&self, kind: &ItemKind) -> Result<SExp> {
match kind {
ItemKind::Fn(func) => Ok(list(vec![sym("Fn"), self.generate_fn(func)?])),
ItemKind::Struct(data) => {
Ok(list(vec![sym("Struct"), self.generate_variant_data(data)]))
}
ItemKind::Enum(enum_def) => {
Ok(list(vec![sym("Enum"), self.generate_enum_def(enum_def)]))
}
ItemKind::Trait(trait_def) => {
Ok(list(vec![sym("Trait"), self.generate_trait_def(trait_def)?]))
}
ItemKind::Impl(impl_def) => {
Ok(list(vec![sym("Impl"), self.generate_impl_def(impl_def)?]))
}
ItemKind::Use(use_tree) => Ok(list(vec![sym("Use"), self.generate_use_tree(use_tree)])),
ItemKind::Static { mutability, ty, expr } => {
let mut fields = kwargs(vec![
kwarg("mutability", self.generate_mutability(*mutability)),
kwarg("ty", self.generate_ty(ty)?),
]);
if let Some(init_expr) = expr {
fields.extend(kwarg("expr", self.generate_expr(init_expr)?));
} else {
fields.extend(kwarg("expr", sym("nil")));
}
Ok(list(vec![sym("Static")].into_iter().chain(fields).collect()))
}
ItemKind::Const { ty, expr } => {
let mut fields = kwargs(vec![kwarg("ty", self.generate_ty(ty)?)]);
if let Some(init_expr) = expr {
fields.extend(kwarg("expr", self.generate_expr(init_expr)?));
} else {
fields.extend(kwarg("expr", sym("nil")));
}
Ok(list(vec![sym("Const")].into_iter().chain(fields).collect()))
}
ItemKind::TyAlias { generics, ty } => {
let mut fields = kwargs(vec![kwarg("generics", self.generate_generics(generics)?)]);
if let Some(alias_ty) = ty {
fields.extend(kwarg("ty", self.generate_ty(alias_ty)?));
} else {
fields.extend(kwarg("ty", sym("nil")));
}
Ok(list(vec![sym("TyAlias")].into_iter().chain(fields).collect()))
}
ItemKind::Mod { items } => {
let items_sexp = if let Some(item_list) = items {
list(
item_list
.iter()
.map(|item| self.generate_item(item))
.collect::<Result<Vec<_>>>()?,
)
} else {
sym("nil")
};
Ok(list(vec![sym("Mod"), kw("items"), items_sexp]))
}
ItemKind::MacroDef(macro_def) => {
let fields = kwargs(vec![
kwarg("macro-rules", sym(if macro_def.macro_rules { "true" } else { "false" })),
kwarg("body", self.generate_mac_args(¯o_def.body)?),
]);
Ok(list(vec![sym("MacroDef")].into_iter().chain(fields).collect()))
}
}
}
fn generate_fn(&self, func: &Fn) -> Result<SExp> {
let mut fields = kwargs(vec![
kwarg("defaultness", self.generate_defaultness(func.defaultness)),
kwarg("sig", self.generate_fn_sig(&func.sig)?),
kwarg("generics", self.generate_generics(&func.generics)?),
]);
if let Some(body) = &func.body {
fields.extend(kwarg("body", self.generate_block(body)?));
} else {
fields.extend(kwarg("body", sym("nil")));
}
Ok(typed_node("Fn", fields))
}
fn generate_defaultness(&self, defaultness: Defaultness) -> SExp {
match defaultness {
Defaultness::Default => sym("Default"),
Defaultness::Final => sym("Final"),
}
}
fn generate_fn_sig(&self, sig: &FnSig) -> Result<SExp> {
let fields = kwargs(vec![
kwarg("header", self.generate_fn_header(&sig.header)?),
kwarg("decl", self.generate_fn_decl(&sig.decl)?),
kwarg("span", self.generate_span(sig.span)),
]);
Ok(typed_node("FnSig", fields))
}
fn generate_fn_header(&self, header: &FnHeader) -> Result<SExp> {
let mut fields = kwargs(vec![
kwarg("safety", self.generate_safety(header.safety)),
kwarg("constness", self.generate_constness(header.constness)),
kwarg("ext", self.generate_extern(&header.ext)),
]);
if let Some(kind) = header.coroutine_kind {
fields.extend(kwarg("coroutine-kind", self.generate_coroutine_kind(kind)));
} else {
fields.extend(kwarg("coroutine-kind", sym("nil")));
}
Ok(typed_node("FnHeader", fields))
}
fn generate_safety(&self, safety: Safety) -> SExp {
match safety {
Safety::Safe => sym("Safe"),
Safety::Unsafe => sym("Unsafe"),
Safety::Default => sym("Default"),
}
}
fn generate_constness(&self, constness: Constness) -> SExp {
match constness {
Constness::Const => sym("Const"),
Constness::NotConst => sym("NotConst"),
}
}
fn generate_extern(&self, ext: &Extern) -> SExp {
match ext {
Extern::None => sym("None"),
Extern::Explicit(abi) => list(vec![sym("Explicit"), string(abi)]),
}
}
fn generate_coroutine_kind(&self, kind: CoroutineKind) -> SExp {
match kind {
CoroutineKind::Async => sym("Async"),
CoroutineKind::Gen => sym("Gen"),
}
}
fn generate_fn_decl(&self, decl: &FnDecl) -> Result<SExp> {
let fields = kwargs(vec![
kwarg("inputs", self.generate_params(&decl.inputs)?),
kwarg("output", self.generate_fn_ret_ty(&decl.output)?),
]);
Ok(typed_node("FnDecl", fields))
}
fn generate_params(&self, params: &[Param]) -> Result<SExp> {
let param_sexps: Result<Vec<SExp>> =
params.iter().map(|param| self.generate_param(param)).collect();
Ok(list(param_sexps?))
}
pub(crate) fn generate_param(&self, param: &Param) -> Result<SExp> {
let fields = kwargs(vec![
kwarg("attrs", self.generate_attr_vec(¶m.attrs)?),
kwarg("ty", self.generate_ty(¶m.ty)?),
kwarg("pat", self.generate_pat(¶m.pat)?),
kwarg("id", self.generate_node_id(param.id)),
kwarg("span", self.generate_span(param.span)),
kwarg("is-placeholder", sym(if param.is_placeholder { "true" } else { "false" })),
]);
Ok(typed_node("Param", fields))
}
fn generate_fn_ret_ty(&self, ret_ty: &FnRetTy) -> Result<SExp> {
match ret_ty {
FnRetTy::Default(span) => Ok(list(vec![sym("Default"), self.generate_span(*span)])),
FnRetTy::Ty(ty) => Ok(list(vec![sym("Ty"), self.generate_ty(ty)?])),
}
}
pub(crate) fn generate_ty(&self, ty: &Ty) -> Result<SExp> {
let mut fields = kwargs(vec![
kwarg("id", self.generate_node_id(ty.id)),
kwarg("kind", self.generate_ty_kind(&ty.kind)?),
kwarg("span", self.generate_span(ty.span)),
]);
if ty.tokens.is_some() {
fields.extend(kwarg("tokens", sym("nil")));
}
Ok(typed_node("Ty", fields))
}
fn generate_ty_kind(&self, kind: &TyKind) -> Result<SExp> {
match kind {
TyKind::Path(qself, path) => {
let qself_sexp = if qself.is_some() {
sym("TODO") } else {
sym("nil")
};
Ok(list(vec![sym("Path"), qself_sexp, self.generate_path(path)]))
}
TyKind::Ref { lifetime, mutability, ty } => {
let lifetime_sexp =
if let Some(lt) = lifetime { self.generate_lifetime(lt) } else { sym("nil") };
Ok(list(vec![
sym("Ref"),
kw("lifetime"),
lifetime_sexp,
kw("mutability"),
self.generate_mutability(*mutability),
kw("ty"),
self.generate_ty(ty)?,
]))
}
TyKind::Ptr { mutability, ty } => Ok(list(vec![
sym("Ptr"),
kw("mutability"),
self.generate_mutability(*mutability),
kw("ty"),
self.generate_ty(ty)?,
])),
TyKind::Array { ty, len } => Ok(list(vec![
sym("Array"),
kw("ty"),
self.generate_ty(ty)?,
kw("len"),
self.generate_expr(len)?,
])),
TyKind::Slice(ty) => Ok(list(vec![sym("Slice"), self.generate_ty(ty)?])),
TyKind::Tuple(tys) => {
let ty_sexps =
tys.iter().map(|ty| self.generate_ty(ty)).collect::<Result<Vec<_>>>()?;
Ok(list(vec![sym("Tuple")].into_iter().chain(ty_sexps).collect()))
}
TyKind::Never => Ok(sym("Never")),
TyKind::Infer => Ok(sym("Infer")),
TyKind::BareFn { safety, abi, inputs, output } => {
let mut fields =
vec![sym("BareFn"), kw("safety"), self.generate_safety(*safety), kw("abi")];
fields.push(if let Some(abi_str) = abi { string(abi_str) } else { sym("nil") });
fields.push(kw("inputs"));
let inputs_sexps: Vec<SExp> = inputs
.iter()
.map(|param| self.generate_bare_fn_param(param))
.collect::<Result<Vec<_>>>()?;
fields.push(list(inputs_sexps));
fields.push(kw("output"));
fields.push(self.generate_fn_ret_ty(output)?);
Ok(list(fields))
}
TyKind::ImplTrait(bounds) => {
let bounds_sexps: Result<Vec<SExp>> =
bounds.iter().map(|b| self.generate_generic_bound(b)).collect();
Ok(list(vec![sym("ImplTrait"), list(bounds_sexps?)]))
}
TyKind::TraitObject { bounds, syntax } => {
let bounds_sexps: Result<Vec<SExp>> =
bounds.iter().map(|b| self.generate_generic_bound(b)).collect();
Ok(list(vec![
sym("TraitObject"),
kw("bounds"),
list(bounds_sexps?),
kw("syntax"),
match syntax {
TraitObjectSyntax::Dyn => sym("Dyn"),
TraitObjectSyntax::None => sym("None"),
},
]))
}
TyKind::MacCall(mac) => {
Ok(list(vec![sym("MacCall"), kw("mac"), self.generate_mac_call(mac)?]))
}
TyKind::Paren(ty) => Ok(list(vec![sym("Paren"), self.generate_ty(ty)?])),
}
}
fn generate_bare_fn_param(&self, param: &BareFnParam) -> Result<SExp> {
Ok(typed_node(
"BareFnParam",
kwargs(vec![
kwarg(
"name",
if let Some(name) = ¶m.name {
self.generate_ident(name)
} else {
sym("nil")
},
),
kwarg("ty", self.generate_ty(¶m.ty)?),
]),
))
}
pub(crate) fn generate_pat(&self, pat: &Pat) -> Result<SExp> {
let mut fields = kwargs(vec![
kwarg("id", self.generate_node_id(pat.id)),
kwarg("kind", self.generate_pat_kind(&pat.kind)?),
kwarg("span", self.generate_span(pat.span)),
]);
if pat.tokens.is_some() {
fields.extend(kwarg("tokens", sym("nil")));
}
Ok(typed_node("Pat", fields))
}
fn generate_pat_kind(&self, kind: &PatKind) -> Result<SExp> {
match kind {
PatKind::Ident { binding_mode, ident, sub } => {
let mut fields = kwargs(vec![
kwarg("binding-mode", self.generate_binding_mode(*binding_mode)),
kwarg("ident", self.generate_ident(ident)),
]);
if let Some(sub_pat) = sub {
fields.extend(kwarg("sub", self.generate_pat(sub_pat)?));
} else {
fields.extend(kwarg("sub", sym("nil")));
}
Ok(typed_node("Ident", fields))
}
PatKind::Wild => Ok(sym("Wild")),
PatKind::Struct { path, fields } => {
let fields_sexp = list(
fields
.iter()
.map(|f| self.generate_pat_field(f))
.collect::<Result<Vec<_>>>()?,
);
Ok(list(vec![
sym("Struct"),
kw("path"),
self.generate_path(path),
kw("fields"),
fields_sexp,
]))
}
PatKind::TupleStruct { path, elems } => {
let elems_sexp =
list(elems.iter().map(|e| self.generate_pat(e)).collect::<Result<Vec<_>>>()?);
Ok(list(vec![
sym("TupleStruct"),
kw("path"),
self.generate_path(path),
kw("elems"),
elems_sexp,
]))
}
PatKind::Tuple(pats) => {
let pats_sexp =
list(pats.iter().map(|p| self.generate_pat(p)).collect::<Result<Vec<_>>>()?);
Ok(list(vec![sym("Tuple"), pats_sexp]))
}
PatKind::Slice(pats) => {
let pats_sexp =
list(pats.iter().map(|p| self.generate_pat(p)).collect::<Result<Vec<_>>>()?);
Ok(list(vec![sym("Slice"), pats_sexp]))
}
PatKind::Or(pats) => {
let pats_sexp =
list(pats.iter().map(|p| self.generate_pat(p)).collect::<Result<Vec<_>>>()?);
Ok(list(vec![sym("Or"), pats_sexp]))
}
PatKind::Ref { pat, mutability } => Ok(list(vec![
sym("Ref"),
kw("pat"),
self.generate_pat(pat)?,
kw("mutability"),
self.generate_mutability(*mutability),
])),
PatKind::Lit(expr) => Ok(list(vec![sym("Lit"), self.generate_expr(expr)?])),
PatKind::Box(pat) => Ok(list(vec![sym("Box"), kw("pat"), self.generate_pat(pat)?])),
PatKind::Path { qself, path } => Ok(list(vec![
sym("Path"),
kw("qself"),
match qself {
Some(q) => self.generate_qself(q),
None => sym("nil"),
},
kw("path"),
self.generate_path(path),
])),
PatKind::Range { start, end, limits } => {
let mut fields = vec![sym("Range")];
fields.push(kw("start"));
fields.push(match start {
Some(e) => self.generate_expr(e)?,
None => sym("nil"),
});
fields.push(kw("end"));
fields.push(match end {
Some(e) => self.generate_expr(e)?,
None => sym("nil"),
});
fields.push(kw("limits"));
fields.push(match limits {
RangeEnd::Included => sym("Included"),
RangeEnd::Excluded => sym("Excluded"),
});
Ok(list(fields))
}
PatKind::Rest => Ok(sym("Rest")),
PatKind::Paren(pat) => Ok(list(vec![sym("Paren"), kw("pat"), self.generate_pat(pat)?])),
PatKind::Type { pat, ty } => Ok(list(vec![
sym("Type"),
kw("pat"),
self.generate_pat(pat)?,
kw("ty"),
self.generate_ty(ty)?,
])),
PatKind::Const(const_block) => Ok(list(vec![
sym("Const"),
kw("id"),
num(const_block.id.0),
kw("value"),
self.generate_expr(&const_block.value)?,
])),
PatKind::MacCall(mac) => {
Ok(list(vec![sym("MacCall"), kw("mac"), self.generate_mac_call(mac)?]))
}
PatKind::Err => Ok(sym("Err")),
}
}
fn generate_pat_field(&self, field: &PatField) -> Result<SExp> {
Ok(typed_node(
"PatField",
kwargs(vec![
kwarg("attrs", self.generate_attr_vec(&field.attrs)?),
kwarg("ident", self.generate_ident(&field.ident)),
kwarg("pat", self.generate_pat(&field.pat)?),
kwarg("is-shorthand", sym(if field.is_shorthand { "true" } else { "false" })),
kwarg("span", self.generate_span(field.span)),
]),
))
}
fn generate_binding_mode(&self, mode: BindingMode) -> SExp {
match mode {
BindingMode::ByRef(mutability) => {
list(vec![sym("ByRef"), self.generate_mutability(mutability)])
}
BindingMode::ByValue(mutability) => {
list(vec![sym("ByValue"), self.generate_mutability(mutability)])
}
}
}
fn generate_mutability(&self, mutability: Mutability) -> SExp {
match mutability {
Mutability::Mut => sym("Mut"),
Mutability::Not => sym("Not"),
}
}
pub(crate) fn generate_lifetime(&self, lifetime: &Lifetime) -> SExp {
typed_node("Lifetime", kwargs(vec![kwarg("ident", self.generate_ident(&lifetime.ident))]))
}
fn generate_vis_restriction_kind(&self, kind: VisRestrictionKind) -> SExp {
match kind {
VisRestrictionKind::Crate => sym("Crate"),
VisRestrictionKind::Super => sym("Super"),
VisRestrictionKind::In => sym("In"),
}
}
pub fn generate_path(&self, path: &Path) -> SExp {
let mut fields = kwargs(vec![
kwarg("span", self.generate_span(path.span)),
kwarg("segments", self.generate_path_segments(&path.segments)),
]);
if path.tokens.is_some() {
fields.extend(kwarg("tokens", sym("nil")));
}
typed_node("Path", fields)
}
fn generate_qself(&self, _qself: &QSelf) -> SExp {
typed_node("QSelf", kwargs(vec![]))
}
fn generate_path_segments(&self, segments: &[PathSegment]) -> SExp {
let segment_sexps: Vec<SExp> =
segments.iter().map(|seg| self.generate_path_segment(seg)).collect();
list(segment_sexps)
}
fn generate_path_segment(&self, segment: &PathSegment) -> SExp {
let mut fields = kwargs(vec![
kwarg("ident", self.generate_ident(&segment.ident)),
kwarg("id", self.generate_node_id(segment.id)),
]);
if segment.args.is_some() {
fields.extend(kwarg("args", sym("TODO"))); } else {
fields.extend(kwarg("args", sym("nil")));
}
typed_node("PathSegment", fields)
}
fn generate_variant_data(&self, data: &VariantData) -> SExp {
match data {
VariantData::Struct { fields, recovered } => {
let fields_sexp = list(fields.iter().map(|f| self.generate_field_def(f)).collect());
typed_node(
"Struct",
kwargs(vec![
kwarg("fields", fields_sexp),
kwarg("recovered", sym(if *recovered { "true" } else { "false" })),
]),
)
}
VariantData::Tuple(fields) => {
let fields_sexp = list(fields.iter().map(|f| self.generate_field_def(f)).collect());
list(vec![sym("Tuple"), fields_sexp])
}
VariantData::Unit => sym("Unit"),
}
}
fn generate_enum_def(&self, enum_def: &EnumDef) -> SExp {
let variants_sexp =
list(enum_def.variants.iter().map(|v| self.generate_variant(v)).collect::<Vec<_>>());
typed_node("EnumDef", kwargs(vec![kwarg("variants", variants_sexp)]))
}
fn generate_variant(&self, variant: &Variant) -> SExp {
let mut fields = kwargs(vec![
kwarg("attrs", self.generate_attr_vec(&variant.attrs).unwrap_or_else(|_| sym("ERROR"))),
kwarg("id", self.generate_node_id(variant.id)),
kwarg("span", self.generate_span(variant.span)),
kwarg("vis", self.generate_visibility(&variant.vis)),
kwarg("ident", self.generate_ident(&variant.ident)),
kwarg("data", self.generate_variant_data(&variant.data)),
]);
if let Some(ref expr) = variant.disr_expr {
fields.extend(kwarg(
"disr-expr",
self.generate_expr(expr).unwrap_or_else(|_| sym("ERROR")),
));
} else {
fields.extend(kwarg("disr-expr", sym("nil")));
}
typed_node("Variant", fields)
}
fn generate_field_def(&self, field: &FieldDef) -> SExp {
let mut fields = kwargs(vec![
kwarg("attrs", self.generate_attr_vec(&field.attrs).unwrap_or_else(|_| sym("ERROR"))),
kwarg("id", self.generate_node_id(field.id)),
kwarg("span", self.generate_span(field.span)),
kwarg("vis", self.generate_visibility(&field.vis)),
]);
if let Some(ref ident) = field.ident {
fields.extend(kwarg("ident", self.generate_ident(ident)));
} else {
fields.extend(kwarg("ident", sym("nil")));
}
fields.extend(kwarg("ty", self.generate_ty(&field.ty).unwrap_or_else(|_| sym("ERROR"))));
typed_node("FieldDef", fields)
}
fn generate_trait_def(&self, trait_def: &TraitDef) -> Result<SExp> {
let bounds_result: Result<Vec<SExp>> =
trait_def.bounds.iter().map(|b| self.generate_generic_bound(b)).collect();
let bounds_sexp = list(bounds_result?);
let items_sexp = list(
trait_def
.items
.iter()
.map(|item| self.generate_assoc_item(item))
.collect::<Result<Vec<_>>>()?,
);
Ok(typed_node(
"TraitDef",
kwargs(vec![
kwarg("safety", self.generate_safety(trait_def.safety)),
kwarg("generics", self.generate_generics(&trait_def.generics)?),
kwarg("bounds", bounds_sexp),
kwarg("items", items_sexp),
]),
))
}
fn generate_impl_def(&self, impl_def: &ImplDef) -> Result<SExp> {
let mut fields = kwargs(vec![
kwarg("safety", self.generate_safety(impl_def.safety)),
kwarg("generics", self.generate_generics(&impl_def.generics)?),
]);
if let Some(ref trait_ref) = impl_def.of_trait {
fields.extend(kwarg("of-trait", self.generate_trait_ref(trait_ref)));
} else {
fields.extend(kwarg("of-trait", sym("nil")));
}
fields.extend(kwarg("self-ty", self.generate_ty(&impl_def.self_ty)?));
let items_sexp = list(
impl_def
.items
.iter()
.map(|item| self.generate_assoc_item(item))
.collect::<Result<Vec<_>>>()?,
);
fields.extend(kwarg("items", items_sexp));
Ok(typed_node("ImplDef", fields))
}
fn generate_assoc_item(&self, item: &AssocItem) -> Result<SExp> {
let kind_sexp = match &item.kind {
AssocItemKind::Fn(func) => list(vec![sym("Fn"), self.generate_fn(func)?]),
AssocItemKind::Type(ty_opt) => {
if let Some(ty) = &**ty_opt {
list(vec![sym("Type"), self.generate_ty(ty)?])
} else {
list(vec![sym("Type"), sym("nil")])
}
}
};
Ok(typed_node(
"AssocItem",
kwargs(vec![
kwarg("attrs", self.generate_attr_vec(&item.attrs)?),
kwarg("id", self.generate_node_id(item.id)),
kwarg("span", self.generate_span(item.span)),
kwarg("vis", self.generate_visibility(&item.vis)),
kwarg("ident", self.generate_ident(&item.ident)),
kwarg("kind", kind_sexp),
]),
))
}
fn generate_trait_ref(&self, trait_ref: &TraitRef) -> SExp {
typed_node("TraitRef", kwargs(vec![kwarg("path", self.generate_path(&trait_ref.path))]))
}
pub(crate) fn generate_generic_bound(&self, bound: &GenericBound) -> Result<SExp> {
Ok(match bound {
GenericBound::Trait(poly_trait_ref, modifier) => list(vec![
sym("Trait"),
self.generate_poly_trait_ref(poly_trait_ref),
self.generate_trait_bound_modifier(modifier),
]),
GenericBound::Outlives(lifetime) => {
list(vec![sym("Outlives"), self.generate_lifetime(lifetime)])
}
})
}
fn generate_poly_trait_ref(&self, poly_trait_ref: &PolyTraitRef) -> SExp {
typed_node(
"PolyTraitRef",
kwargs(vec![
kwarg("trait-ref", self.generate_trait_ref(&poly_trait_ref.trait_ref)),
kwarg("bound-lifetimes", empty_list()),
]),
)
}
fn generate_trait_bound_modifier(&self, modifier: &TraitBoundModifier) -> SExp {
match modifier {
TraitBoundModifier::None => sym("None"),
TraitBoundModifier::Maybe => sym("Maybe"),
TraitBoundModifier::Negative => sym("Negative"),
}
}
fn generate_use_tree(&self, use_tree: &UseTree) -> SExp {
let fields = kwargs(vec![
kwarg("prefix", self.generate_path(&use_tree.prefix)),
kwarg("kind", self.generate_use_tree_kind(&use_tree.kind)),
]);
typed_node("UseTree", fields)
}
fn generate_use_tree_kind(&self, kind: &UseTreeKind) -> SExp {
match kind {
UseTreeKind::Simple(rename) => {
let rename_sexp =
if let Some(ident) = rename { self.generate_ident(ident) } else { sym("nil") };
list(vec![sym("Simple"), rename_sexp])
}
UseTreeKind::Glob => sym("Glob"),
UseTreeKind::Nested(trees) => {
let trees_sexp =
list(trees.iter().map(|tree| self.generate_use_tree(tree)).collect());
list(vec![sym("Nested"), trees_sexp])
}
}
}
}