From 9986bc6bfd6d7f67ad94e325b6a141ec989f6673 Mon Sep 17 00:00:00 2001 From: KtorZ Date: Fri, 15 Mar 2024 00:05:37 +0100 Subject: [PATCH] Remove duplication between docs & compile And move some logic out of project/lib to be near the CheckedModule instead. The project API is already quite heavy and long, so making it more lightweight is generally what we want to tend to. --- crates/aiken-project/src/lib.rs | 99 +++++++----------------------- crates/aiken-project/src/module.rs | 80 +++++++++++++++++++++++- 2 files changed, 100 insertions(+), 79 deletions(-) diff --git a/crates/aiken-project/src/lib.rs b/crates/aiken-project/src/lib.rs index cea3b478..e0b8f657 100644 --- a/crates/aiken-project/src/lib.rs +++ b/crates/aiken-project/src/lib.rs @@ -194,15 +194,11 @@ where self.read_source_files()?; - let destination = destination.unwrap_or_else(|| self.root.join("docs")); - let mut modules = self.parse_sources(self.config.name.clone())?; - let our_modules: BTreeSet = modules.keys().cloned().collect(); + self.type_check(&mut modules, Tracing::silent(), false)?; - self.with_dependencies(&mut modules)?; - - self.type_check(&our_modules, modules, Tracing::silent(), false)?; + let destination = destination.unwrap_or_else(|| self.root.join("docs")); self.event_listener.handle_event(Event::GeneratingDocFiles { output_path: destination.clone(), @@ -296,11 +292,7 @@ where let mut modules = self.parse_sources(self.config.name.clone())?; - let our_modules: BTreeSet = modules.keys().cloned().collect(); - - self.with_dependencies(&mut modules)?; - - self.type_check(&our_modules, modules, options.tracing, true)?; + self.type_check(&mut modules, options.tracing, true)?; match options.code_gen_mode { CodeGenMode::Build(uplc_dump) => { @@ -684,78 +676,33 @@ where fn type_check( &mut self, - our_modules: &BTreeSet, - mut all_modules: ParsedModules, + modules: &mut ParsedModules, tracing: Tracing, validate_module_name: bool, - ) -> Result<(), Error> { - let processing_sequence = all_modules.sequence(our_modules)?; + ) -> Result<(), Vec> { + let our_modules: BTreeSet = modules.keys().cloned().collect(); - for name in processing_sequence { - if let Some(ParsedModule { - name, - path, - code, - kind, - extra, - package, - ast, - }) = all_modules.remove(&name) - { - let mut type_warnings = Vec::new(); + self.with_dependencies(modules)?; - let ast = ast - .infer( - &self.id_gen, - kind, - &self.config.name.to_string(), - &self.module_types, - tracing, - &mut type_warnings, - ) - .map_err(|error| Error::Type { - path: path.clone(), - src: code.clone(), - named: NamedSource::new(path.display().to_string(), code.clone()), - error, - })?; + for name in modules.sequence(&our_modules)? { + if let Some(module) = modules.remove(&name) { + let (checked_module, warnings) = module.infer( + &self.id_gen, + &self.config.name.to_string(), + tracing, + validate_module_name, + &mut self.module_sources, + &mut self.module_types, + &mut self.functions, + &mut self.data_types, + )?; - if validate_module_name { - ast.validate_module_name()?; + if our_modules.contains(checked_module.name.as_str()) { + self.warnings.extend(warnings); } - // Register any warnings emitted as type warnings - let type_warnings = type_warnings - .into_iter() - .map(|w| Warning::from_type_warning(w, path.clone(), code.clone())); - - if our_modules.contains(name.as_str()) { - self.warnings.extend(type_warnings); - } - - // Register module sources for an easier access later. - self.module_sources - .insert(name.clone(), (code.clone(), LineNumbers::new(&code))); - - // Register the types from this module so they can be - // imported into other modules. - self.module_types - .insert(name.clone(), ast.type_info.clone()); - - // Register function definitions & data-types for easier access later. - ast.register_definitions(&mut self.functions, &mut self.data_types); - - let checked_module = CheckedModule { - kind, - extra, - name: name.clone(), - code, - ast, - package, - input_path: path, - }; - - self.checked_modules.insert(name, checked_module); + self.checked_modules + .insert(checked_module.name.clone(), checked_module); } } diff --git a/crates/aiken-project/src/module.rs b/crates/aiken-project/src/module.rs index 5d3f281e..ff70e38a 100644 --- a/crates/aiken-project/src/module.rs +++ b/crates/aiken-project/src/module.rs @@ -1,11 +1,17 @@ -use crate::error::Error; +use crate::{Error, Warning}; use aiken_lang::{ ast::{ - DataType, Definition, Function, Located, ModuleKind, TypedModule, TypedValidator, - UntypedModule, Validator, + DataType, DataTypeKey, Definition, Function, FunctionAccessKey, Located, ModuleKind, + Tracing, TypedDataType, TypedFunction, TypedModule, TypedValidator, UntypedModule, + Validator, }, + line_numbers::LineNumbers, parser::extra::{comments_before, Comment, ModuleExtra}, + tipo::TypeInfo, + IdGenerator, }; +use indexmap::IndexMap; +use miette::NamedSource; use petgraph::{algo, graph::NodeIndex, Direction, Graph}; use std::{ collections::{BTreeSet, HashMap}, @@ -38,6 +44,74 @@ impl ParsedModule { (name, deps) } + + #[allow(clippy::too_many_arguments)] + pub fn infer( + self, + id_gen: &IdGenerator, + package: &str, + tracing: Tracing, + validate_module_name: bool, + module_sources: &mut HashMap, + module_types: &mut HashMap, + functions: &mut IndexMap, + data_types: &mut IndexMap, + ) -> Result<(CheckedModule, Vec), Error> { + let mut warnings = Vec::new(); + + let ast = self + .ast + .infer( + id_gen, + self.kind, + package, + module_types, + tracing, + &mut warnings, + ) + .map_err(|error| Error::Type { + path: self.path.clone(), + src: self.code.clone(), + named: NamedSource::new(self.path.display().to_string(), self.code.clone()), + error, + })?; + + let warnings = warnings + .into_iter() + .map(|w| Warning::from_type_warning(w, self.path.clone(), self.code.clone())) + .collect::>(); + + // Unless we're compiling prelude documentation, prevent keywords in module name + if validate_module_name { + ast.validate_module_name()?; + } + + // Register module sources for an easier access later. + module_sources.insert( + self.name.clone(), + (self.code.clone(), LineNumbers::new(&self.code)), + ); + + // Register the types from this module so they can be + // imported into other modules. + module_types.insert(self.name.clone(), ast.type_info.clone()); + + // Register function definitions & data-types for easier access later. + ast.register_definitions(functions, data_types); + + Ok(( + CheckedModule { + ast, + kind: self.kind, + extra: self.extra, + name: self.name, + code: self.code, + package: self.package, + input_path: self.path, + }, + warnings, + )) + } } pub struct ParsedModules(HashMap);