mirror of
https://github.com/roc-lang/roc.git
synced 2024-10-05 06:37:26 +03:00
Added formatting for module completion
This commit is contained in:
parent
c6f1b8b0b2
commit
76a2fd2fb0
@ -45,6 +45,7 @@ pub(super) struct AnalyzedModule {
|
||||
interns: Interns,
|
||||
subs: Subs,
|
||||
other_modules_subs: Arc<Mutex<HashMap<ModuleId, Subs>>>,
|
||||
modules_exposed: Arc<Mutex<HashMap<ModuleId, Arc<Vec<(Symbol, Variable)>>>>>,
|
||||
abilities: AbilitiesStore,
|
||||
declarations: Declarations,
|
||||
// We need this because ModuleIds are not stable between compilations, so a ModuleId visible to
|
||||
@ -139,10 +140,12 @@ pub(crate) fn global_analysis(doc_info: DocInfo) -> Vec<AnalyzedDocument> {
|
||||
})
|
||||
.collect();
|
||||
//Create a list
|
||||
let exposed: HashMap<_, _> = exposes
|
||||
.into_iter()
|
||||
.map(|(id, symbols)| (id, Arc::new(symbols)))
|
||||
.collect();
|
||||
let exposed = Arc::new(Mutex::new(
|
||||
exposes
|
||||
.into_iter()
|
||||
.map(|(id, symbols)| (id, Arc::new(symbols)))
|
||||
.collect::<HashMap<_, _>>(),
|
||||
));
|
||||
//Combine the subs from all modules
|
||||
let all_subs = Arc::new(Mutex::new(
|
||||
typechecked
|
||||
@ -240,7 +243,7 @@ struct AnalyzedDocumentBuilder<'a> {
|
||||
root_module: &'a mut Option<RootModule>,
|
||||
imports: &'a mut MutMap<ModuleId, MutSet<ModuleId>>,
|
||||
exposed_imports: HashMap<ModuleId, Vec<(Symbol, Variable)>>,
|
||||
exposed: HashMap<ModuleId, Arc<Vec<(Symbol, Variable)>>>,
|
||||
exposed: Arc<Mutex<HashMap<ModuleId, Arc<Vec<(Symbol, Variable)>>>>>,
|
||||
all_subs: Arc<Mutex<HashMap<ModuleId, Subs>>>,
|
||||
}
|
||||
|
||||
@ -266,7 +269,11 @@ impl<'a> AnalyzedDocumentBuilder<'a> {
|
||||
.map(|id| {
|
||||
(
|
||||
id,
|
||||
self.exposed.get(&id).unwrap_or(&Arc::new(vec![])).clone(),
|
||||
self.exposed
|
||||
.lock()
|
||||
.get(&id)
|
||||
.unwrap_or(&Arc::new(vec![]))
|
||||
.clone(),
|
||||
)
|
||||
})
|
||||
.collect::<HashMap<_, _>>();
|
||||
@ -296,6 +303,7 @@ impl<'a> AnalyzedDocumentBuilder<'a> {
|
||||
other_modules_subs: self.all_subs.clone(),
|
||||
interns: self.interns.clone(),
|
||||
module_id_to_url: self.module_id_to_url.clone(),
|
||||
modules_exposed: self.exposed.clone(),
|
||||
};
|
||||
|
||||
let line_info = LineInfo::new(&source);
|
||||
|
@ -226,9 +226,10 @@ impl AnalyzedDocument {
|
||||
subs,
|
||||
declarations,
|
||||
exposed_imports,
|
||||
aliases,
|
||||
|
||||
imports,
|
||||
other_modules_subs,
|
||||
modules_exposed,
|
||||
..
|
||||
} = self.module()?;
|
||||
|
||||
@ -250,6 +251,7 @@ impl AnalyzedDocument {
|
||||
interns,
|
||||
imports,
|
||||
other_modules_subs,
|
||||
modules_exposed,
|
||||
true,
|
||||
))
|
||||
} else {
|
||||
@ -276,6 +278,7 @@ impl AnalyzedDocument {
|
||||
interns,
|
||||
imports,
|
||||
other_modules_subs,
|
||||
modules_exposed,
|
||||
true,
|
||||
);
|
||||
Some(completions)
|
||||
|
@ -5,6 +5,7 @@ use parking_lot::Mutex;
|
||||
use roc_can::{
|
||||
def::Def,
|
||||
expr::{ClosureData, Declarations, Expr, WhenBranch},
|
||||
module::ExposedByModule,
|
||||
pattern::{ListPatterns, Pattern, RecordDestruct, TupleDestruct},
|
||||
traverse::{walk_decl, walk_def, walk_expr, DeclarationInfo, Visitor},
|
||||
};
|
||||
@ -15,9 +16,12 @@ use roc_types::{
|
||||
subs::{Subs, Variable},
|
||||
types::Alias,
|
||||
};
|
||||
use tower_lsp::lsp_types::{CompletionItem, CompletionItemKind};
|
||||
use tower_lsp::lsp_types::{
|
||||
CompletionItem, CompletionItemKind, Documentation, MarkupContent, MarkupKind,
|
||||
};
|
||||
|
||||
use super::utils::format_var_type;
|
||||
mod formatting;
|
||||
|
||||
pub struct CompletionVisitor<'a> {
|
||||
position: Position,
|
||||
@ -294,7 +298,6 @@ fn make_completion_item(
|
||||
label: str,
|
||||
detail: Some(type_str),
|
||||
kind: Some(typ),
|
||||
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
@ -327,37 +330,47 @@ pub fn get_upper_case_completion_items(
|
||||
interns: &Interns,
|
||||
imported_modules: &HashMap<ModuleId, Arc<Vec<(Symbol, Variable)>>>,
|
||||
all_subs: &Mutex<HashMap<ModuleId, Subs>>,
|
||||
modules_exposed: &Mutex<HashMap<ModuleId, Arc<Vec<(Symbol, Variable)>>>>,
|
||||
just_modules: bool,
|
||||
) -> Vec<CompletionItem> {
|
||||
//TODO! use a proper completion type instead of simple
|
||||
|
||||
let module_completions = imported_modules.iter().flat_map(|(mod_id, vars)| {
|
||||
let mod_name = mod_id.to_ident_str(interns).to_string();
|
||||
|
||||
if mod_name.starts_with(&prefix) {
|
||||
let item = CompletionItem {
|
||||
label: mod_name.clone(),
|
||||
kind: Some(CompletionItemKind::MODULE),
|
||||
detail: Some(format!("`{0}` module", mod_name)),
|
||||
documentation: Some(formatting::module_documentation(
|
||||
formatting::DescripitonType::Exposes,
|
||||
mod_id,
|
||||
&mod_name,
|
||||
interns,
|
||||
imported_modules,
|
||||
all_subs,
|
||||
modules_exposed,
|
||||
)),
|
||||
..Default::default()
|
||||
};
|
||||
vec![item]
|
||||
} else if prefix.starts_with(&mod_name) {
|
||||
//Complete dot completions
|
||||
} else if prefix.starts_with(&(mod_name + ".")) {
|
||||
vars.clone()
|
||||
.iter()
|
||||
.map(|(sym, var)| {
|
||||
//TODO! I need to get subs from the module we are completing from
|
||||
let detail = all_subs
|
||||
all_subs
|
||||
.lock()
|
||||
.get_mut(mod_id)
|
||||
.map(|subs| format_var_type(*var, subs, module_id, interns))
|
||||
.unwrap();
|
||||
|
||||
CompletionItem {
|
||||
label: sym.as_str(interns).to_string(),
|
||||
kind: Some(CompletionItemKind::MODULE),
|
||||
detail: Some(detail),
|
||||
..Default::default()
|
||||
}
|
||||
.map(|subs| {
|
||||
make_completion_item(
|
||||
subs,
|
||||
mod_id,
|
||||
interns,
|
||||
sym.as_str(interns).to_string(),
|
||||
*var,
|
||||
)
|
||||
})
|
||||
.expect("Couldn't find subs for module during completion.")
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
} else {
|
||||
|
70
crates/lang_srv/src/analysis/completion/formatting.rs
Normal file
70
crates/lang_srv/src/analysis/completion/formatting.rs
Normal file
@ -0,0 +1,70 @@
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use parking_lot::Mutex;
|
||||
use roc_module::symbol::{Interns, ModuleId, Symbol};
|
||||
use roc_types::subs::{Subs, Variable};
|
||||
use tower_lsp::lsp_types::{Documentation, MarkupContent, MarkupKind};
|
||||
|
||||
use crate::analysis::utils::format_var_type;
|
||||
|
||||
fn module_exposed_list(
|
||||
module_id: &ModuleId,
|
||||
interns: &Interns,
|
||||
imported_modules: &HashMap<ModuleId, Arc<Vec<(Symbol, Variable)>>>,
|
||||
all_subs: &Mutex<HashMap<ModuleId, Subs>>,
|
||||
modules_exposed: &Mutex<HashMap<ModuleId, Arc<Vec<(Symbol, Variable)>>>>,
|
||||
) -> Option<std::string::String> {
|
||||
modules_exposed.lock().get(module_id).and_then(|exposed| {
|
||||
all_subs.lock().get_mut(module_id).map(|subs| {
|
||||
let items = exposed
|
||||
.iter()
|
||||
.map(|(symb, var)| {
|
||||
let var_str = format_var_type(*var, subs, module_id, interns);
|
||||
format!(" {0}: {1}", symb.as_str(interns), var_str)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
format!("{{\n{0}\n}}", items.join(",\n"))
|
||||
})
|
||||
})
|
||||
}
|
||||
pub enum DescripitonType {
|
||||
Name,
|
||||
Exposes,
|
||||
NameAndExposes,
|
||||
}
|
||||
fn md_doc(val: String) -> Documentation {
|
||||
Documentation::MarkupContent(MarkupContent {
|
||||
kind: MarkupKind::Markdown,
|
||||
value: val,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn module_documentation(
|
||||
description_type: DescripitonType,
|
||||
module_id: &ModuleId,
|
||||
mod_name: &String,
|
||||
interns: &Interns,
|
||||
imported_modules: &HashMap<ModuleId, Arc<Vec<(Symbol, Variable)>>>,
|
||||
all_subs: &Mutex<HashMap<ModuleId, Subs>>,
|
||||
modules_exposed: &Mutex<HashMap<ModuleId, Arc<Vec<(Symbol, Variable)>>>>,
|
||||
) -> Documentation {
|
||||
let exposed = || {
|
||||
module_exposed_list(
|
||||
module_id,
|
||||
interns,
|
||||
imported_modules,
|
||||
all_subs,
|
||||
modules_exposed,
|
||||
)
|
||||
.unwrap_or_default()
|
||||
};
|
||||
|
||||
match description_type {
|
||||
DescripitonType::Name => md_doc(format!("{0} module", mod_name)),
|
||||
DescripitonType::Exposes => md_doc(format!("```roc\n{0}\n```", exposed())),
|
||||
DescripitonType::NameAndExposes => {
|
||||
md_doc(format!("{0}\n```roc\n{1}\n```", mod_name, exposed()))
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user