Skip to content

Commit e54057d

Browse files
authored
fix(LSP): don't crash on broken function definition (#9441)
1 parent b7273d7 commit e54057d

File tree

2 files changed

+65
-3
lines changed

2 files changed

+65
-3
lines changed

compiler/noirc_frontend/src/parser/parser.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,12 @@ impl<'a> Parser<'a> {
220220
}
221221
},
222222
Some(Err(lexer_error)) => self.errors.push(lexer_error.into()),
223-
None => return (eof_located_token(), last_comments),
223+
None => {
224+
let end_span = Span::single_char(self.current_token_location.span.end());
225+
let end_location = Location::new(end_span, self.current_token_location.file);
226+
let end_token = LocatedToken::new(Token::EOF, end_location);
227+
return (end_token, last_comments);
228+
}
224229
}
225230
}
226231
}

tooling/lsp/src/requests/document_symbol.rs

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -509,14 +509,49 @@ impl Visitor for DocumentSymbolCollector<'_> {
509509

510510
#[cfg(test)]
511511
mod document_symbol_tests {
512-
use crate::test_utils;
512+
use crate::{notifications::on_did_open_text_document, test_utils};
513513

514514
use super::*;
515515
use async_lsp::lsp_types::{
516-
PartialResultParams, Range, SymbolKind, TextDocumentIdentifier, WorkDoneProgressParams,
516+
DidOpenTextDocumentParams, PartialResultParams, Range, SymbolKind, TextDocumentIdentifier,
517+
TextDocumentItem, WorkDoneProgressParams,
517518
};
518519
use tokio::test;
519520

521+
async fn get_document_symbols(src: &str) -> Vec<DocumentSymbol> {
522+
let (mut state, noir_text_document) = test_utils::init_lsp_server("document_symbol").await;
523+
524+
let _ = on_did_open_text_document(
525+
&mut state,
526+
DidOpenTextDocumentParams {
527+
text_document: TextDocumentItem {
528+
uri: noir_text_document.clone(),
529+
language_id: "noir".to_string(),
530+
version: 0,
531+
text: src.to_string(),
532+
},
533+
},
534+
);
535+
536+
let response = on_document_symbol_request(
537+
&mut state,
538+
DocumentSymbolParams {
539+
text_document: TextDocumentIdentifier { uri: noir_text_document },
540+
work_done_progress_params: WorkDoneProgressParams { work_done_token: None },
541+
partial_result_params: PartialResultParams { partial_result_token: None },
542+
},
543+
)
544+
.await
545+
.expect("Could not execute on_document_symbol_request")
546+
.unwrap();
547+
548+
let DocumentSymbolResponse::Nested(symbols) = response else {
549+
panic!("Expected response to be nested");
550+
};
551+
552+
symbols
553+
}
554+
520555
#[test]
521556
async fn test_document_symbol() {
522557
let (mut state, noir_text_document) = test_utils::init_lsp_server("document_symbol").await;
@@ -752,4 +787,26 @@ mod document_symbol_tests {
752787
]
753788
);
754789
}
790+
791+
#[test]
792+
async fn test_function_with_just_open_parentheses() {
793+
let src = "fn main(\n";
794+
let mut symbols = get_document_symbols(src).await;
795+
assert_eq!(symbols.len(), 1);
796+
let symbol = symbols.remove(0);
797+
assert_eq!(
798+
symbol.range,
799+
Range {
800+
start: Position { line: 0, character: 0 },
801+
end: Position { line: 1, character: 0 },
802+
}
803+
);
804+
assert_eq!(
805+
symbol.selection_range,
806+
Range {
807+
start: Position { line: 0, character: 3 },
808+
end: Position { line: 0, character: 7 },
809+
}
810+
);
811+
}
755812
}

0 commit comments

Comments
 (0)