Skip to content

Commit

Permalink
Provide the types for completed import modules
Browse files Browse the repository at this point in the history
  • Loading branch information
Marwes committed Dec 6, 2017
1 parent 6e791ec commit 740de56
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 19 deletions.
5 changes: 5 additions & 0 deletions base/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@ impl Symbol {
}

impl SymbolRef {
#[inline]
pub fn new<N: ?Sized + AsRef<str>>(n: &N) -> &SymbolRef {
unsafe { ::std::mem::transmute::<&Name, &SymbolRef>(Name::new(n)) }
}

/// Checks whether the names of two symbols are equal
pub fn name_eq(&self, other: &SymbolRef) -> bool {
self.name() == other.name()
Expand Down
34 changes: 17 additions & 17 deletions completion/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use base::metadata::Metadata;
use base::resolve;
use base::pos::{self, BytePos, HasSpan, Span, Spanned, NO_EXPANSION};
use base::scoped_map::ScopedMap;
use base::symbol::Symbol;
use base::symbol::{Name, Symbol, SymbolRef};
use base::types::{walk_type_, AliasData, ArcType, ControlVisitation, Generic, Type, TypeEnv};

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -970,7 +970,7 @@ impl SuggestionQuery {
Match::Expr(expr) => match expr.value {
Expr::Ident(ref id) if id.name.is_global() => {
let name = &id.name.as_ref()[1..];
self.suggest_module_import(name, &mut result);
self.suggest_module_import(env, name, &mut result);
}
_ => {
result.extend(expr_iter(&suggest.stack, expr).map(|(k, typ)| {
Expand Down Expand Up @@ -1026,7 +1026,7 @@ impl SuggestionQuery {
}));
}
Expr::Ident(ref id) if id.name.is_global() => {
self.suggest_module_import(&id.name.as_ref()[1..], &mut result);
self.suggest_module_import(env, &id.name.as_ref()[1..], &mut result);
}
_ => (),
},
Expand Down Expand Up @@ -1113,24 +1113,19 @@ impl SuggestionQuery {
result
}

fn suggest_module_import(&self, path: &str, suggestions: &mut Vec<Suggestion>) {
fn suggest_module_import<T>(&self, env: &T, path: &str, suggestions: &mut Vec<Suggestion>)
where
T: TypeEnv,
{
use std::ffi::OsStr;
let path = Name::new(path);

let path = path.replace(".", "/");
let (base, prefix) = if path.ends_with('/') {
(Path::new(&path[..]), "")
} else {
let base = Path::new(&path[..]).parent().unwrap_or(Path::new(""));
let prefix = Path::new(&path[..])
.file_name()
.and_then(|os_str| os_str.to_str())
.unwrap_or("");
(base, prefix)
};
let base = PathBuf::from(path.module().as_str().replace(".", "/"));
let prefix = path.declared_name();

let mut module_prefixes = self.paths
.iter()
.map(|root| root.join(base))
.map(|root| root.join(&*base))
.flat_map(|root| {
walkdir::WalkDir::new(&*root)
.into_iter()
Expand Down Expand Up @@ -1164,9 +1159,14 @@ impl SuggestionQuery {
.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[..]))
.cloned()
.unwrap_or_else(|| Type::hole()),
),
name,
typ: Either::Right(Type::hole()),
}
}),
);
Expand Down
30 changes: 30 additions & 0 deletions completion/tests/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,36 @@ import! std.
);
}

#[test]
fn suggest_module_import_typed() {
let _ = env_logger::init();

let text = r#"
import! std.prelud
"#;
let query = SuggestionQuery {
paths: vec![find_gluon_root()],
};
let result = suggest_query(
query,
text,
Source::new(text)
.lines()
.offset(1.into(), 12.into())
.expect("Position is not in source"),
);
assert!(result.is_ok());

let expected = Ok(vec![
Suggestion {
name: "prelude".into(),
typ: Either::Right(Type::int()),
},
]);

assert_eq!(result, expected);
}

#[test]
fn dont_suggest_variant_at_record_field() {
let _ = env_logger::init();
Expand Down
4 changes: 4 additions & 0 deletions completion/tests/support/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub fn parse_new(

pub struct MockEnv {
bool: Alias<Symbol, ArcType>,
int: ArcType,
}

impl MockEnv {
Expand All @@ -53,6 +54,7 @@ impl MockEnv {

MockEnv {
bool: Alias::new(bool_sym, bool_ty),
int: Type::int(),
}
}
}
Expand All @@ -70,6 +72,8 @@ impl TypeEnv for MockEnv {
fn find_type(&self, id: &SymbolRef) -> Option<&ArcType> {
match id.definition_name() {
"False" | "True" => Some(&self.bool.as_type()),
// Just need a dummy type that is not `Type::hole` to verify that lookups work
"std.prelude" => Some(&self.int),
_ => None,
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ where
// that we can do completion on the name
let mut modulename = None;
self.expand_(macros, args, &mut modulename)
.or_else(|err| match modulename {
.or_else(move |err| match modulename {
None => Err(err),
Some(modulename) => {
macros.errors.push(pos::spanned(args[0].span, err));
Expand Down
2 changes: 1 addition & 1 deletion tests/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,7 @@ fn deep_clone_partial_application() {
let memory_for_closures = child.context().gc.allocated_memory();

vm.set_global(
Symbol::from("test"),
Symbol::from("@test"),
Type::hole(),
Metadata::default(),
unsafe { result.unwrap().0.get_value() },
Expand Down

0 comments on commit 740de56

Please sign in to comment.