feat: compile deps

This commit is contained in:
rvcas
2022-12-20 15:32:37 -05:00
committed by Lucas
parent b06bf610b7
commit e34cbc8e7e
11 changed files with 112 additions and 214 deletions

View File

@@ -19,7 +19,8 @@ use aiken_lang::{
uplc::CodeGenerator,
IdGenerator,
};
use deps::UseManifest;
use config::PackageName;
use deps::{manifest::Package, UseManifest};
use miette::NamedSource;
use options::{CodeGenMode, Options};
use pallas::{
@@ -61,6 +62,7 @@ where
{
config: Config,
defined_modules: HashMap<String, PathBuf>,
checked_modules: CheckedModules,
id_gen: IdGenerator,
module_types: HashMap<String, TypeInfo>,
root: PathBuf,
@@ -85,6 +87,7 @@ where
Ok(Project {
config,
checked_modules: CheckedModules::default(),
defined_modules: HashMap::new(),
id_gen,
module_types,
@@ -110,19 +113,29 @@ where
name: self.config.name.to_string(),
version: self.config.version.clone(),
});
self.read_source_files()?;
let destination = destination.unwrap_or_else(|| self.root.join("doc"));
let mut parsed_modules = self.parse_sources()?;
let mut parsed_modules = self.parse_sources(self.config.name.clone())?;
for (_, module) in parsed_modules.iter_mut() {
module.attach_doc_and_module_comments();
}
let checked_modules = self.type_check(parsed_modules)?;
self.type_check(parsed_modules)?;
self.event_listener.handle_event(Event::GeneratingDocFiles {
output_path: destination.clone(),
});
let doc_files =
docs::generate_all(&self.root, &self.config, checked_modules.values().collect());
let doc_files = docs::generate_all(
&self.root,
&self.config,
self.checked_modules.values().collect(),
);
for file in doc_files {
let path = destination.join(file.path);
fs::create_dir_all(path.parent().unwrap())?;
@@ -153,14 +166,6 @@ where
}
pub fn compile(&mut self, options: Options) -> Result<(), Error> {
let manifest = deps::download(
&self.event_listener,
None,
UseManifest::Yes,
&self.root,
&self.config,
)?;
self.event_listener
.handle_event(Event::StartingCompilation {
root: self.root.clone(),
@@ -168,31 +173,41 @@ where
version: self.config.version.clone(),
});
self.compile_deps()?;
self.read_source_files()?;
let parsed_modules = self.parse_sources()?;
let mut checked_modules = self.type_check(parsed_modules)?;
let validators = self.validate_validators(&mut checked_modules)?;
let parsed_modules = self.parse_sources(self.config.name.clone())?;
self.type_check(parsed_modules)?;
let validators = self.validate_validators()?;
match options.code_gen_mode {
CodeGenMode::Build(uplc_dump) => {
self.event_listener.handle_event(Event::GeneratingUPLC {
output_path: self.output_path(),
});
let programs = self.code_gen(validators, &checked_modules)?;
let programs = self.code_gen(validators)?;
self.write_build_outputs(programs, uplc_dump)?;
Ok(())
}
CodeGenMode::Test {
match_tests,
verbose,
} => {
let tests = self.collect_scripts(&checked_modules, verbose, |def| {
matches!(def, Definition::Test(..))
})?;
let tests =
self.collect_scripts(verbose, |def| matches!(def, Definition::Test(..)))?;
if !tests.is_empty() {
self.event_listener.handle_event(Event::RunningTests);
}
let results = self.eval_scripts(tests, match_tests);
let errors: Vec<Error> = results
.iter()
.filter_map(|e| {
@@ -212,6 +227,7 @@ where
self.event_listener
.handle_event(Event::FinishedTests { tests: results });
if !errors.is_empty() {
Err(Error::List(errors))
} else {
@@ -222,6 +238,26 @@ where
}
}
fn compile_deps(&mut self) -> Result<(), Error> {
let manifest = deps::download(
&self.event_listener,
None,
UseManifest::Yes,
&self.root,
&self.config,
)?;
for package in manifest.packages {
self.read_package_source_files(&package)?;
let parsed_modules = self.parse_sources(package.name)?;
self.type_check(parsed_modules)?;
}
Ok(())
}
fn read_source_files(&mut self) -> Result<(), Error> {
let lib = self.root.join("lib");
let validators = self.root.join("validators");
@@ -232,7 +268,18 @@ where
Ok(())
}
fn parse_sources(&mut self) -> Result<ParsedModules, Error> {
fn read_package_source_files(&mut self, package: &Package) -> Result<(), Error> {
let lib = self
.root
.join(paths::build_deps_package(&package.name))
.join("lib");
self.aiken_files(&lib, ModuleKind::Lib)?;
Ok(())
}
fn parse_sources(&mut self, package_name: PackageName) -> Result<ParsedModules, Error> {
self.event_listener.handle_event(Event::ParsingProjectFiles);
let mut errors = Vec::new();
@@ -257,7 +304,7 @@ where
name,
path,
extra,
package: self.config.name.to_string(),
package: package_name.to_string(),
};
if let Some(first) = self
@@ -293,10 +340,9 @@ where
}
}
fn type_check(&mut self, mut parsed_modules: ParsedModules) -> Result<CheckedModules, Error> {
fn type_check(&mut self, mut parsed_modules: ParsedModules) -> Result<(), Error> {
self.event_listener.handle_event(Event::TypeChecking);
let processing_sequence = parsed_modules.sequence()?;
let mut modules = HashMap::with_capacity(parsed_modules.len() + 1);
for name in processing_sequence {
if let Some(ParsedModule {
@@ -305,8 +351,7 @@ where
code,
kind,
extra,
// TODO: come back and figure out where to use this
package: _package,
package,
ast,
}) = parsed_modules.remove(&name)
{
@@ -339,7 +384,7 @@ where
self.module_types
.insert(name.clone(), ast.type_info.clone());
modules.insert(
self.checked_modules.insert(
name.clone(),
CheckedModule {
kind,
@@ -347,25 +392,22 @@ where
name,
code,
ast,
package,
input_path: path,
},
);
}
}
Ok(modules.into())
Ok(())
}
fn validate_validators(
&self,
checked_modules: &mut CheckedModules,
) -> Result<Vec<(PathBuf, String, TypedFunction)>, Error> {
fn validate_validators(&self) -> Result<Vec<(PathBuf, String, TypedFunction)>, Error> {
let mut errors = Vec::new();
let mut validators = Vec::new();
let mut indices_to_remove = Vec::new();
for module in checked_modules.validators() {
for (index, def) in module.ast.definitions().enumerate() {
for module in self.checked_modules.validators() {
for def in module.ast.definitions() {
if let Definition::Fn(func_def) = def {
if VALIDATOR_NAMES.contains(&func_def.name.as_str()) {
// validators must return a Bool
@@ -418,14 +460,9 @@ where
module.name.clone(),
func_def.clone(),
));
indices_to_remove.push(index);
}
}
}
for index in indices_to_remove.drain(0..) {
module.ast.definitions.remove(index);
}
}
if errors.is_empty() {
@@ -438,7 +475,6 @@ where
fn code_gen(
&mut self,
validators: Vec<(PathBuf, String, TypedFunction)>,
checked_modules: &CheckedModules,
) -> Result<Vec<Script>, Error> {
let mut programs = Vec::new();
let mut functions = HashMap::new();
@@ -457,7 +493,7 @@ where
&option_data_type,
);
for module in checked_modules.values() {
for module in self.checked_modules.values() {
for def in module.ast.definitions() {
match def {
Definition::Fn(func) => {
@@ -529,7 +565,6 @@ where
// TODO: revisit ownership and lifetimes of data in this function
fn collect_scripts(
&mut self,
checked_modules: &CheckedModules,
verbose: bool,
should_collect: fn(&TypedDefinition) -> bool,
) -> Result<Vec<Script>, Error> {
@@ -550,10 +585,13 @@ where
&option_data_type,
);
// let mut indices_to_remove = Vec::new();
let mut scripts = Vec::new();
for module in checked_modules.values() {
for module in self
.checked_modules
.values()
.filter(|checked| checked.package == self.config.name.to_string())
{
for (_index, def) in module.ast.definitions().enumerate() {
match def {
Definition::Fn(func) => {
@@ -595,10 +633,6 @@ where
}
}
}
// for index in indices_to_remove.drain(0..) {
// module.ast.definitions.remove(index);
// }
}
for (input_path, module_name, func_def) in scripts {

View File

@@ -219,11 +219,12 @@ pub struct CheckedModule {
pub code: String,
pub input_path: PathBuf,
pub kind: ModuleKind,
pub package: String,
pub ast: TypedModule,
pub extra: ModuleExtra,
}
#[derive(Debug, Clone)]
#[derive(Default, Debug, Clone)]
pub struct CheckedModules(HashMap<String, CheckedModule>);
impl From<HashMap<String, CheckedModule>> for CheckedModules {
@@ -239,10 +240,8 @@ impl From<CheckedModules> for HashMap<String, CheckedModule> {
}
impl CheckedModules {
pub fn validators(&mut self) -> impl Iterator<Item = &mut CheckedModule> {
self.0
.values_mut()
.filter(|module| module.kind.is_validator())
pub fn validators(&self) -> impl Iterator<Item = &CheckedModule> {
self.0.values().filter(|module| module.kind.is_validator())
}
pub fn into_validators(self) -> impl Iterator<Item = CheckedModule> {