Merge branch 'master' into remove_bind_by_move

This commit is contained in:
Jonathan Turner
2019-08-29 15:08:23 +12:00
committed by GitHub
23 changed files with 1263 additions and 1043 deletions

View File

@ -272,11 +272,7 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
if ctrlcbreak {
std::process::exit(0);
} else {
context
.host
.lock()
.unwrap()
.stdout("CTRL-C pressed (again to quit)");
context.with_host(|host| host.stdout("CTRL-C pressed (again to quit)"));
ctrlcbreak = true;
continue;
}
@ -285,18 +281,19 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
LineResult::Error(mut line, err) => {
rl.add_history_entry(line.clone());
let diag = err.to_diagnostic();
let host = context.host.lock().unwrap();
let writer = host.err_termcolor();
line.push_str(" ");
let files = crate::parser::Files::new(line);
let _ = std::panic::catch_unwind(move || {
let _ = language_reporting::emit(
&mut writer.lock(),
&files,
&diag,
&language_reporting::DefaultConfig,
);
});
context.with_host(|host| {
let writer = host.err_termcolor();
line.push_str(" ");
let files = crate::parser::Files::new(line);
let _ = std::panic::catch_unwind(move || {
let _ = language_reporting::emit(
&mut writer.lock(),
&files,
&diag,
&language_reporting::DefaultConfig,
);
});
})
}
LineResult::Break => {
@ -304,11 +301,9 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
}
LineResult::FatalError(_, err) => {
context
.host
.lock()
.unwrap()
.stdout(&format!("A surprising fatal error occurred.\n{:?}", err));
context.with_host(|host| {
host.stdout(&format!("A surprising fatal error occurred.\n{:?}", err))
});
}
}
ctrlcbreak = false;
@ -330,31 +325,6 @@ enum LineResult {
FatalError(String, ShellError),
}
impl std::ops::Try for LineResult {
type Ok = Option<String>;
type Error = (String, ShellError);
fn into_result(self) -> Result<Option<String>, (String, ShellError)> {
match self {
LineResult::Success(s) => Ok(Some(s)),
LineResult::Error(string, err) => Err((string, err)),
LineResult::Break => Ok(None),
LineResult::CtrlC => Ok(None),
LineResult::FatalError(string, err) => Err((string, err)),
}
}
fn from_error(v: (String, ShellError)) -> Self {
LineResult::Error(v.0, v.1)
}
fn from_ok(v: Option<String>) -> Self {
match v {
None => LineResult::Break,
Some(v) => LineResult::Success(v),
}
}
}
async fn process_line(readline: Result<String, ReadlineError>, ctx: &mut Context) -> LineResult {
match &readline {
Ok(line) if line.trim() == "" => LineResult::Success(line.clone()),
@ -371,8 +341,10 @@ async fn process_line(readline: Result<String, ReadlineError>, ctx: &mut Context
debug!("=== Parsed ===");
debug!("{:#?}", result);
let mut pipeline = classify_pipeline(&result, ctx, &Text::from(line))
.map_err(|err| (line.clone(), err))?;
let mut pipeline = match classify_pipeline(&result, ctx, &Text::from(line)) {
Ok(pipeline) => pipeline,
Err(err) => return LineResult::Error(line.clone(), err),
};
match pipeline.commands.last() {
Some(ClassifiedCommand::External(_)) => {}

View File

@ -315,19 +315,23 @@ impl ExternalCommand {
if arg_string.contains("$it") {
let mut first = true;
for i in &inputs {
if i.as_string().is_err() {
let mut span = name_span;
for arg in &self.args {
if arg.item.contains("$it") {
span = arg.span();
let i = match i.as_string() {
Err(_err) => {
let mut span = name_span;
for arg in &self.args {
if arg.item.contains("$it") {
span = arg.span();
}
}
return Err(ShellError::labeled_error(
"External $it needs string data",
"given object instead of string data",
span,
));
}
return Err(ShellError::labeled_error(
"External $it needs string data",
"given object instead of string data",
span,
));
}
Ok(val) => val,
};
if !first {
new_arg_string.push_str("&&");
new_arg_string.push_str(&self.name);
@ -341,7 +345,7 @@ impl ExternalCommand {
}
new_arg_string.push_str(" ");
new_arg_string.push_str(&arg.replace("$it", &i.as_string().unwrap()));
new_arg_string.push_str(&arg.replace("$it", &i));
}
}
} else {
@ -366,7 +370,7 @@ impl ExternalCommand {
process = process.stdin(stdin);
}
let mut popen = process.popen().unwrap();
let mut popen = process.popen()?;
match stream_next {
StreamNext::Last => {

View File

@ -596,14 +596,10 @@ impl Command {
.unwrap();
// We don't have an $it or block, so just execute what we have
command
.run(&call_info, &registry, &raw_args.shell_manager, nothing)?
.into()
// let out = match command.run(&call_info, &registry, &raw_args.shell_manager, nothing) {
// Ok(o) => o,
// Err(e) => VecDeque::from(vec![ReturnValue::Err(e)]),
// };
// Ok(out.to_output_stream())
match command.run(&call_info, &registry, &raw_args.shell_manager, nothing) {
Ok(o) => o,
Err(e) => OutputStream::one(Err(e)),
}
}
}
}

View File

@ -74,7 +74,7 @@ impl CommandRegistry {
pub struct Context {
registry: CommandRegistry,
crate source_map: SourceMap,
crate host: Arc<Mutex<dyn Host + Send>>,
host: Arc<Mutex<dyn Host + Send>>,
crate shell_manager: ShellManager,
}
@ -93,6 +93,12 @@ impl Context {
})
}
crate fn with_host(&mut self, block: impl FnOnce(&mut dyn Host)) {
let mut host = self.host.lock().unwrap();
block(&mut *host)
}
pub fn add_commands(&mut self, commands: Vec<Arc<Command>>) {
for command in commands {
self.registry.insert(command.name().to_string(), command);
@ -103,10 +109,6 @@ impl Context {
self.source_map.insert(uuid, span_source);
}
// pub fn clone_commands(&self) -> CommandRegistry {
// self.registry.clone()
// }
crate fn has_command(&self, name: &str) -> bool {
self.registry.has(name)
}

View File

@ -1,7 +1,6 @@
#![feature(crate_visibility_modifier)]
#![feature(in_band_lifetimes)]
#![feature(generators)]
#![feature(try_trait)]
#![feature(specialization)]
#![feature(proc_macro_hygiene)]
@ -30,7 +29,7 @@ pub use crate::env::host::BasicHost;
pub use crate::object::base::OF64;
pub use crate::parser::hir::SyntaxType;
pub use crate::plugin::{serve_plugin, Plugin};
pub use crate::utils::{AbsolutePath, RelativePath};
pub use crate::utils::{AbsoluteFile, AbsolutePath, RelativePath};
pub use cli::cli;
pub use errors::ShellError;
pub use object::base::{Primitive, Value};

View File

@ -16,10 +16,6 @@ macro_rules! trace_stream {
(target: $target:tt, $desc:tt = $expr:expr) => {{
if log::log_enabled!(target: $target, log::Level::Trace) {
use futures::stream::StreamExt;
// Blocking is generally quite bad, but this is for debugging
// let mut local = futures::executor::LocalPool::new();
// let objects = local.run_until($expr.into_vec());
// let objects: Vec<_> = futures::executor::block_on($expr.into_vec());
let objects = $expr.values.inspect(|o| {
trace!(target: $target, "{} = {:#?}", $desc, o.debug());

View File

@ -84,22 +84,6 @@ impl OutputStream {
}
}
impl std::ops::Try for OutputStream {
type Ok = OutputStream;
type Error = ShellError;
fn into_result(self) -> Result<Self::Ok, Self::Error> {
Ok(self)
}
fn from_error(v: Self::Error) -> Self {
OutputStream::one(Err(v))
}
fn from_ok(v: Self::Ok) -> Self {
v
}
}
impl Stream for OutputStream {
type Item = ReturnValue;

View File

@ -1,7 +1,52 @@
use crate::errors::ShellError;
use std::fmt;
use std::ops::Div;
use std::path::{Path, PathBuf};
pub struct AbsoluteFile {
inner: PathBuf,
}
impl AbsoluteFile {
pub fn new(path: impl AsRef<Path>) -> AbsoluteFile {
let path = path.as_ref();
if !path.is_absolute() {
panic!(
"AbsoluteFile::new must take an absolute path :: {}",
path.display()
)
} else if path.is_dir() {
// At the moment, this is not an invariant, but rather a way to catch bugs
// in tests.
panic!(
"AbsoluteFile::new must not take a directory :: {}",
path.display()
)
} else {
AbsoluteFile {
inner: path.to_path_buf(),
}
}
}
pub fn dir(&self) -> AbsolutePath {
AbsolutePath::new(self.inner.parent().unwrap())
}
}
impl From<AbsoluteFile> for PathBuf {
fn from(file: AbsoluteFile) -> Self {
file.inner
}
}
impl fmt::Display for AbsoluteFile {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.inner.display())
}
}
pub struct AbsolutePath {
inner: PathBuf,
}
@ -20,6 +65,12 @@ impl AbsolutePath {
}
}
impl fmt::Display for AbsolutePath {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.inner.display())
}
}
impl Div<&str> for &AbsolutePath {
type Output = AbsolutePath;
@ -72,6 +123,12 @@ impl<T: AsRef<str>> Div<T> for &RelativePath {
}
}
impl fmt::Display for RelativePath {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.inner.display())
}
}
#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct Res {
pub loc: PathBuf,