1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
extern crate reproto_ast as ast;
extern crate reproto_core as core;
extern crate reproto_manifest as manifest;
use core::{ContextItem, RelativePath, Resolver, RpPackage, RpVersionedPackage, Source};
use manifest::Lang;
use std::any::Any;
use std::cell::RefCell;
use std::rc::Rc;
use std::str;
pub enum Input<'input> {
File(ast::File<'input>, Option<RpVersionedPackage>),
Source(Source, Option<RpVersionedPackage>),
}
pub struct SimpleCompile<'a, 'input> {
pub input: Input<'input>,
pub package_prefix: Option<RpPackage>,
pub resolver: Option<&'a mut Resolver>,
pub items: Option<Rc<RefCell<Vec<ContextItem>>>>,
}
impl<'a, 'input> SimpleCompile<'a, 'input> {
pub fn new(input: Input<'input>) -> SimpleCompile<'a, 'input> {
Self {
input: input,
package_prefix: None,
resolver: None,
items: None,
}
}
pub fn package_prefix(self, package: RpPackage) -> Self {
Self {
package_prefix: Some(package),
..self
}
}
pub fn resolver(self, resolver: &'a mut Resolver) -> Self {
Self {
resolver: Some(resolver),
..self
}
}
pub fn with_items(self, items: Rc<RefCell<Vec<ContextItem>>>) -> Self {
Self {
items: Some(items),
..self
}
}
}
pub fn simple_compile<'a, 'input, O>(
mut out: O,
config: SimpleCompile<'a, 'input>,
modules: Vec<Box<Any>>,
lang: &Lang,
) -> core::errors::Result<()>
where
O: FnMut(&RelativePath, &str) -> core::errors::Result<()>,
{
let SimpleCompile {
input,
package_prefix,
resolver,
items,
} = config;
let mut empty_resolver = core::EmptyResolver;
let resolver = resolver.unwrap_or_else(|| &mut empty_resolver);
let capturing = core::CapturingFilesystem::new();
let ctx = core::Context::new(capturing.filesystem());
let ctx = if let Some(items) = items {
ctx.with_items(items)
} else {
ctx
};
let ctx = Rc::new(ctx);
let mut env = lang.into_env(ctx.clone(), package_prefix.clone(), resolver);
match input {
Input::File(file, package) => {
env.import_file(file, package)?;
}
Input::Source(source, package) => {
env.import_source(source, package)?;
}
}
let mut manifest = manifest::Manifest::default();
manifest.lang = Some(lang.copy());
manifest.modules = modules;
manifest.package_prefix = package_prefix;
lang.compile(ctx, env, manifest)?;
let borrowed = capturing.files().try_borrow()?;
let mut it = borrowed.iter().peekable();
while let Some((path, content)) = it.next() {
let content = str::from_utf8(content)?;
out(path, content)?;
}
Ok(())
}