From 0c4100db345f2728e4aabb4379445d854b7f57d9 Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Sat, 16 Dec 2017 01:51:37 +0100 Subject: [PATCH] fix(completion): Don't print duplicate primitive modules --- base/src/lib.rs | 13 +++++++++++++ completion/src/lib.rs | 44 ++++++++++++++----------------------------- src/import.rs | 7 +++++-- src/io.rs | 1 - src/lib.rs | 15 ++------------- 5 files changed, 34 insertions(+), 46 deletions(-) diff --git a/base/src/lib.rs b/base/src/lib.rs index 9dc5645eec..a991e4e89a 100644 --- a/base/src/lib.rs +++ b/base/src/lib.rs @@ -86,3 +86,16 @@ pub mod serialization; pub mod source; pub mod symbol; pub mod types; + + +pub fn filename_to_module(filename: &str) -> String { + use std::path::Path; + let path = Path::new(filename); + let name = path.extension().map_or(filename, |ext| { + ext.to_str() + .map(|ext| &filename[..filename.len() - ext.len() - 1]) + .unwrap_or(filename) + }); + + name.replace(|c: char| c == '/' || c == '\\', ".") +} diff --git a/completion/src/lib.rs b/completion/src/lib.rs index a8065dc362..62e41883ad 100644 --- a/completion/src/lib.rs +++ b/completion/src/lib.rs @@ -10,12 +10,13 @@ extern crate gluon_base as base; use std::borrow::Cow; use std::iter::once; use std::cmp::Ordering; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use either::Either; use itertools::Itertools; +use base::filename_to_module; use base::ast::{walk_expr, walk_pattern, AstType, Expr, Pattern, PatternField, SpannedExpr, SpannedIdent, SpannedPattern, Typed, TypedIdent, Visitor}; use base::fnv::{FnvMap, FnvSet}; @@ -1123,13 +1124,12 @@ impl SuggestionQuery { let path = Name::new(path); let base = PathBuf::from(path.module().as_str().replace(".", "/")); - let prefix = path.declared_name(); - let mut module_prefixes = self.paths + let modules = self.paths .iter() - .map(|root| root.join(&*base)) .flat_map(|root| { - walkdir::WalkDir::new(&*root) + let walk_root = root.join(&*base); + walkdir::WalkDir::new(walk_root) .into_iter() .filter_map(|entry| entry.ok()) .filter_map(move |entry| { @@ -1138,14 +1138,9 @@ impl SuggestionQuery { { let unprefixed_file = entry .path() - .strip_prefix(&root) + .strip_prefix(&*root) .expect("Root is not a prefix of path from walk_dir"); - unprefixed_file - .iter() - .next() - .and_then(|s| Path::new(s).file_stem()) - .and_then(|s| s.to_str()) - .map(|s| s.to_string()) + unprefixed_file.to_str().map(filename_to_module) } else { None } @@ -1153,12 +1148,11 @@ impl SuggestionQuery { }) .collect::>(); - module_prefixes.sort(); - module_prefixes.dedup(); - suggestions.extend( - self.modules + modules .iter() + .map(|s| &s[..]) + .chain(self.modules.iter().map(|s| &s[..])) .filter(|module| module.starts_with(path.as_str())) .map(|module| { let name = module[path.module().as_str().len()..] @@ -1169,27 +1163,17 @@ impl SuggestionQuery { .to_string(); Suggestion { name, - typ: Either::Right(Type::hole()), - } - }), - ); - - suggestions.extend( - module_prefixes - .into_iter() - .filter(|name| name.starts_with(prefix)) - .map(|name| { - let full_name = format!("{}.{}", path.module(), name); - Suggestion { typ: Either::Right( - env.find_type(SymbolRef::new(&full_name[..])) + env.find_type(SymbolRef::new(module)) .cloned() .unwrap_or_else(|| Type::hole()), ), - name, } }), ); + + suggestions.sort_by(|l, r| l.name.cmp(&r.name)); + suggestions.dedup_by(|l, r| l.name == r.name); } } diff --git a/src/import.rs b/src/import.rs index 10ac988d3f..5c0ed17bf8 100644 --- a/src/import.rs +++ b/src/import.rs @@ -10,6 +10,7 @@ use std::path::PathBuf; use itertools::Itertools; +use base::filename_to_module; use base::ast::{expr_to_path, Expr, Literal, SpannedExpr, Typed, TypedIdent}; use base::fnv::FnvMap; use base::pos::{self, BytePos, Span}; @@ -21,7 +22,7 @@ use vm::{ExternLoader, ExternModule}; use vm::macros::{Error as MacroError, Macro, MacroExpander}; use vm::thread::{Thread, ThreadInternal}; -use super::{filename_to_module, Compiler}; +use super::Compiler; quick_error! { /// Error type for the import macro @@ -458,7 +459,9 @@ where .map_err(|err| Error::String(err.to_string()))?; modulename } - Expr::Literal(Literal::String(ref filename)) => filename_to_module(filename), + Expr::Literal(Literal::String(ref filename)) => { + format!("@{}", filename_to_module(filename)) + } _ => { return Err( Error::String("Expected a string literal or path to import".into()).into(), diff --git a/src/io.rs b/src/io.rs index 330d228a86..26d84b2805 100644 --- a/src/io.rs +++ b/src/io.rs @@ -200,7 +200,6 @@ fn load_script( WithVM { vm, value: name }: WithVM<&str>, expr: &str, ) -> PrimitiveFuture> { - let vm1 = vm.root_thread(); let vm = vm.root_thread(); let name = name.to_string(); diff --git a/src/lib.rs b/src/lib.rs index 157c9d5a71..5fe8fa8e77 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -49,6 +49,7 @@ use std::result::Result as StdResult; use std::string::String as StdString; use std::env; +use base::filename_to_module; use base::ast::{self, SpannedExpr}; use base::error::{Errors, InFile}; use base::metadata::Metadata; @@ -386,7 +387,7 @@ impl Compiler { &owned_import } }; - let module_name = Symbol::from(filename_to_module(filename)); + let module_name = Symbol::from(format!("@{}", filename_to_module(filename))); let mut macros = MacroExpander::new(vm); FutureValue::from( import @@ -550,18 +551,6 @@ let { error } = import! std.prim in () "#; -pub fn filename_to_module(filename: &str) -> StdString { - use std::path::Path; - let path = Path::new(filename); - let name = path.extension().map_or(filename, |ext| { - ext.to_str() - .map(|ext| &filename[..filename.len() - ext.len() - 1]) - .unwrap_or(filename) - }); - - format!("@{}", name.replace(|c: char| c == '/' || c == '\\', ".")) -} - #[derive(Default)] pub struct VmBuilder { event_loop: Option<::tokio_core::reactor::Remote>,