mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-22 19:42:31 +00:00
scoping all working and patterns too
Signed-off-by: faldor20 <eli.jambu@yahoo.com>
This commit is contained in:
parent
049c0e6358
commit
a988ee29ff
3 changed files with 238 additions and 164 deletions
|
@ -169,7 +169,7 @@ pub fn walk_decls<V: Visitor>(visitor: &mut V, decls: &Declarations) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn walk_decl<V: Visitor>(visitor: &mut V, decl: DeclarationInfo<'_>) {
|
pub fn walk_decl<V: Visitor>(visitor: &mut V, decl: DeclarationInfo<'_>) {
|
||||||
use DeclarationInfo::*;
|
use DeclarationInfo::*;
|
||||||
|
|
||||||
match decl {
|
match decl {
|
||||||
|
@ -968,74 +968,3 @@ pub fn find_declaration(symbol: Symbol, decls: &'_ Declarations) -> Option<Found
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
struct CompletionVisitor<'a, U, T> {
|
|
||||||
position: Position,
|
|
||||||
found_decls: Vec<T>,
|
|
||||||
state: &'a mut U,
|
|
||||||
processor: fn(&mut U, FoundDeclaration) -> T,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, U> Visitor for CompletionVisitor<'_, U, T> {
|
|
||||||
fn should_visit(&mut self, region: Region) -> bool {
|
|
||||||
region.contains_pos(self.position)
|
|
||||||
}
|
|
||||||
|
|
||||||
// fn visit_expr(&mut self, expr: &Expr, region: Region, var: Variable) {
|
|
||||||
// if region.contains_pos(self.position) {
|
|
||||||
// // self.region_typ = Some((region, var));
|
|
||||||
|
|
||||||
// walk_expr(self, expr, var);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn visit_pattern(&mut self, pat: &Pattern, region: Region, opt_var: Option<Variable>) {
|
|
||||||
// if region.contains_pos(self.position) {
|
|
||||||
// // if let Some(var) = opt_var {
|
|
||||||
// // self.region_typ = Some((region, var));
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// walk_pattern(self, pat);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
fn visit_decl(&mut self, decl: DeclarationInfo<'_>) {
|
|
||||||
match decl {
|
|
||||||
DeclarationInfo::Value { .. }
|
|
||||||
| DeclarationInfo::Function { .. }
|
|
||||||
| DeclarationInfo::Destructure { .. } => {
|
|
||||||
let res = (self.processor)(
|
|
||||||
self.state,
|
|
||||||
FoundDeclaration::Decl(unsafe { std::mem::transmute(decl.clone()) }),
|
|
||||||
);
|
|
||||||
self.found_decls.push(res);
|
|
||||||
walk_decl(self, decl);
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
walk_decl(self, decl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_def(&mut self, def: &Def) {
|
|
||||||
let res = ((self.processor)(
|
|
||||||
self.state,
|
|
||||||
FoundDeclaration::Def(unsafe { std::mem::transmute(def) }),
|
|
||||||
));
|
|
||||||
self.found_decls.push(res);
|
|
||||||
walk_def(self, def);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn get_completions<'a, U, T>(
|
|
||||||
position: Position,
|
|
||||||
decls: &'a Declarations,
|
|
||||||
state: &mut U,
|
|
||||||
processor: fn(&mut U, FoundDeclaration) -> T,
|
|
||||||
) -> Vec<T> {
|
|
||||||
let mut visitor = CompletionVisitor {
|
|
||||||
position,
|
|
||||||
found_decls: Vec::new(),
|
|
||||||
state,
|
|
||||||
processor,
|
|
||||||
};
|
|
||||||
visitor.visit_decls(decls);
|
|
||||||
visitor.found_decls
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,11 +5,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
use roc_can::{
|
use roc_can::{abilities::AbilitiesStore, expr::Declarations};
|
||||||
abilities::AbilitiesStore,
|
|
||||||
expr::Declarations,
|
|
||||||
traverse::{get_completions, DeclarationInfo, FoundDeclaration},
|
|
||||||
};
|
|
||||||
use roc_collections::MutMap;
|
use roc_collections::MutMap;
|
||||||
use roc_load::{CheckedModule, LoadedModule};
|
use roc_load::{CheckedModule, LoadedModule};
|
||||||
use roc_module::symbol::{Interns, ModuleId, Symbol};
|
use roc_module::symbol::{Interns, ModuleId, Symbol};
|
||||||
|
@ -25,7 +21,7 @@ use tower_lsp::lsp_types::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
analysis::completion::Completion,
|
analysis::completion::get_completions,
|
||||||
convert::{
|
convert::{
|
||||||
diag::{IntoLspDiagnostic, ProblemFmt},
|
diag::{IntoLspDiagnostic, ProblemFmt},
|
||||||
ToRange, ToRocPosition,
|
ToRange, ToRocPosition,
|
||||||
|
@ -454,19 +450,15 @@ impl AnalyzedDocument {
|
||||||
writeln!(&mut stderr, "prefix is: {:?}", symbol_prefix);
|
writeln!(&mut stderr, "prefix is: {:?}", symbol_prefix);
|
||||||
|
|
||||||
//TODO: to impliment record destructuring and other complex patterns i should pass in the completion item maker into this call and call it directly from the visitor
|
//TODO: to impliment record destructuring and other complex patterns i should pass in the completion item maker into this call and call it directly from the visitor
|
||||||
let mut completion = Completion {
|
|
||||||
subs,
|
|
||||||
interns,
|
|
||||||
module_id,
|
|
||||||
prefix: symbol_prefix,
|
|
||||||
};
|
|
||||||
let completions = get_completions(
|
let completions = get_completions(
|
||||||
position,
|
position,
|
||||||
&declarations,
|
declarations,
|
||||||
&mut completion,
|
subs,
|
||||||
Completion::maybe_complete,
|
symbol_prefix,
|
||||||
|
interns,
|
||||||
|
module_id,
|
||||||
);
|
);
|
||||||
writeln!(&mut stderr, "got completions: ");
|
writeln!(&mut stderr, "got completions: ");
|
||||||
Some(completions.into_iter().flatten().collect())
|
Some(completions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,96 @@
|
||||||
use std::io::Write;
|
use std::{io::Write, path::Prefix};
|
||||||
|
|
||||||
use roc_can::{
|
use roc_can::{
|
||||||
pattern::{Pattern, RecordDestruct},
|
def::Def,
|
||||||
traverse::{DeclarationInfo, FoundDeclaration},
|
expr::{Declarations, Expr, WhenBranch},
|
||||||
|
pattern::{Pattern, RecordDestruct, TupleDestruct},
|
||||||
|
traverse::{walk_decl, walk_def, walk_expr, DeclarationInfo, FoundDeclaration, Visitor},
|
||||||
};
|
};
|
||||||
use roc_module::symbol::{self, Interns, ModuleId, Symbol};
|
use roc_module::symbol::{self, Interns, ModuleId, Symbol};
|
||||||
use roc_region::all::Loc;
|
use roc_region::all::{Loc, Position, Region};
|
||||||
use roc_types::subs::{Subs, Variable};
|
use roc_types::subs::{Subs, Variable};
|
||||||
use tower_lsp::lsp_types::{CompletionItem, CompletionItemKind};
|
use tower_lsp::lsp_types::{CompletionItem, CompletionItemKind};
|
||||||
|
|
||||||
use crate::analysis::format_var_type;
|
use crate::analysis::format_var_type;
|
||||||
|
|
||||||
use super::AnalyzedModule;
|
pub struct CompletionVisitor<'a> {
|
||||||
pub(crate) struct Completion<'a> {
|
position: Position,
|
||||||
|
found_decls: Vec<CompletionItem>,
|
||||||
pub subs: &'a mut Subs,
|
pub subs: &'a mut Subs,
|
||||||
pub interns: &'a Interns,
|
pub interns: &'a Interns,
|
||||||
pub module_id: &'a ModuleId,
|
pub module_id: &'a ModuleId,
|
||||||
pub prefix: String,
|
pub prefix: String,
|
||||||
}
|
}
|
||||||
impl Completion<'_> {
|
|
||||||
pub fn make_completion_items(&mut self, found: Vec<FoundDeclaration>) -> Vec<CompletionItem> {
|
impl Visitor for CompletionVisitor<'_> {
|
||||||
|
fn should_visit(&mut self, region: Region) -> bool {
|
||||||
|
region.contains_pos(self.position)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_expr(&mut self, expr: &Expr, region: Region, var: Variable) {
|
||||||
|
if region.contains_pos(self.position) {
|
||||||
|
// self.region_typ = Some((region, var));
|
||||||
|
let mut res = self
|
||||||
|
.expression_defs(expr)
|
||||||
|
.into_iter()
|
||||||
|
.map(|(symbol, var)| {
|
||||||
|
self.make_completion_item(&symbol, &var, CompletionItemKind::VARIABLE)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
self.found_decls.append(&mut res);
|
||||||
|
|
||||||
|
walk_expr(self, expr, var);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fn visit_pattern(&mut self, pat: &Pattern, region: Region, opt_var: Option<Variable>) {
|
||||||
|
// if region.contains_pos(self.position) {
|
||||||
|
// // if let Some(var) = opt_var {
|
||||||
|
// // self.region_typ = Some((region, var));
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// walk_pattern(self, pat);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
fn visit_decl(&mut self, decl: DeclarationInfo<'_>) {
|
||||||
|
match decl {
|
||||||
|
DeclarationInfo::Value { loc_expr, .. }
|
||||||
|
| DeclarationInfo::Function {
|
||||||
|
loc_body: loc_expr, ..
|
||||||
|
}
|
||||||
|
| DeclarationInfo::Destructure { loc_expr, .. } => {
|
||||||
|
let mut res = self
|
||||||
|
.decl_to_completion_item(&decl)
|
||||||
|
.into_iter()
|
||||||
|
.map(|(symbol, var)| {
|
||||||
|
self.make_completion_item(&symbol, &var, CompletionItemKind::VARIABLE)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
self.found_decls.append(&mut res);
|
||||||
|
if loc_expr.region.contains_pos(self.position) {
|
||||||
|
walk_decl(self, decl);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
walk_decl(self, decl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_def(&mut self, def: &Def) {
|
||||||
|
let mut res = self
|
||||||
|
.extract_defs(def)
|
||||||
|
.into_iter()
|
||||||
|
.map(|(symbol, var)| {
|
||||||
|
self.make_completion_item(&symbol, &var, CompletionItemKind::VARIABLE)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
self.found_decls.append(&mut res);
|
||||||
|
walk_def(self, def);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl CompletionVisitor<'_> {
|
||||||
|
fn make_completion_items(&mut self, found: Vec<FoundDeclaration>) -> Vec<(Symbol, Variable)> {
|
||||||
found
|
found
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|comp| match comp {
|
.flat_map(|comp| match comp {
|
||||||
|
@ -27,31 +98,102 @@ impl Completion<'_> {
|
||||||
FoundDeclaration::Def(def) => def
|
FoundDeclaration::Def(def) => def
|
||||||
.pattern_vars
|
.pattern_vars
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(symbol, var)| self.make_completion_item_var(symbol, var))
|
.map(|(symbol, var)| (symbol.clone(), var.clone()))
|
||||||
.collect(),
|
.collect(),
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
pub fn maybe_complete(&mut self, found: FoundDeclaration) -> Vec<CompletionItem> {
|
fn extract_defs(&mut self, def: &Def) -> Vec<(Symbol, Variable)> {
|
||||||
let mut stderr = std::io::stderr();
|
let mut stderr = std::io::stderr();
|
||||||
writeln!(&mut stderr, "completion begin");
|
writeln!(&mut stderr, "completion begin");
|
||||||
match found {
|
def.pattern_vars
|
||||||
FoundDeclaration::Decl(dec) => self.decl_to_completion_item(&dec),
|
|
||||||
FoundDeclaration::Def(def) => def
|
|
||||||
.pattern_vars
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(symbol, var)| self.make_completion_item_var(symbol, var))
|
.map(|(symbol, var)| (symbol.clone(), var.clone()))
|
||||||
.collect(),
|
.collect()
|
||||||
}
|
}
|
||||||
|
fn expression_defs(&self, expr: &Expr) -> Vec<(Symbol, Variable)> {
|
||||||
|
match expr {
|
||||||
|
// Expr::Num(_, _, _, _) => todo!(),
|
||||||
|
// Expr::Int(_, _, _, _, _) => todo!(),
|
||||||
|
// Expr::Float(_, _, _, _, _) => todo!(),
|
||||||
|
// Expr::Str(_) => todo!(),
|
||||||
|
// Expr::SingleQuote(_, _, _, _) => todo!(),
|
||||||
|
// Expr::List { elem_var, loc_elems } => todo!(),
|
||||||
|
// Expr::IngestedFile(_, _, _) => todo!(),
|
||||||
|
// Expr::Var(_, _) => todo!(),
|
||||||
|
// Expr::AbilityMember(_, _, _) => todo!(),
|
||||||
|
Expr::When { loc_cond, cond_var, expr_var, region, branches, branches_cond_var, exhaustive } => {
|
||||||
|
|
||||||
|
let out:Vec<_> =
|
||||||
|
branches.iter().flat_map(|WhenBranch{ patterns, value, guard, redundant }|{
|
||||||
|
if value.region.contains_pos(self.position) {
|
||||||
|
patterns.iter().flat_map(|pattern|{
|
||||||
|
//We use the expression var here because if the pattern is an identifier then it must have the type of the expession given to the when is block
|
||||||
|
self.patterns(&pattern.pattern.value,expr_var)
|
||||||
|
|
||||||
|
}).collect()
|
||||||
}
|
}
|
||||||
fn record_destructs(&mut self, destructs: &Vec<Loc<RecordDestruct>>) -> Vec<CompletionItem> {
|
else{vec![]}
|
||||||
|
|
||||||
|
}).collect();
|
||||||
|
out
|
||||||
|
},
|
||||||
|
// Expr::If { cond_var, branch_var, branches, final_else } => todo!(),
|
||||||
|
_=>vec![]
|
||||||
|
// Expr::LetRec(_, _, _) => todo!(),
|
||||||
|
// Expr::LetNonRec(_, _) => todo!(),
|
||||||
|
// Expr::Call(_, _, _) => todo!(),
|
||||||
|
// Expr::RunLowLevel { op, args, ret_var } => todo!(),
|
||||||
|
// Expr::ForeignCall { foreign_symbol, args, ret_var } => todo!(),
|
||||||
|
// Expr::Closure(_) => todo!(),
|
||||||
|
// Expr::Record { record_var, fields } => todo!(),
|
||||||
|
// Expr::EmptyRecord => todo!(),
|
||||||
|
// Expr::Tuple { tuple_var, elems } => todo!(),
|
||||||
|
// Expr::Crash { msg, ret_var } => todo!(),
|
||||||
|
// Expr::RecordAccess { record_var, ext_var, field_var, loc_expr, field } => todo!(),
|
||||||
|
// Expr::RecordAccessor(_) => todo!(),
|
||||||
|
// Expr::TupleAccess { tuple_var, ext_var, elem_var, loc_expr, index } => todo!(),
|
||||||
|
// Expr::RecordUpdate { record_var, ext_var, symbol, updates } => todo!(),
|
||||||
|
// Expr::Tag { tag_union_var, ext_var, name, arguments } => todo!(),
|
||||||
|
// Expr::ZeroArgumentTag { closure_name, variant_var, ext_var, name } => todo!(),
|
||||||
|
// Expr::OpaqueRef { opaque_var, name, argument, specialized_def_type, type_arguments, lambda_set_variables } => todo!(),
|
||||||
|
// Expr::OpaqueWrapFunction(_) => todo!(),
|
||||||
|
// Expr::Expect { loc_condition, loc_continuation, lookups_in_cond } => todo!(),
|
||||||
|
// Expr::ExpectFx { loc_condition, loc_continuation, lookups_in_cond } => todo!(),
|
||||||
|
// Expr::Dbg { loc_message, loc_continuation, variable, symbol } => todo!(),
|
||||||
|
// Expr::TypedHole(_) => todo!(),
|
||||||
|
// Expr::RuntimeError(_) => todo!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
fn record_destructs(&self, destructs: &Vec<Loc<RecordDestruct>>) -> Vec<(Symbol, Variable)> {
|
||||||
destructs
|
destructs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|a| self.make_completion_item_var(&a.value.symbol, &a.value.var))
|
//TODO:I need to destructure value.typ here
|
||||||
|
.flat_map(|a| {
|
||||||
|
|
||||||
|
match &a.value.typ {
|
||||||
|
roc_can::pattern::DestructType::Required |
|
||||||
|
roc_can::pattern::DestructType::Optional(_, _) => vec![(a.value.symbol,a.value.var)],
|
||||||
|
roc_can::pattern::DestructType::Guard(var, pat) =>self.patterns(&pat.value,&var ) ,
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
fn tuple_destructs(&self, destructs: &Vec<Loc<TupleDestruct>>) -> Vec<(Symbol, Variable)> {
|
||||||
|
destructs
|
||||||
|
.iter()
|
||||||
|
//TODO:I need to destructure value.typ here
|
||||||
|
.flat_map(|a| {
|
||||||
|
let (var,pattern)=&a.value.typ;
|
||||||
|
self.patterns(&pattern.value,&var)
|
||||||
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_pattern(&mut self, as_pat: &Pattern, as_symbol: &Symbol) -> CompletionItem {
|
fn as_pattern(&self, as_pat: &Pattern, as_symbol: Symbol) -> (Symbol, Variable) {
|
||||||
let var = match as_pat {
|
let var = match as_pat {
|
||||||
Pattern::AppliedTag {
|
Pattern::AppliedTag {
|
||||||
whole_var,
|
whole_var,
|
||||||
|
@ -95,40 +237,50 @@ impl Completion<'_> {
|
||||||
// Pattern::MalformedPattern(_, _) => todo!(),
|
// Pattern::MalformedPattern(_, _) => todo!(),
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
};
|
};
|
||||||
self.make_completion_item_var(&as_symbol, &var)
|
(as_symbol, var.clone())
|
||||||
}
|
}
|
||||||
fn patterns(&mut self, pattern: &roc_can::pattern::Pattern) -> Vec<CompletionItem> {
|
fn patterns(&self, pattern: &roc_can::pattern::Pattern,var: &Variable) -> Vec<(Symbol, Variable)> {
|
||||||
match pattern {
|
match pattern {
|
||||||
// roc_can::pattern::Pattern::Identifier(symbol) => {
|
roc_can::pattern::Pattern::Identifier(symbol) => {
|
||||||
// todo!()
|
if self.is_match(symbol) {
|
||||||
// }
|
vec![(symbol.clone(),var.clone())]
|
||||||
roc_can::pattern::Pattern::As(pat, symbol) => {
|
|
||||||
vec![self.as_pattern(&pat.value, symbol)]
|
|
||||||
}
|
}
|
||||||
// roc_can::pattern::Pattern::AppliedTag {
|
else {vec![]}
|
||||||
|
}
|
||||||
|
// Pattern::AppliedTag {
|
||||||
// whole_var,
|
// whole_var,
|
||||||
// ext_var,
|
// ext_var,
|
||||||
// tag_name,
|
// tag_name,
|
||||||
// arguments,
|
// arguments,
|
||||||
// } => todo!(),
|
// } => whole_var,
|
||||||
// roc_can::pattern::Pattern::UnwrappedOpaque {
|
// Pattern::UnwrappedOpaque {
|
||||||
// whole_var,
|
// whole_var,
|
||||||
// opaque,
|
// opaque,
|
||||||
// argument,
|
// argument,
|
||||||
// specialized_def_type,
|
// specialized_def_type,
|
||||||
// type_arguments,
|
// type_arguments,
|
||||||
// lambda_set_variables,
|
// lambda_set_variables,
|
||||||
// } => todo!(),
|
// } => whole_var,
|
||||||
|
// Pattern::List {
|
||||||
|
// list_var,
|
||||||
|
// elem_var,
|
||||||
|
// patterns,
|
||||||
|
// } => list_var,
|
||||||
|
roc_can::pattern::Pattern::As(pat, symbol) => {
|
||||||
|
vec![self.as_pattern(&pat.value, symbol.clone())]
|
||||||
|
}
|
||||||
roc_can::pattern::Pattern::RecordDestructure {
|
roc_can::pattern::Pattern::RecordDestructure {
|
||||||
whole_var,
|
whole_var,
|
||||||
ext_var,
|
ext_var,
|
||||||
destructs,
|
destructs,
|
||||||
} => self.record_destructs(destructs),
|
} => self.record_destructs(destructs),
|
||||||
// roc_can::pattern::Pattern::TupleDestructure {
|
roc_can::pattern::Pattern::TupleDestructure {
|
||||||
// whole_var,
|
whole_var,
|
||||||
// ext_var,
|
ext_var,
|
||||||
// destructs,
|
destructs,
|
||||||
// } => todo!(),
|
} => {
|
||||||
|
self.tuple_destructs(destructs)
|
||||||
|
},
|
||||||
// roc_can::pattern::Pattern::List {
|
// roc_can::pattern::Pattern::List {
|
||||||
// list_var,
|
// list_var,
|
||||||
// elem_var,
|
// elem_var,
|
||||||
|
@ -161,61 +313,43 @@ impl Completion<'_> {
|
||||||
);
|
);
|
||||||
symbol.as_str(self.interns).starts_with(&self.prefix)
|
symbol.as_str(self.interns).starts_with(&self.prefix)
|
||||||
}
|
}
|
||||||
fn decl_to_completion_item(&mut self, decl: &DeclarationInfo) -> Vec<CompletionItem> {
|
fn decl_to_completion_item(&self, decl: &DeclarationInfo) -> Vec<(Symbol, Variable)> {
|
||||||
match decl {
|
match decl {
|
||||||
DeclarationInfo::Value {
|
DeclarationInfo::Value {
|
||||||
loc_symbol,
|
loc_symbol,
|
||||||
expr_var,
|
expr_var,
|
||||||
|
pattern,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if self.is_match(&loc_symbol.value) {
|
self.patterns(pattern,expr_var )
|
||||||
let mut stderr = std::io::stderr();
|
|
||||||
writeln!(&mut stderr, "match");
|
|
||||||
|
|
||||||
vec![self.make_completion_item(
|
|
||||||
&loc_symbol.value,
|
|
||||||
expr_var,
|
|
||||||
CompletionItemKind::VARIABLE,
|
|
||||||
)]
|
|
||||||
} else {
|
|
||||||
let mut stderr = std::io::stderr();
|
|
||||||
writeln!(&mut stderr, "non_match");
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
DeclarationInfo::Function {
|
DeclarationInfo::Function {
|
||||||
loc_symbol,
|
loc_symbol,
|
||||||
expr_var,
|
expr_var,
|
||||||
pattern,
|
pattern,
|
||||||
function,
|
function,
|
||||||
|
loc_body,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
|
let mut out: Vec<_> = vec![];
|
||||||
|
//append the function declaration
|
||||||
|
out.append(&mut self.patterns(pattern,expr_var));
|
||||||
|
|
||||||
|
if loc_body.region.contains_pos(self.position) {
|
||||||
|
//also add the arguments if we are inside the function
|
||||||
let mut args: Vec<_> = function
|
let mut args: Vec<_> = function
|
||||||
.value
|
.value
|
||||||
.arguments
|
.arguments
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|(var, _1, pat)| match pat.value {
|
.flat_map(|(var, _1, pat)| self.patterns(&pat.value,var),
|
||||||
Pattern::Identifier(symbol) => {
|
)
|
||||||
if self.is_match(&symbol) {
|
//We add in the pattern for the function declaration
|
||||||
vec![self.make_completion_item_var(&symbol, var)]
|
|
||||||
} else {
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => self.patterns(&pat.value),
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
if self.is_match(&loc_symbol.value) {
|
out.append(&mut args);
|
||||||
args.push(self.make_completion_item(
|
|
||||||
&loc_symbol.value,
|
|
||||||
expr_var,
|
|
||||||
CompletionItemKind::FUNCTION,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
args.append(&mut self.patterns(pattern));
|
out
|
||||||
args
|
|
||||||
}
|
}
|
||||||
DeclarationInfo::Destructure { loc_pattern, .. } => self.patterns(&loc_pattern.value),
|
DeclarationInfo::Destructure { loc_pattern,expr_var, .. } => self.patterns(&loc_pattern.value,expr_var),
|
||||||
DeclarationInfo::Expectation { .. } => vec![],
|
DeclarationInfo::Expectation { .. } => vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,3 +388,22 @@ impl Completion<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn get_completions<'a>(
|
||||||
|
position: Position,
|
||||||
|
decls: &'a Declarations,
|
||||||
|
subs: &mut Subs,
|
||||||
|
prefix: String,
|
||||||
|
interns: &Interns,
|
||||||
|
module_id: &ModuleId,
|
||||||
|
) -> Vec<CompletionItem> {
|
||||||
|
let mut visitor = CompletionVisitor {
|
||||||
|
position,
|
||||||
|
found_decls: Vec::new(),
|
||||||
|
subs,
|
||||||
|
interns,
|
||||||
|
module_id,
|
||||||
|
prefix,
|
||||||
|
};
|
||||||
|
visitor.visit_decls(decls);
|
||||||
|
visitor.found_decls
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue