mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 14:13:52 +01:00
improve support for #include in language server
This commit is contained in:
parent
2e6c6940d4
commit
d3164254b3
@ -27,7 +27,6 @@ async fn main() {
|
|||||||
|
|
||||||
struct Backend {
|
struct Backend {
|
||||||
client: Client,
|
client: Client,
|
||||||
main_document: Arc<Mutex<Option<tower_lsp::lsp_types::Url>>>,
|
|
||||||
current_document: Arc<Mutex<Option<tower_lsp::lsp_types::Url>>>,
|
current_document: Arc<Mutex<Option<tower_lsp::lsp_types::Url>>>,
|
||||||
documents: Arc<Mutex<HashMap<tower_lsp::lsp_types::Url, TextDocumentItem>>>,
|
documents: Arc<Mutex<HashMap<tower_lsp::lsp_types::Url, TextDocumentItem>>>,
|
||||||
last_compiled: Arc<Mutex<Option<ParseCompileCheckResult>>>,
|
last_compiled: Arc<Mutex<Option<ParseCompileCheckResult>>>,
|
||||||
@ -36,7 +35,6 @@ impl Backend {
|
|||||||
pub fn new(client: Client) -> Self {
|
pub fn new(client: Client) -> Self {
|
||||||
Self {
|
Self {
|
||||||
client,
|
client,
|
||||||
main_document: Arc::new(Mutex::new(None)),
|
|
||||||
current_document: Arc::new(Mutex::new(None)),
|
current_document: Arc::new(Mutex::new(None)),
|
||||||
documents: Arc::new(Mutex::new(HashMap::new())),
|
documents: Arc::new(Mutex::new(HashMap::new())),
|
||||||
last_compiled: Arc::new(Mutex::new(None)),
|
last_compiled: Arc::new(Mutex::new(None)),
|
||||||
@ -47,10 +45,10 @@ impl Backend {
|
|||||||
#[tower_lsp::async_trait]
|
#[tower_lsp::async_trait]
|
||||||
impl LanguageServer for Backend {
|
impl LanguageServer for Backend {
|
||||||
async fn did_open(&self, p: DidOpenTextDocumentParams) {
|
async fn did_open(&self, p: DidOpenTextDocumentParams) {
|
||||||
*self.last_compiled.lock().await = None;
|
{
|
||||||
let mut md = self.main_document.lock().await;
|
let mut md = self.current_document.lock().await;
|
||||||
if md.is_none() {
|
|
||||||
*md = Some(p.text_document.uri.clone());
|
*md = Some(p.text_document.uri.clone());
|
||||||
|
*self.last_compiled.lock().await = None;
|
||||||
}
|
}
|
||||||
self.documents
|
self.documents
|
||||||
.lock()
|
.lock()
|
||||||
@ -58,7 +56,11 @@ impl LanguageServer for Backend {
|
|||||||
.insert(p.text_document.uri.clone(), p.text_document);
|
.insert(p.text_document.uri.clone(), p.text_document);
|
||||||
}
|
}
|
||||||
async fn did_change(&self, p: DidChangeTextDocumentParams) {
|
async fn did_change(&self, p: DidChangeTextDocumentParams) {
|
||||||
|
{
|
||||||
|
let mut md = self.current_document.lock().await;
|
||||||
|
*md = Some(p.text_document.uri.clone());
|
||||||
*self.last_compiled.lock().await = None;
|
*self.last_compiled.lock().await = None;
|
||||||
|
}
|
||||||
if let Some(document) = self.documents.lock().await.get_mut(&p.text_document.uri) {
|
if let Some(document) = self.documents.lock().await.get_mut(&p.text_document.uri) {
|
||||||
for change in p.content_changes {
|
for change in p.content_changes {
|
||||||
if let Some(_range) = change.range {
|
if let Some(_range) = change.range {
|
||||||
@ -113,18 +115,22 @@ impl LanguageServer for Backend {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn hover(&self, params: HoverParams) -> tower_lsp::jsonrpc::Result<Option<Hover>> {
|
async fn hover(&self, p: HoverParams) -> tower_lsp::jsonrpc::Result<Option<Hover>> {
|
||||||
|
{
|
||||||
|
let mut md = self.current_document.lock().await;
|
||||||
|
*md = Some(p.text_document_position_params.text_document.uri.clone());
|
||||||
*self.last_compiled.lock().await = None;
|
*self.last_compiled.lock().await = None;
|
||||||
|
}
|
||||||
let byte_pos = {
|
let byte_pos = {
|
||||||
match self.main_document.lock().await.as_ref() {
|
match self.current_document.lock().await.as_ref() {
|
||||||
Some(uri) => {
|
Some(uri) => {
|
||||||
let doc = self.documents.lock().await;
|
let doc = self.documents.lock().await;
|
||||||
let doc = doc.get(uri);
|
let doc = doc.get(uri);
|
||||||
let doc = doc.map(|doc| doc.text.as_str()).unwrap_or("");
|
let doc = doc.map(|doc| doc.text.as_str()).unwrap_or("");
|
||||||
let pos_in_og = get_byte_pos_in_og(
|
let pos_in_og = get_byte_pos_in_og(
|
||||||
doc,
|
doc,
|
||||||
params.text_document_position_params.position.line as _,
|
p.text_document_position_params.position.line as _,
|
||||||
params.text_document_position_params.position.character as _,
|
p.text_document_position_params.position.character as _,
|
||||||
);
|
);
|
||||||
Some(
|
Some(
|
||||||
mers_lib::prelude_compile::Source::new_from_string(doc.to_owned())
|
mers_lib::prelude_compile::Source::new_from_string(doc.to_owned())
|
||||||
@ -250,10 +256,17 @@ impl LanguageServer for Backend {
|
|||||||
|
|
||||||
async fn code_action(
|
async fn code_action(
|
||||||
&self,
|
&self,
|
||||||
params: CodeActionParams,
|
p: CodeActionParams,
|
||||||
) -> tower_lsp::jsonrpc::Result<Option<CodeActionResponse>> {
|
) -> tower_lsp::jsonrpc::Result<Option<CodeActionResponse>> {
|
||||||
|
{
|
||||||
|
let mut md = self.current_document.lock().await;
|
||||||
|
if !md.as_ref().is_some_and(|md| *md == p.text_document.uri) {
|
||||||
|
*md = Some(p.text_document.uri.clone());
|
||||||
|
*self.last_compiled.lock().await = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
Ok(Some(
|
Ok(Some(
|
||||||
if let Some(doc) = self.documents.lock().await.get(¶ms.text_document.uri) {
|
if let Some(doc) = self.documents.lock().await.get(&p.text_document.uri) {
|
||||||
let mut src = mers_lib::prelude_compile::Source::new_from_string(doc.text.clone());
|
let mut src = mers_lib::prelude_compile::Source::new_from_string(doc.text.clone());
|
||||||
let srca = Arc::new(src.clone());
|
let srca = Arc::new(src.clone());
|
||||||
match mers_lib::prelude_compile::parse(&mut src, &srca) {
|
match mers_lib::prelude_compile::parse(&mut src, &srca) {
|
||||||
@ -262,16 +275,16 @@ impl LanguageServer for Backend {
|
|||||||
let pos_start = srca.pos_from_og(
|
let pos_start = srca.pos_from_og(
|
||||||
get_byte_pos_in_og(
|
get_byte_pos_in_og(
|
||||||
srca.src_og(),
|
srca.src_og(),
|
||||||
params.range.start.line as _,
|
p.range.start.line as _,
|
||||||
params.range.start.character as _,
|
p.range.start.character as _,
|
||||||
),
|
),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
let pos_end = srca.pos_from_og(
|
let pos_end = srca.pos_from_og(
|
||||||
get_byte_pos_in_og(
|
get_byte_pos_in_og(
|
||||||
srca.src_og(),
|
srca.src_og(),
|
||||||
params.range.end.line as _,
|
p.range.end.line as _,
|
||||||
params.range.end.character as _,
|
p.range.end.character as _,
|
||||||
),
|
),
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
@ -322,7 +335,7 @@ impl LanguageServer for Backend {
|
|||||||
TextDocumentEdit {
|
TextDocumentEdit {
|
||||||
text_document:
|
text_document:
|
||||||
OptionalVersionedTextDocumentIdentifier {
|
OptionalVersionedTextDocumentIdentifier {
|
||||||
uri: params.text_document.uri.clone(),
|
uri: p.text_document.uri.clone(),
|
||||||
version: None,
|
version: None,
|
||||||
},
|
},
|
||||||
edits: vec![OneOf::Left(TextEdit {
|
edits: vec![OneOf::Left(TextEdit {
|
||||||
@ -437,7 +450,7 @@ impl Backend {
|
|||||||
let mut last_compiled = self.last_compiled.lock().await;
|
let mut last_compiled = self.last_compiled.lock().await;
|
||||||
if last_compiled.is_none() {
|
if last_compiled.is_none() {
|
||||||
*last_compiled = Some(
|
*last_compiled = Some(
|
||||||
if let Some(source) = self.main_document.lock().await.clone() {
|
if let Some(source) = self.current_document.lock().await.clone() {
|
||||||
if let Some(document) = self.documents.lock().await.get(&source) {
|
if let Some(document) = self.documents.lock().await.get(&source) {
|
||||||
let src_from = match document.uri.to_file_path() {
|
let src_from = match document.uri.to_file_path() {
|
||||||
Ok(path) => mers_lib::parsing::SourceFrom::File(path),
|
Ok(path) => mers_lib::parsing::SourceFrom::File(path),
|
||||||
|
@ -27,8 +27,10 @@ impl MersStatement for IncludeMers {
|
|||||||
info: &mut info::Info<super::Local>,
|
info: &mut info::Info<super::Local>,
|
||||||
comp: CompInfo,
|
comp: CompInfo,
|
||||||
) -> Result<Box<dyn program::run::MersStatement>, CheckError> {
|
) -> Result<Box<dyn program::run::MersStatement>, CheckError> {
|
||||||
|
let mut inc_info = info.duplicate();
|
||||||
|
inc_info.global.enable_hooks = false;
|
||||||
let compiled: Arc<Box<dyn crate::program::run::MersStatement>> =
|
let compiled: Arc<Box<dyn crate::program::run::MersStatement>> =
|
||||||
match self.include.compile(&mut info.duplicate(), comp) {
|
match self.include.compile(&mut inc_info, comp) {
|
||||||
Ok(v) => Arc::new(v),
|
Ok(v) => Arc::new(v),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(CheckError::new()
|
return Err(CheckError::new()
|
||||||
|
@ -26,8 +26,11 @@ impl MersStatement for Chain {
|
|||||||
if init_to.is_some() {
|
if init_to.is_some() {
|
||||||
return Err("can't init to statement type Chain".to_string().into());
|
return Err("can't init to statement type Chain".to_string().into());
|
||||||
}
|
}
|
||||||
|
let prev_enable_hooks = info.global.enable_hooks;
|
||||||
|
info.global.enable_hooks = false;
|
||||||
let arg = self.first.check(info, None)?;
|
let arg = self.first.check(info, None)?;
|
||||||
let func = self.chained.check(info, None)?;
|
let func = self.chained.check(info, None)?;
|
||||||
|
info.global.enable_hooks = prev_enable_hooks;
|
||||||
let mut o = Type::empty();
|
let mut o = Type::empty();
|
||||||
for func in &func.types {
|
for func in &func.types {
|
||||||
if let Some(func) = func
|
if let Some(func) = func
|
||||||
|
Loading…
Reference in New Issue
Block a user