Resolve child template path inside resolver
This commit is contained in:
parent
64ded9616a
commit
7d77b755c6
|
@ -27,7 +27,7 @@ quote = { version = "1.0.6", default-features = false }
|
|||
[dependencies.syn]
|
||||
version = "1.0.21"
|
||||
default-features = false
|
||||
features = ["parsing", "full", "visit-mut", "printing", "clone-impls"]
|
||||
features = ["parsing", "full", "visit-mut", "printing", "clone-impls", "extra-traits"]
|
||||
|
||||
[dependencies.proc-macro2]
|
||||
version = "1.0.10"
|
||||
|
|
|
@ -40,15 +40,8 @@ impl Compiler {
|
|||
|
||||
let input = input.canonicalize()?;
|
||||
|
||||
let include_handler = Arc::new(|arg: &str| -> Result<_, Error> {
|
||||
let input_file = if arg.starts_with("/") {
|
||||
// absolute imclude
|
||||
template_dir.join(arg)
|
||||
} else {
|
||||
// relative include
|
||||
input.parent().unwrap().join(arg)
|
||||
};
|
||||
Ok(self.translate_file_contents(&*input_file)?.ast)
|
||||
let include_handler = Arc::new(|child_file: &Path| -> Result<_, Error> {
|
||||
Ok(self.translate_file_contents(&*child_file)?.ast)
|
||||
});
|
||||
|
||||
let resolver = Resolver::new().include_handler(include_handler);
|
||||
|
@ -57,7 +50,7 @@ impl Compiler {
|
|||
let compile_file = |input: &Path, output: &Path| -> Result<(), Error> {
|
||||
let mut tsource = self.translate_file_contents(input)?;
|
||||
|
||||
resolver.resolve(&mut tsource.ast)?;
|
||||
resolver.resolve(template_dir, &*input, &mut tsource.ast)?;
|
||||
optimizer.optimize(&mut tsource.ast);
|
||||
|
||||
if let Some(parent) = output.parent() {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
use syn::visit_mut::VisitMut;
|
||||
use syn::{Block, Expr, ExprBlock, LitStr};
|
||||
|
@ -28,13 +29,15 @@ fn empty_block() -> Block {
|
|||
}
|
||||
}
|
||||
|
||||
struct ResolverImpl<'h> {
|
||||
struct ResolverImpl<'s, 'h> {
|
||||
template_dir: &'s Path,
|
||||
path_stack: Vec<PathBuf>,
|
||||
deps: Vec<String>,
|
||||
error: Option<Error>,
|
||||
include_handler: Arc<dyn 'h + Fn(&str) -> Result<Block, Error>>,
|
||||
include_handler: Arc<dyn 'h + Fn(&Path) -> Result<Block, Error>>,
|
||||
}
|
||||
|
||||
impl<'h> VisitMut for ResolverImpl<'h> {
|
||||
impl<'s, 'h> VisitMut for ResolverImpl<'s, 'h> {
|
||||
fn visit_expr_mut(&mut self, i: &mut Expr) {
|
||||
return_if_some!(self.error);
|
||||
let em = matches_or_else!(*i, Expr::Macro(ref em), em, {
|
||||
|
@ -60,8 +63,17 @@ impl<'h> VisitMut for ResolverImpl<'h> {
|
|||
}
|
||||
};
|
||||
|
||||
// resolve the template file path
|
||||
let input_file = if arg.starts_with('/') {
|
||||
// absolute imclude
|
||||
self.template_dir.join(&arg[1..])
|
||||
} else {
|
||||
// relative include
|
||||
self.path_stack.last().unwrap().parent().unwrap().join(arg.clone())
|
||||
};
|
||||
|
||||
// parse and translate the child template
|
||||
let mut blk = match (*self.include_handler)(&arg) {
|
||||
let mut blk = match (*self.include_handler)(&*input_file) {
|
||||
Ok(blk) => blk,
|
||||
Err(mut e) => {
|
||||
e.chains
|
||||
|
@ -71,6 +83,7 @@ impl<'h> VisitMut for ResolverImpl<'h> {
|
|||
}
|
||||
};
|
||||
|
||||
self.path_stack.push(input_file);
|
||||
self.deps.push(arg);
|
||||
syn::visit_mut::visit_block_mut(self, &mut blk);
|
||||
|
||||
|
@ -84,7 +97,7 @@ impl<'h> VisitMut for ResolverImpl<'h> {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct Resolver<'h> {
|
||||
include_handler: Arc<dyn 'h + Fn(&str) -> Result<Block, Error>>,
|
||||
include_handler: Arc<dyn 'h + Fn(&Path) -> Result<Block, Error>>,
|
||||
}
|
||||
|
||||
impl<'h> Resolver<'h> {
|
||||
|
@ -101,7 +114,7 @@ impl<'h> Resolver<'h> {
|
|||
#[inline]
|
||||
pub fn include_handler(
|
||||
self,
|
||||
new: Arc<dyn 'h + Fn(&str) -> Result<Block, Error>>,
|
||||
new: Arc<dyn 'h + Fn(&Path) -> Result<Block, Error>>,
|
||||
) -> Resolver<'h> {
|
||||
Self {
|
||||
include_handler: new,
|
||||
|
@ -109,12 +122,20 @@ impl<'h> Resolver<'h> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn resolve(&self, ast: &mut Block) -> Result<(), Error> {
|
||||
ResolverImpl {
|
||||
pub fn resolve(&self, template_dir: &Path, input_file: &Path, ast: &mut Block) -> Result<(), Error> {
|
||||
let mut child = ResolverImpl {
|
||||
template_dir: template_dir,
|
||||
path_stack: vec![input_file.to_owned()],
|
||||
deps: Vec::new(),
|
||||
error: None,
|
||||
include_handler: Arc::clone(&self.include_handler)
|
||||
}.visit_block_mut(ast);
|
||||
Ok(())
|
||||
};
|
||||
child.visit_block_mut(ast);
|
||||
|
||||
if let Some(e) = child.error {
|
||||
Err(e)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue