-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
290 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,108 +1,7 @@ | ||
use std::collections::HashMap; | ||
use std::env::args; | ||
use std::fmt::Display; | ||
use std::fs::read_to_string; | ||
use std::process::ExitCode; | ||
|
||
use ariadne::{Cache, Label, Report, ReportKind, Source}; | ||
use glob::glob; | ||
use litho_compiler::{builtins, Compiler}; | ||
use litho_language::lex::{SourceId, SourceMap, Span}; | ||
use smol_str::SmolStr; | ||
|
||
#[derive(Default)] | ||
pub struct Sources(HashMap<SourceId, (String, Source)>); | ||
|
||
impl Sources { | ||
pub fn insert(&mut self, source_id: SourceId, path: String, source: Source) { | ||
self.0.insert(source_id, (path, source)); | ||
} | ||
} | ||
|
||
impl Cache<SourceId> for Sources { | ||
fn display<'a>(&self, id: &'a SourceId) -> Option<Box<dyn Display + 'a>> { | ||
self.0 | ||
.get(id) | ||
.map(|(path, _)| Box::new(path.clone()) as Box<dyn Display>) | ||
} | ||
|
||
fn fetch(&mut self, id: &SourceId) -> Result<&Source, Box<dyn std::fmt::Debug + '_>> { | ||
self.0.get(id).map(|(_, text)| Ok(text)).unwrap() | ||
} | ||
} | ||
use litho_cli::cli; | ||
|
||
pub fn main() -> ExitCode { | ||
let mut inputs = vec![]; | ||
let mut args = args().skip(1); | ||
|
||
while let Some(arg) = args.next() { | ||
match arg.as_str() { | ||
"--version" | "-v" | "version" => { | ||
println!( | ||
"litho {} ({} {})", | ||
env!("CARGO_PKG_VERSION"), | ||
env!("VERGEN_GIT_SHA_SHORT"), | ||
env!("VERGEN_GIT_COMMIT_DATE") | ||
); | ||
|
||
return ExitCode::SUCCESS; | ||
} | ||
arg => inputs.extend( | ||
glob(&arg) | ||
.into_iter() | ||
.flatten() | ||
.map(IntoIterator::into_iter) | ||
.flatten() | ||
.map(|path| path.to_string_lossy().into_owned()), | ||
), | ||
} | ||
} | ||
|
||
let mut compiler = Compiler::<SmolStr>::new(); | ||
let mut source_map = SourceMap::new(); | ||
let mut sources = Sources::default(); | ||
|
||
for (path, text) in builtins().into_iter().copied() { | ||
let source_id = source_map.get_or_insert(path.to_owned()); | ||
sources.insert(source_id, path.to_owned(), Source::from(&text)); | ||
compiler.add_document(source_id, &text, true); | ||
} | ||
|
||
for input in inputs.iter() { | ||
let source_id = source_map.get_or_insert(input.clone()); | ||
let text = read_to_string(input.clone()).unwrap(); | ||
sources.insert(source_id, input.clone(), Source::from(&text)); | ||
compiler.add_document(source_id, &text, true); | ||
} | ||
|
||
compiler.rebuild(); | ||
|
||
let mut code = ExitCode::SUCCESS; | ||
|
||
for input in inputs.iter() { | ||
let Some(source_id) = source_map.get(&input) else { | ||
continue | ||
}; | ||
|
||
let diagnostics = compiler.diagnostics(source_id); | ||
|
||
for diagnostic in diagnostics { | ||
let span = diagnostic.span(); | ||
let mut builder = Report::<Span>::build(ReportKind::Error, span.source_id, span.start) | ||
.with_code(diagnostic.code()) | ||
.with_message(diagnostic.message()); | ||
builder.add_labels( | ||
diagnostic | ||
.labels() | ||
.into_iter() | ||
.map(|(span, message)| Label::new(span).with_message(message)), | ||
); | ||
builder.finish().eprint(&mut sources).unwrap(); | ||
eprintln!(""); | ||
|
||
code = ExitCode::FAILURE; | ||
} | ||
} | ||
|
||
code | ||
cli() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
use std::env::args; | ||
use std::process::ExitCode; | ||
|
||
use super::commands; | ||
|
||
pub fn cli() -> ExitCode { | ||
let command = args().skip(1).next(); | ||
|
||
match command.as_deref() { | ||
Some("generate") => {} | ||
Some("--version" | "-v" | "version") => return commands::version(), | ||
_ => {} | ||
} | ||
|
||
commands::generate() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
use std::env::args; | ||
use std::fs::{metadata, write}; | ||
use std::process::ExitCode; | ||
|
||
use ariadne::{Label, Report, ReportKind}; | ||
use litho_language::fmt::Format; | ||
use litho_language::lex::Span; | ||
use yansi::Paint; | ||
|
||
use crate::Workspace; | ||
|
||
#[derive(Default)] | ||
pub struct Options { | ||
fix: bool, | ||
format: bool, | ||
} | ||
|
||
pub enum FormattingError { | ||
Unformatted, | ||
Changed, | ||
} | ||
|
||
pub fn generate() -> ExitCode { | ||
let mut inputs = vec![]; | ||
let mut options = Options::default(); | ||
|
||
for arg in args().skip(1) { | ||
match arg.as_str() { | ||
"--fix" => options.fix = true, | ||
"--fmt" | "--format" => options.format = true, | ||
_ => inputs.push(arg), | ||
} | ||
} | ||
|
||
let workspace = Workspace::new(inputs); | ||
|
||
let mut files = workspace.files().collect::<Vec<_>>(); | ||
files.sort_by_key(|file| file.path); | ||
|
||
let mut sources = workspace.to_sources(); | ||
|
||
let mut code = ExitCode::SUCCESS; | ||
|
||
for file in files { | ||
let formatted = file.document.format_to_string(80); | ||
if &formatted != file.text { | ||
let formatting_error = if options.fix { | ||
let modified = metadata(file.path).and_then(|metadata| metadata.modified()); | ||
|
||
if file.modified.as_ref().ok() != modified.as_ref().ok() { | ||
Some(FormattingError::Changed) | ||
} else { | ||
write(file.path, formatted).unwrap(); | ||
None | ||
} | ||
} else { | ||
Some(FormattingError::Unformatted) | ||
}; | ||
|
||
if let Some(diagnostic) = formatting_error { | ||
eprintln!( | ||
"{} {}\n {}{}{}\n", | ||
Paint::red("[E0000] Error:"), | ||
match diagnostic { | ||
FormattingError::Changed => "File has changed on disk while formatting.", | ||
FormattingError::Unformatted => "File must be formatted.", | ||
}, | ||
Paint::new("──[").dimmed(), | ||
file.path, | ||
Paint::new("]").dimmed(), | ||
); | ||
|
||
code = ExitCode::FAILURE; | ||
} | ||
} | ||
|
||
for diagnostic in workspace.compiler().diagnostics(file.source_id).cloned() { | ||
let span = diagnostic.span(); | ||
let mut builder = Report::<Span>::build(ReportKind::Error, span.source_id, span.start) | ||
.with_code(diagnostic.code()) | ||
.with_message(diagnostic.message()); | ||
builder.add_labels( | ||
diagnostic | ||
.labels() | ||
.into_iter() | ||
.map(|(span, message)| Label::new(span).with_message(message)), | ||
); | ||
builder.finish().eprint(&mut sources).unwrap(); | ||
eprintln!(""); | ||
|
||
code = ExitCode::FAILURE; | ||
} | ||
} | ||
|
||
code | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
mod generate; | ||
mod version; | ||
|
||
pub use generate::generate; | ||
pub use version::version; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
use std::process::ExitCode; | ||
|
||
pub fn version() -> ExitCode { | ||
println!( | ||
"litho {} ({} {})", | ||
env!("CARGO_PKG_VERSION"), | ||
env!("VERGEN_GIT_SHA_SHORT"), | ||
env!("VERGEN_GIT_COMMIT_DATE") | ||
); | ||
|
||
ExitCode::SUCCESS | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
mod cli; | ||
pub mod commands; | ||
mod workspace; | ||
|
||
pub use cli::cli; | ||
pub use workspace::Workspace; |
Oops, something went wrong.