#![allow(clippy::enum_variant_names)]
mod db;
pub mod diagnostics;
mod diagnostics_snippets;
mod driver;
pub use mun_hir::FileId;
pub use mun_paths::{RelativePath, RelativePathBuf};
pub use mun_target::spec::Target;
use std::path::{Path, PathBuf};
pub use crate::driver::DisplayColor;
pub use crate::driver::{Config, Driver};
pub use mun_codegen::OptimizationLevel;
pub use crate::db::CompilerDatabase;
pub use annotate_snippets::snippet::AnnotationType;
use mun_project::Package;
use std::ffi::OsStr;
use std::io::stderr;
#[derive(Debug, Clone)]
pub enum PathOrInline {
Path(PathBuf),
Inline {
rel_path: RelativePathBuf,
contents: String,
},
}
#[derive(Debug, Clone)]
pub struct CompilerOptions {
pub input: PathOrInline,
pub config: Config,
pub emit_colors: DisplayColor,
}
impl CompilerOptions {
pub fn with_path<P: AsRef<Path>>(input: P) -> CompilerOptions {
CompilerOptions {
input: PathOrInline::Path(input.as_ref().to_path_buf()),
config: Config::default(),
emit_colors: DisplayColor::Auto,
}
}
pub fn with_file<P: Into<RelativePathBuf>, T: AsRef<str>>(
path: P,
input: T,
) -> CompilerOptions {
CompilerOptions {
input: PathOrInline::Inline {
rel_path: path.into(),
contents: input.as_ref().to_string(),
},
config: Config::default(),
emit_colors: DisplayColor::Auto,
}
}
}
pub fn is_source_file<P: AsRef<Path>>(p: P) -> bool {
p.as_ref().extension() == Some(OsStr::new("mun"))
}
pub fn ensure_package_output_dir(
package: &Package,
config: &Config,
) -> Result<PathBuf, anyhow::Error> {
let out_dir = config
.out_dir
.clone()
.unwrap_or_else(|| package.root().join("target"));
std::fs::create_dir_all(&out_dir)?;
Ok(out_dir)
}
pub fn compile_manifest(
manifest_path: &Path,
config: Config,
emit_colors: DisplayColor,
) -> Result<bool, anyhow::Error> {
let (_package, mut driver) = Driver::with_package_path(manifest_path, config)?;
if driver.emit_diagnostics(&mut stderr(), emit_colors)? {
return Ok(false);
};
driver.write_all_assemblies(false)?;
Ok(true)
}
pub fn compute_source_relative_path(
source_dir: &Path,
source_path: &Path,
) -> Result<RelativePathBuf, anyhow::Error> {
RelativePathBuf::from_path(source_path.strip_prefix(source_dir).map_err(|e| {
anyhow::anyhow!(
"could not determine relative source path for '{}': {}",
source_path.display(),
e
)
})?)
.map_err(|e| {
anyhow::anyhow!(
"could not determine source relative path for '{}': {}",
source_path.display(),
e
)
})
}
#[cfg(test)]
mod test {
use crate::{compute_source_relative_path, is_source_file, RelativePath};
use std::path::Path;
#[test]
fn test_is_source_file() {
assert!(is_source_file("main.mun"));
assert!(is_source_file("foo.mun"));
assert!(is_source_file("foo/bar.mun"));
assert!(!is_source_file("foo/bar"));
}
#[test]
fn test_compute_source_relative_path() {
let source_dir = Path::new("some_path/src");
assert_eq!(
compute_source_relative_path(source_dir, &source_dir.join("main.mun")).unwrap(),
RelativePath::new("main.mun")
);
assert_eq!(
compute_source_relative_path(source_dir, &source_dir.join("foo/bar/main.mun")).unwrap(),
RelativePath::new("foo/bar/main.mun")
);
}
}