Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cargo check statements #71

Merged
merged 5 commits into from
Oct 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 29 additions & 5 deletions src/irust/cargo_cmds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,23 +88,47 @@ pub fn cargo_add(dep: &[String]) -> io::Result<std::process::Child> {
.spawn()?)
}

macro_rules! cargo_build_common {
macro_rules! cargo_common {
// The difference in env flags makes cargo recompiles again!!!
// => make sure all build env flags are the same
//
// Make sure to specify CARGO_TARGET_DIR to overwrite custom user one (in case it's set)
($toolchain: ident) => {
($cmd: literal, $toolchain: ident) => {
Command::new("cargo")
.arg($toolchain.as_arg())
.arg("build")
.arg($cmd)
.env("CARGO_TARGET_DIR", &*IRUST_TARGET_DIR)
.env("RUSTFLAGS", "-Awarnings")
.current_dir(&*IRUST_DIR)
};
}

pub fn cargo_check(toolchain: ToolChain) -> Result<std::process::Child, io::Error> {
Ok(cargo_common!("check", toolchain)
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.spawn()?)
}

pub fn cargo_check_output(toolchain: ToolChain) -> Result<String, io::Error> {
#[cfg(not(windows))]
let color = "always";
#[cfg(windows)]
let color = if crossterm::ansi_support::supports_ansi() {
"always"
} else {
"never"
};

Ok(stdout_and_stderr(
cargo_common!("check", toolchain)
.args(&["--color", color])
.output()?,
))
}

pub fn cargo_build(toolchain: ToolChain) -> Result<std::process::Child, io::Error> {
Ok(cargo_build_common!(toolchain)
Ok(cargo_common!("build", toolchain)
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.spawn()?)
Expand All @@ -125,7 +149,7 @@ pub fn cargo_build_output(color: bool, toolchain: ToolChain) -> Result<String, i
};

Ok(stdout_and_stderr(
cargo_build_common!(toolchain)
cargo_common!("build", toolchain)
.args(&["--color", color])
.output()?,
))
Expand Down
13 changes: 13 additions & 0 deletions src/irust/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,16 @@ pub fn format_eval_output(output: &str) -> Option<Printer> {
Some(eval_output)
}
}

// Note: Maybe use this for cargo build as well
fn check_is_err(s: &str) -> bool {
!s.contains("dev [unoptimized + debuginfo]")
}

pub fn format_check_output(output: String) -> Option<Printer> {
if check_is_err(&output) {
Some(format_err(&output))
} else {
None
}
}
2 changes: 2 additions & 0 deletions src/irust/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub struct Options {
pub first_irust_run: bool,
pub enable_racer: bool,
pub toolchain: ToolChain,
pub check_statements: bool,
}

impl Default for Options {
Expand Down Expand Up @@ -59,6 +60,7 @@ impl Default for Options {
//other
first_irust_run: true,
toolchain: ToolChain::Stable,
check_statements: true,
}
}
}
Expand Down
59 changes: 43 additions & 16 deletions src/irust/parser.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::cargo_cmds::ToolChain;
use super::cargo_cmds::{cargo_fmt, cargo_fmt_file, cargo_run, MAIN_FILE, MAIN_FILE_EXTERN};
use super::highlight::highlight;
use crate::irust::format::{format_err, format_eval_output, output_is_err};
use crate::irust::format::{format_check_output, format_err, format_eval_output, output_is_err};
use crate::irust::printer::{Printer, PrinterItem, PrinterItemType};
use crate::irust::{IRust, IRustError};
use crate::utils::{remove_main, stdout_and_stderr};
Expand All @@ -27,6 +27,7 @@ impl IRust {
cmd if cmd.starts_with(":cd") => self.cd(),
cmd if cmd.starts_with(":color") => self.color(),
cmd if cmd.starts_with(":toolchain") => self.toolchain(),
cmd if cmd.starts_with(":check_statements") => self.check_statements(),
_ => self.parse_second_order(),
}
}
Expand All @@ -47,6 +48,18 @@ impl IRust {
Ok(outputs)
}

fn check_statements(&mut self) -> Result<Printer, IRustError> {
const ERROR: &str = "Invalid argument, accepted values are `false` `true`";
let buffer = self.buffer.to_string();
let buffer = buffer.split_whitespace().nth(1).ok_or(ERROR)?;
self.options.check_statements = buffer.parse().map_err(|_| ERROR)?;

let mut outputs = Printer::new(PrinterItem::new(SUCCESS.to_string(), PrinterItemType::Ok));
outputs.add_new_line(1);

Ok(outputs)
}

fn del(&mut self) -> Result<Printer, IRustError> {
if let Some(line_num) = self.buffer.to_string().split_whitespace().last() {
self.repl.del(line_num)?;
Expand Down Expand Up @@ -105,6 +118,13 @@ impl IRust {
self.cursor.save_position()?;
self.wait_add(self.repl.add_dep(&dep)?, "Add")?;
self.wait_add(self.repl.build(self.options.toolchain)?, "Build")?;

if self.options.check_statements {
self.wait_add(
super::cargo_cmds::cargo_check(self.options.toolchain)?,
"Check",
)?;
}
self.write_newline()?;

let mut outputs = Printer::new(PrinterItem::new(SUCCESS.to_string(), PrinterItemType::Ok));
Expand Down Expand Up @@ -197,7 +217,7 @@ impl IRust {
if output_is_err(&output) {
Ok(format_err(&output))
} else {
self.repl.insert(code, false);
self.repl.insert(code);
let mut outputs =
Printer::new(PrinterItem::new(SUCCESS.to_string(), PrinterItemType::Ok));
outputs.add_new_line(1);
Expand Down Expand Up @@ -287,20 +307,12 @@ impl IRust {
// struct B{}
const ATTRIBUTE: &str = "#";

// CRATE_ATTRIBUTE are special in the sense that they should be inserted outside of the main function
// #![feature(unboxed_closures)]
// fn main() {}
const CRATE_ATTRIBUTE: &str = "#!";

// This trimed buffer should not be inserted nor evaluated
let buffer = self.buffer.to_string();
let buffer = buffer.trim();

if buffer.is_empty() {
Ok(Printer::default())
} else if buffer.starts_with(CRATE_ATTRIBUTE) {
self.repl.insert(self.buffer.to_string(), true);
let printer = Printer::default();
Ok(printer)
} else if buffer.ends_with(';')
|| buffer.starts_with(FUNCTION_DEF)
|| buffer.starts_with(ASYNC_FUNCTION_DEF)
Expand All @@ -313,13 +325,28 @@ impl IRust {
|| buffer.starts_with(WHILE)
|| buffer.starts_with(EXTERN)
{
self.repl.insert(self.buffer.to_string(), false);
let mut printer = Printer::default();

let mut insert_flag = true;

// save repl to main_extern.rs which can be used with external editors
self.repl.write_to_extern()?;
let _ = cargo_fmt_file(&*MAIN_FILE_EXTERN);
if self.options.check_statements {
if let Some(mut e) = format_check_output(
self.repl
.check(self.buffer.to_string(), self.options.toolchain)?,
) {
printer.append(&mut e);
insert_flag = false;
}
}

let printer = Printer::default();
// if cargo_check is disabled or if cargo_check is enabled but returned no error
if insert_flag {
self.repl.insert(self.buffer.to_string());

// save repl to main_extern.rs which can be used with external editors
self.repl.write_to_extern()?;
let _ = cargo_fmt_file(&*MAIN_FILE_EXTERN);
}

Ok(printer)
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/irust/racer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub struct Racer {
// suggestions: (Name, definition)
suggestions: Vec<(String, String)>,
suggestion_idx: usize,
cmds: [String; 12],
cmds: [String; 13],
update_lock: bool,
}

Expand Down Expand Up @@ -51,6 +51,7 @@ impl Racer {
"cd".to_string(),
"color".to_string(),
"toolchain".to_string(),
"check_statements".to_string(),
];

Ok(Racer {
Expand Down
21 changes: 18 additions & 3 deletions src/irust/repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,13 @@ impl Repl {
Ok(())
}

pub fn insert(&mut self, input: String, outside_main: bool) {
pub fn insert(&mut self, input: String) {
// CRATE_ATTRIBUTE are special in the sense that they should be inserted outside of the main function
// #![feature(unboxed_closures)]
// fn main() {}
const CRATE_ATTRIBUTE: &str = "#!";

let outside_main = input.trim_start().starts_with(CRATE_ATTRIBUTE);
if outside_main {
for line in input.lines() {
self.body.insert(0, line.to_owned());
Expand Down Expand Up @@ -101,7 +107,7 @@ impl Repl {
let orig_body = self.body.clone();
let orig_cursor = self.cursor;

self.insert(input, false);
self.insert(input);
self.write()?;
let output = cargo_build_output(true, toolchain)?;

Expand All @@ -118,7 +124,7 @@ impl Repl {
let orig_body = self.body.clone();
let orig_cursor = self.cursor;

self.insert(input, false);
self.insert(input);
self.write()?;
f()?;

Expand All @@ -136,6 +142,15 @@ impl Repl {
cargo_build(toolchain)
}

pub fn check(&mut self, buffer: String, toolchain: ToolChain) -> Result<String, IRustError> {
let mut result = String::new();
self.eval_in_tmp_repl(buffer, || {
result = cargo_check_output(toolchain)?;
Ok(())
})?;
Ok(result)
}

pub fn write(&self) -> io::Result<()> {
let mut main_file = std::fs::File::create(&*MAIN_FILE)?;
write!(main_file, "{}", self.body.join("\n"))?;
Expand Down