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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
extern crate reproto_ast as ast;
extern crate reproto_core as core;
extern crate reproto_manifest as manifest;
use core::{ContextItem, Object, Resolver, RpPackage, RpVersionedPackage};
use manifest::Lang;
use std::any::Any;
use std::cell::RefCell;
use std::fmt;
use std::rc::Rc;
use std::str;
pub enum Input<'input> {
File(ast::File<'input>, Option<RpVersionedPackage>),
Object(Box<Object>, Option<RpVersionedPackage>),
}
pub struct SimpleCompile<'input> {
pub input: Input<'input>,
pub package_prefix: Option<RpPackage>,
pub resolver: Option<Box<Resolver>>,
pub errors: Option<Rc<RefCell<Vec<ContextItem>>>>,
}
impl<'input> SimpleCompile<'input> {
pub fn new(input: Input<'input>) -> SimpleCompile {
Self {
input: input,
package_prefix: None,
resolver: None,
errors: None,
}
}
pub fn package_prefix(self, package: RpPackage) -> Self {
Self {
package_prefix: Some(package),
..self
}
}
pub fn resolver(self, resolver: Box<Resolver>) -> Self {
Self {
resolver: Some(resolver),
..self
}
}
pub fn with_errors(self, errors: Rc<RefCell<Vec<ContextItem>>>) -> Self {
Self {
errors: Some(errors),
..self
}
}
}
pub fn simple_compile(
out: &mut fmt::Write,
config: SimpleCompile,
modules: Vec<Box<Any>>,
lang: &Lang,
) -> core::errors::Result<()> {
let SimpleCompile {
input,
package_prefix,
resolver,
errors,
} = config;
let resolver = resolver.unwrap_or_else(|| Box::new(core::EmptyResolver));
let capturing = core::CapturingFilesystem::new();
let ctx = core::Context::new(capturing.filesystem());
let ctx = if let Some(errors) = errors {
ctx.with_errors(errors)
} 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::Object(object, package) => {
env.import_object(object.as_ref(), package)?;
}
}
let preamble = manifest::ManifestPreamble::new(Some(manifest::Language::Java), None);
let mut manifest = manifest::read_manifest(lang, preamble)?;
manifest.modules = modules;
manifest.package_prefix = package_prefix;
lang.compile(ctx, env, manifest)?;
let borrowed = capturing.files().try_borrow()?;
let comment = format!(
" {} file(s) generated by https://github.com/reproto",
borrowed.len()
);
if let Some(comment) = lang.comment(comment.as_str()) {
writeln!(out, "{}", comment.as_str())?;
writeln!(out, "")?;
}
let mut it = borrowed.iter().peekable();
while let Some((path, content)) = it.next() {
if let Some(comment) = lang.comment(format!(" File: {}", path.display()).as_str()) {
writeln!(out, "{}", comment)?;
writeln!(out, "")?;
}
out.write_str(str::from_utf8(content)?)?;
if it.peek().is_some() {
writeln!(out, "")?;
}
}
Ok(())
}