Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 7 additions & 24 deletions sailfish-compiler/src/compiler.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use quote::ToTokens;
use std::fs;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use syn::Block;
Expand All @@ -12,7 +11,7 @@ use crate::optimizer::Optimizer;
use crate::parser::Parser;
use crate::resolver::Resolver;
use crate::translator::{TranslatedSource, Translator};
use crate::util::{copy_filetimes, read_to_string, rustfmt_block};
use crate::util::{read_to_string, rustfmt_block};

#[derive(Default)]
pub struct Compiler {
Expand Down Expand Up @@ -45,8 +44,7 @@ impl Compiler {
pub fn compile_file(
&self,
input: &Path,
output: &Path,
) -> Result<CompilationReport, Error> {
) -> Result<(CompilationReport, String), Error> {
// TODO: introduce cache system

let input = input
Expand All @@ -61,9 +59,8 @@ impl Compiler {
let analyzer = Analyzer::new();
let optimizer = Optimizer::new().rm_whitespace(self.config.rm_whitespace);

let compile_file = |input: &Path,
output: &Path|
-> Result<CompilationReport, Error> {
let compile_file = |input: &Path,|
-> Result<(CompilationReport, String), Error> {
let mut tsource = self.translate_file_contents(input)?;
let mut report = CompilationReport { deps: Vec::new() };

Expand All @@ -73,27 +70,13 @@ impl Compiler {
analyzer.analyze(&mut tsource.ast)?;
optimizer.optimize(&mut tsource.ast);

if let Some(parent) = output.parent() {
fs::create_dir_all(parent)
.chain_err(|| format!("Failed to save artifacts in {:?}", parent))?;
}

let string = tsource.ast.into_token_stream().to_string();
let ret = format!("{}", rustfmt_block(&*string).unwrap_or(string));

let mut f = fs::File::create(output)
.chain_err(|| format!("Failed to create artifact: {:?}", output))?;
writeln!(f, "{}", rustfmt_block(&*string).unwrap_or(string))
.chain_err(|| format!("Failed to write artifact into {:?}", output))?;
drop(f);

// FIXME: This is a silly hack to prevent output file from being tracking by
// cargo. Another better solution should be considered.
let _ = copy_filetimes(input, output);

Ok(report)
Ok((report, ret))
};

compile_file(&*input, &*output)
compile_file(&*input)
.chain_err(|| "Failed to compile template.")
.map_err(|mut e| {
e.source = fs::read_to_string(&*input).ok();
Expand Down
41 changes: 5 additions & 36 deletions sailfish-compiler/src/procmacro.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use proc_macro2::{Span, TokenStream};
use quote::quote;
use std::collections::hash_map::DefaultHasher;
use std::env;
use std::hash::{Hash, Hasher};
use std::path::{Path, PathBuf};
use syn::parse::{ParseStream, Parser, Result as ParseResult};
use syn::punctuated::Punctuated;
Expand Down Expand Up @@ -103,33 +101,10 @@ fn resolve_template_file(path: &str, template_dirs: &[PathBuf]) -> Option<PathBu
None
}

fn filename_hash(path: &Path) -> String {
use std::fmt::Write;

let mut path_with_hash = String::with_capacity(16);

if let Some(n) = path.file_name() {
let mut filename = &*n.to_string_lossy();
if let Some(p) = filename.find('.') {
filename = &filename[..p];
}
path_with_hash.push_str(filename);
path_with_hash.push('-');
}

let mut hasher = DefaultHasher::new();
path.hash(&mut hasher);
let hash = hasher.finish();
let _ = write!(path_with_hash, "{:016x}", hash);

path_with_hash
}

fn compile(
input_file: &Path,
output_file: &Path,
config: Config,
) -> Result<CompilationReport, Error> {
) -> Result<(CompilationReport, String), Error> {
struct FallbackScope {}

impl FallbackScope {
Expand All @@ -153,7 +128,7 @@ fn compile(
let compiler = Compiler::with_config(config);

let _scope = FallbackScope::new();
compiler.compile_file(input_file, &*output_file)
compiler.compile_file(input_file)
}

fn derive_template_impl(tokens: TokenStream) -> Result<TokenStream, syn::Error> {
Expand Down Expand Up @@ -207,20 +182,13 @@ fn derive_template_impl(tokens: TokenStream) -> Result<TokenStream, syn::Error>
)?
};

let mut output_file = PathBuf::from(env!("OUT_DIR"));
output_file.push("templates");
output_file.push(filename_hash(&*input_file));

merge_config_options(&mut config, &all_options);
let report = compile(&*input_file, &*output_file, config)
let (report, output_str) = compile(&*input_file, config)
.map_err(|e| syn::Error::new(Span::call_site(), e))?;

let input_file_string = input_file
.to_str()
.unwrap_or_else(|| panic!("Non UTF-8 file name: {:?}", input_file));
let output_file_string = output_file
.to_str()
.unwrap_or_else(|| panic!("Non UTF-8 file name: {:?}", output_file));

let mut include_bytes_seq = quote! { include_bytes!(#input_file_string); };
for dep in report.deps {
Expand Down Expand Up @@ -253,6 +221,7 @@ fn derive_template_impl(tokens: TokenStream) -> Result<TokenStream, syn::Error>
};

let (impl_generics, ty_generics, where_clause) = strct.generics.split_for_impl();
let out_tokens: syn::Expr = syn::parse_str(&output_str).expect("Must be an expr; qed");

// render_once method always results in the same code.
// This method can be implemented in `sailfish` crate, but I found that performance
Expand All @@ -275,7 +244,7 @@ fn derive_template_impl(tokens: TokenStream) -> Result<TokenStream, syn::Error>

use sailfish::runtime as __sf_rt;
let #name { #field_names } = self;
include!(#output_file_string);
#out_tokens;

Ok(())
}
Expand Down
9 changes: 0 additions & 9 deletions sailfish-compiler/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use filetime::FileTime;
use std::fs;
use std::io::{self, Write};
use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -77,11 +76,3 @@ pub fn rustfmt_block(source: &str) -> io::Result<String> {
))
}
}

pub fn copy_filetimes(input: &Path, output: &Path) -> io::Result<()> {
let mtime = fs::metadata(input)
.and_then(|metadata| metadata.modified())
.map_or(FileTime::zero(), |time| FileTime::from_system_time(time));

filetime::set_file_times(output, mtime, mtime)
}
3 changes: 0 additions & 3 deletions sailfish-tests/integration-tests/tests/template_once.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
#[macro_use]
extern crate sailfish_macros;

use integration_tests::assert_string_eq;
use sailfish::runtime::RenderResult;
use sailfish::TemplateOnce;
Expand Down