finally compiled codegen/typegen

This commit is contained in:
NikVolf 2016-04-13 09:57:35 +03:00
parent a9cceefaa4
commit 3f5382d52c
2 changed files with 68 additions and 8 deletions

View File

@ -34,6 +34,7 @@ use syntax::ext::build::AstBuilder;
use syntax::ptr::P;
use super::typegen;
use std::collections::HashMap;
pub struct Error;
@ -94,6 +95,7 @@ fn push_invoke_signature_aster(
builder: &aster::AstBuilder,
implement: &ImplItem,
signature: &MethodSig,
replacements: &HashMap<String, P<Ty>>,
push: &mut FnMut(Annotatable),
) -> Dispatch {
@ -108,17 +110,25 @@ fn push_invoke_signature_aster(
let mut arg_names = Vec::new();
let mut arg_tys = Vec::new();
let arg_name = format!("{}", field_name(builder, &inputs[skip-1]).name);
let arg_ty = inputs[skip-1].ty.clone();
let mut arg_ty = inputs[skip-1].ty.clone();
arg_ty = typegen::argument_replacement(builder, replacements, &arg_ty).unwrap_or(arg_ty);
let mut tree = builder.item()
.attr().word("derive(Serialize, Deserialize)")
.attr().word("allow(non_camel_case_types)")
.struct_(name_str.as_str())
.field(arg_name.as_str()).ty().build(arg_ty.clone());
.field(arg_name.as_str()).ty()
.build(arg_ty.clone());
arg_names.push(arg_name);
arg_tys.push(arg_ty.clone());
arg_tys.push(arg_ty);
for arg in inputs.iter().skip(skip) {
let arg_name = format!("{}", field_name(builder, &arg));
let arg_ty = arg.ty.clone();
let mut arg_ty = arg.ty.clone();
arg_ty = typegen::argument_replacement(builder, replacements, &arg_ty).unwrap_or(arg_ty);
tree = tree.field(arg_name.as_str()).ty().build(arg_ty.clone());
arg_names.push(arg_name);
arg_tys.push(arg_ty);
@ -339,8 +349,6 @@ fn implement_client_method_body(
{
let request = if dispatch.input_arg_names.len() > 0 {
let substitutes = typegen::match_unknown_tys(cx, builder, dispatch.input_arg_tys
let arg_name = dispatch.input_arg_names[0].as_str();
let arg_ty = builder
.ty().ref_()
@ -645,7 +653,7 @@ fn implement_interface(
let mut dispatch_table = Vec::new();
for impl_item in impl_items {
if let ImplItemKind::Method(ref signature, _) = impl_item.node {
dispatch_table.push(push_invoke_signature_aster(builder, &impl_item, signature, push));
dispatch_table.push(push_invoke_signature_aster(builder, &impl_item, signature, &HashMap::<String, P<Ty>>::new(), push));
}
}

View File

@ -27,6 +27,7 @@ use syntax::ast::{
Ty,
TyKind,
Path,
DUMMY_NODE_ID,
};
use syntax::ast;
@ -56,7 +57,7 @@ fn is_new_entry(builder: &aster::AstBuilder, path: &Path) -> Option<String> {
};
if known { None }
else { Some(path_str(path)) }
else { Some(::syntax::print::pprust::path_to_string(path)) }
}
fn path_str(path: &Path) -> String {
@ -67,6 +68,57 @@ fn path_str(path: &Path) -> String {
res
}
pub fn argument_replacement(
builder: &aster::AstBuilder,
replacements: &HashMap<String, P<Ty>>,
ty: &P<Ty>,
) -> Option<P<Ty>> {
match ty.node {
TyKind::Vec(ref nested_ty) => {
argument_replacement(builder, replacements, nested_ty).and_then(|replaced_with| {
let mut inplace_ty = nested_ty.deref().clone();
inplace_ty.node = TyKind::Vec(replaced_with);
inplace_ty.id = DUMMY_NODE_ID;
Some(P(inplace_ty))
})
},
TyKind::FixedLengthVec(ref nested_ty, ref len_expr) => {
argument_replacement(builder, replacements, nested_ty).and_then(|replaced_with| {
let mut inplace_ty = nested_ty.deref().clone();
inplace_ty.node = TyKind::FixedLengthVec(replaced_with, len_expr.clone());
inplace_ty.id = DUMMY_NODE_ID;
Some(P(inplace_ty))
})
},
TyKind::Path(_, ref path) => {
if path.segments.len() > 0 && path.segments[0].identifier.name.as_str() == "Option" ||
path.segments[0].identifier.name.as_str() == "Result" {
let nested_ty = &path.segments[0].parameters.types()[0];
argument_replacement(builder, replacements, nested_ty).and_then(|replaced_with| {
let mut inplace_path = path.clone();
match inplace_path.segments[0].parameters {
::syntax::ast::PathParameters::AngleBracketed(ref mut data) => {
data.types = data.types.map(|_| replaced_with.clone());
},
_ => {}
}
let mut inplace_ty = nested_ty.deref().deref().clone();
inplace_ty.node = TyKind::Path(None, inplace_path);
inplace_ty.id = DUMMY_NODE_ID;
Some(P(inplace_ty))
})
}
else {
replacements.get(&::syntax::print::pprust::path_to_string(path)).and_then(|replaced_with| {
Some(replaced_with.clone())
})
}
}
_ => { None }
}
}
pub fn push_bin_box(
cx: &ExtCtxt,
builder: &aster::AstBuilder,