Skip to content

Commit

Permalink
feat(completion): Return scoped symbols in the all_symbols query
Browse files Browse the repository at this point in the history
  • Loading branch information
Marwes committed Apr 4, 2019
1 parent b0e3ec4 commit 94a385a
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 27 deletions.
82 changes: 56 additions & 26 deletions completion/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -978,70 +978,100 @@ pub fn symbol(
completion(extract, source_span, expr, pos)
}

pub type SpCompletionSymbol<'a> = Spanned<CompletionSymbol<'a>, BytePos>;

#[derive(Debug, PartialEq)]
pub struct CompletionSymbol<'a> {
pub name: &'a Symbol,
pub content: CompletionSymbolContent<'a>,
pub children: Vec<SpCompletionSymbol<'a>>,
}

#[derive(Debug, PartialEq)]
pub enum CompletionSymbol<'a> {
pub enum CompletionSymbolContent<'a> {
Value {
name: &'a Symbol,
typ: &'a ArcType,
expr: &'a SpannedExpr<Symbol>,
},
Type {
name: &'a Symbol,
alias: &'a AliasData<Symbol, AstType<Symbol>>,
},
}

pub fn all_symbols(
source_span: Span<BytePos>,
expr: &SpannedExpr<Symbol>,
) -> Vec<Spanned<CompletionSymbol, BytePos>> {
) -> Vec<SpCompletionSymbol> {
struct AllIdents<'a> {
source_span: Span<BytePos>,
result: Vec<Spanned<CompletionSymbol<'a>, BytePos>>,
}

impl<'a> Visitor<'a> for AllIdents<'a> {
type Ident = Symbol;

fn visit_expr(&mut self, e: &'a SpannedExpr<Self::Ident>) {
if self.source_span.contains(e.span) {
match e.value {
Expr::TypeBindings(ref binds, _) => {
let source_span = self.source_span;
match &e.value {
Expr::TypeBindings(binds, expr) => {
self.result.extend(binds.iter().map(|bind| {
pos::spanned(
bind.name.span,
CompletionSymbol::Type {
CompletionSymbol {
name: &bind.name.value,
alias: &bind.alias.value,
content: CompletionSymbolContent::Type {
alias: &bind.alias.value,
},
children: Vec::new(),
},
)
}));

self.visit_expr(expr);
}
Expr::LetBindings(ref binds, _) => {
self.result
.extend(binds.iter().flat_map(|bind| match bind.name.value {
Pattern::Ident(ref id) => Some(pos::spanned(
Expr::LetBindings(binds, expr) => {
self.result.extend(binds.iter().flat_map(|bind| {
let children = idents_of(source_span, &bind.expr);
match bind.name.value {
Pattern::Ident(ref id) => vec![pos::spanned(
bind.name.span,
CompletionSymbol::Value {
CompletionSymbol {
name: &id.name,
typ: &id.typ,
expr: &bind.expr,
content: CompletionSymbolContent::Value {
typ: &id.typ,
expr: &bind.expr,
},
children,
},
)),
_ => None,
}))
)],
_ => children,
}
}));

self.visit_expr(expr);
}
_ => (),
_ => walk_expr(self, e),
}
} else {
walk_expr(self, e);
}
walk_expr(self, e)
}
}
let mut visitor = AllIdents {
source_span,
result: Vec::new(),
};
visitor.visit_expr(expr);
visitor.result

fn idents_of(
source_span: Span<BytePos>,
expr: &SpannedExpr<Symbol>,
) -> Vec<Spanned<CompletionSymbol, BytePos>> {
let mut visitor = AllIdents {
source_span,
result: Vec::new(),
};
visitor.visit_expr(expr);
visitor.result
}

idents_of(source_span, expr)
}

pub fn suggest<T>(
Expand Down
3 changes: 2 additions & 1 deletion completion/tests/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,8 @@ let { x, y } = { x = 1, y = 2 }

let symbols = completion::all_symbols(expr.span, &expr);

assert_eq!(symbols.len(), 4);
assert_eq!(symbols.len(), 3);
assert_eq!(symbols[1].value.children.len(), 1);
}

#[test]
Expand Down

0 comments on commit 94a385a

Please sign in to comment.