Document 'export' and provide better errors on module not found.

This commit is contained in:
KtorZ 2024-08-06 11:09:05 +02:00
parent e3b1cf1093
commit 8c121f6d97
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
4 changed files with 39 additions and 8 deletions

View File

@ -1820,7 +1820,7 @@ pub enum UnknownRecordFieldSituation {
FunctionCall, FunctionCall,
} }
fn format_suggestion(sample: &UntypedExpr) -> String { pub fn format_suggestion(sample: &UntypedExpr) -> String {
Formatter::new() Formatter::new()
.expr(sample, false) .expr(sample, false)
.to_pretty_string(70) .to_pretty_string(70)

View File

@ -128,6 +128,12 @@ pub enum Error {
#[error("I couldn't find any exportable function named '{name}' in module '{module}'.")] #[error("I couldn't find any exportable function named '{name}' in module '{module}'.")]
ExportNotFound { module: String, name: String }, ExportNotFound { module: String, name: String },
#[error("No such module '{module}' found in the project.")]
ModuleNotFound {
module: String,
known_modules: Vec<String>,
},
#[error("I located conditional modules under 'env', but no default one!")] #[error("I located conditional modules under 'env', but no default one!")]
NoDefaultEnvironment, NoDefaultEnvironment,
} }
@ -199,6 +205,7 @@ impl ExtraData for Error {
| Error::MoreThanOneValidatorFound { .. } | Error::MoreThanOneValidatorFound { .. }
| Error::Module { .. } | Error::Module { .. }
| Error::NoDefaultEnvironment { .. } | Error::NoDefaultEnvironment { .. }
| Error::ModuleNotFound { .. }
| Error::ExportNotFound { .. } => None, | Error::ExportNotFound { .. } => None,
Error::Type { error, .. } => error.extra_data(), Error::Type { error, .. } => error.extra_data(),
} }
@ -227,6 +234,7 @@ impl GetSource for Error {
| Error::MalformedStakeAddress { .. } | Error::MalformedStakeAddress { .. }
| Error::NoValidatorNotFound { .. } | Error::NoValidatorNotFound { .. }
| Error::MoreThanOneValidatorFound { .. } | Error::MoreThanOneValidatorFound { .. }
| Error::ModuleNotFound { .. }
| Error::ExportNotFound { .. } | Error::ExportNotFound { .. }
| Error::NoDefaultEnvironment { .. } | Error::NoDefaultEnvironment { .. }
| Error::Module { .. } => None, | Error::Module { .. } => None,
@ -259,6 +267,7 @@ impl GetSource for Error {
| Error::NoValidatorNotFound { .. } | Error::NoValidatorNotFound { .. }
| Error::NoDefaultEnvironment { .. } | Error::NoDefaultEnvironment { .. }
| Error::MoreThanOneValidatorFound { .. } | Error::MoreThanOneValidatorFound { .. }
| Error::ModuleNotFound { .. }
| Error::ExportNotFound { .. } | Error::ExportNotFound { .. }
| Error::Module { .. } => None, | Error::Module { .. } => None,
Error::TomlLoading { src, .. } | Error::Parse { src, .. } | Error::Type { src, .. } => { Error::TomlLoading { src, .. } | Error::Parse { src, .. } | Error::Type { src, .. } => {
@ -313,6 +322,7 @@ impl Diagnostic for Error {
Error::NoValidatorNotFound { .. } => None, Error::NoValidatorNotFound { .. } => None,
Error::MoreThanOneValidatorFound { .. } => None, Error::MoreThanOneValidatorFound { .. } => None,
Error::ExportNotFound { .. } => None, Error::ExportNotFound { .. } => None,
Error::ModuleNotFound { .. } => None,
Error::NoDefaultEnvironment { .. } => None, Error::NoDefaultEnvironment { .. } => None,
Error::Module(e) => e.code().map(boxed), Error::Module(e) => e.code().map(boxed),
} }
@ -347,6 +357,14 @@ impl Diagnostic for Error {
Error::ZipExtract(_) => None, Error::ZipExtract(_) => None,
Error::JoinError(_) => None, Error::JoinError(_) => None,
Error::ExportNotFound { .. } => None, Error::ExportNotFound { .. } => None,
Error::ModuleNotFound { known_modules, .. } => Some(Box::new(format!(
"I know about the following modules:\n{}",
known_modules
.iter()
.map(|s| format!("─▶ {}", s.if_supports_color(Stdout, |s| s.purple())))
.collect::<Vec<_>>()
.join("\n")
))),
Error::UnknownPackageVersion { .. } => Some(Box::new( Error::UnknownPackageVersion { .. } => Some(Box::new(
"Perhaps, double-check the package repository and version?", "Perhaps, double-check the package repository and version?",
)), )),
@ -419,6 +437,7 @@ impl Diagnostic for Error {
Error::NoValidatorNotFound { .. } => None, Error::NoValidatorNotFound { .. } => None,
Error::MoreThanOneValidatorFound { .. } => None, Error::MoreThanOneValidatorFound { .. } => None,
Error::NoDefaultEnvironment { .. } => None, Error::NoDefaultEnvironment { .. } => None,
Error::ModuleNotFound { .. } => None,
Error::Module(e) => e.labels(), Error::Module(e) => e.labels(),
} }
} }
@ -428,6 +447,7 @@ impl Diagnostic for Error {
Error::DuplicateModule { .. } => None, Error::DuplicateModule { .. } => None,
Error::FileIo { .. } => None, Error::FileIo { .. } => None,
Error::ImportCycle { .. } => None, Error::ImportCycle { .. } => None,
Error::ModuleNotFound { .. } => None,
Error::ExportNotFound { .. } => None, Error::ExportNotFound { .. } => None,
Error::Blueprint(e) => e.source_code(), Error::Blueprint(e) => e.source_code(),
Error::NoDefaultEnvironment { .. } => None, Error::NoDefaultEnvironment { .. } => None,
@ -456,6 +476,7 @@ impl Diagnostic for Error {
Error::DuplicateModule { .. } => None, Error::DuplicateModule { .. } => None,
Error::FileIo { .. } => None, Error::FileIo { .. } => None,
Error::ImportCycle { .. } => None, Error::ImportCycle { .. } => None,
Error::ModuleNotFound { .. } => None,
Error::ExportNotFound { .. } => None, Error::ExportNotFound { .. } => None,
Error::Blueprint(e) => e.url(), Error::Blueprint(e) => e.url(),
Error::Parse { .. } => None, Error::Parse { .. } => None,
@ -483,6 +504,7 @@ impl Diagnostic for Error {
match self { match self {
Error::DuplicateModule { .. } => None, Error::DuplicateModule { .. } => None,
Error::FileIo { .. } => None, Error::FileIo { .. } => None,
Error::ModuleNotFound { .. } => None,
Error::ExportNotFound { .. } => None, Error::ExportNotFound { .. } => None,
Error::Blueprint(e) => e.related(), Error::Blueprint(e) => e.related(),
Error::ImportCycle { .. } => None, Error::ImportCycle { .. } => None,

View File

@ -534,14 +534,21 @@ where
} }
pub fn export(&self, module: &str, name: &str, tracing: Tracing) -> Result<Export, Error> { pub fn export(&self, module: &str, name: &str, tracing: Tracing) -> Result<Export, Error> {
let checked_module =
self.checked_modules self.checked_modules
.get(module) .get(module)
.and_then(|checked_module| { .ok_or_else(|| Error::ModuleNotFound {
checked_module.ast.definitions().find_map(|def| match def { module: module.to_string(),
known_modules: self.checked_modules.keys().cloned().collect(),
})?;
checked_module
.ast
.definitions()
.find_map(|def| match def {
Definition::Fn(func) if func.name == name => Some((checked_module, func)), Definition::Fn(func) if func.name == name => Some((checked_module, func)),
_ => None, _ => None,
}) })
})
.map(|(checked_module, func)| { .map(|(checked_module, func)| {
let mut generator = self.new_generator(tracing); let mut generator = self.new_generator(tracing);

View File

@ -4,6 +4,8 @@ use aiken_project::{options::Options, watch::with_project};
use std::path::PathBuf; use std::path::PathBuf;
#[derive(clap::Args)] #[derive(clap::Args)]
/// Export a function as a standalone UPLC program. Arguments to the function can be applied using
/// `aiken apply`.
pub struct Args { pub struct Args {
/// Path to project /// Path to project
directory: Option<PathBuf>, directory: Option<PathBuf>,