Skip to content

Commit

Permalink
feat(service): report top-level error tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
g-plane committed Jan 8, 2025
1 parent c012363 commit 16fcb3f
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 5 deletions.
4 changes: 3 additions & 1 deletion crates/service/src/checker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod immediates;
mod implicit_module;
mod multi_modules;
mod shadow;
mod syntax;
mod typeck;
mod undef;
mod unknown_instr;
Expand All @@ -19,7 +20,8 @@ pub fn check(service: &LanguageService, uri: InternUri) -> Vec<Diagnostic> {
let symbol_table = service.symbol_table(uri);
let config = &service.get_config(uri);

let mut diagnostics = service.parser_result(uri).1;
let mut diagnostics = Vec::with_capacity(4);
syntax::check(service, &mut diagnostics, uri, &line_index, &root);
root.descendants().for_each(|node| match node.kind() {
SyntaxKind::ROOT => {
multi_modules::check(&mut diagnostics, &line_index, &node);
Expand Down
33 changes: 33 additions & 0 deletions crates/service/src/checker/syntax.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use crate::{files::FilesCtx, helpers, InternUri, LanguageService};
use line_index::LineIndex;
use lsp_types::{Diagnostic, DiagnosticSeverity, NumberOrString};
use std::rc::Rc;
use wat_syntax::{SyntaxElement, SyntaxKind, SyntaxNode};

const DIAGNOSTIC_CODE: &str = "syntax";

pub fn check(
service: &LanguageService,
diags: &mut Vec<Diagnostic>,
uri: InternUri,
line_index: &LineIndex,
root: &SyntaxNode,
) {
let mut errors = Rc::unwrap_or_clone(service.parser_result(uri).1);
diags.append(&mut errors);
diags.extend(
root.children_with_tokens()
.filter_map(|element| match element {
SyntaxElement::Token(token) if token.kind() == SyntaxKind::ERROR => Some(token),
_ => None,
})
.map(|token| Diagnostic {
range: helpers::rowan_range_to_lsp_range(line_index, token.text_range()),
severity: Some(DiagnosticSeverity::ERROR),
source: Some("wat".into()),
code: Some(NumberOrString::String(DIAGNOSTIC_CODE.into())),
message: "syntax error: unexpected token".into(),
..Default::default()
}),
);
}
6 changes: 3 additions & 3 deletions crates/service/src/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub(crate) trait FilesCtx: salsa::Database {

#[salsa::memoized]
#[salsa::invoke(parse)]
fn parser_result(&self, uri: InternUri) -> (GreenNode, Vec<Diagnostic>);
fn parser_result(&self, uri: InternUri) -> (GreenNode, Rc<Vec<Diagnostic>>);

#[salsa::memoized]
fn root(&self, uri: InternUri) -> GreenNode;
Expand All @@ -29,7 +29,7 @@ fn get_line_index(db: &dyn FilesCtx, uri: InternUri) -> Rc<LineIndex> {
Rc::new(LineIndex::new(&db.source(uri)))
}

fn parse(db: &dyn FilesCtx, uri: InternUri) -> (GreenNode, Vec<Diagnostic>) {
fn parse(db: &dyn FilesCtx, uri: InternUri) -> (GreenNode, Rc<Vec<Diagnostic>>) {
let source = db.source(uri);
let line_index = db.line_index(uri);
let mut parser = Parser::new(&source);
Expand Down Expand Up @@ -60,7 +60,7 @@ fn parse(db: &dyn FilesCtx, uri: InternUri) -> (GreenNode, Vec<Diagnostic>) {
}
})
.collect();
(green, syntax_errors)
(green, Rc::new(syntax_errors))
}

fn root(db: &dyn FilesCtx, uri: InternUri) -> GreenNode {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
source: crates/service/tests/diagnostics/syntax.rs
expression: response
---
{
"kind": "full",
"items": [
{
"range": {
"start": {
"line": 0,
"character": 8
},
"end": {
"line": 0,
"character": 9
}
},
"severity": 1,
"code": "syntax",
"source": "wat",
"message": "syntax error: unexpected token"
}
]
}
11 changes: 11 additions & 0 deletions crates/service/tests/diagnostics/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,14 @@ fn blocks() {
let response = service.pull_diagnostics(create_params(uri));
assert_json_snapshot!(response);
}

#[test]
fn top_level_error_token() {
let uri = "untitled:test".parse::<Uri>().unwrap();
let source = "(module))";
let mut service = LanguageService::default();
service.commit(uri.clone(), source.into());
calm(&mut service, uri.clone());
let response = service.pull_diagnostics(create_params(uri));
assert_json_snapshot!(response);
}
2 changes: 1 addition & 1 deletion crates/service/tests/diagnostics/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ fn type_unused() {
let source = r#"
(module
(type (func))
(type $t (func))))
(type $t (func)))
"#;
let mut service = LanguageService::default();
service.commit(uri.clone(), source.into());
Expand Down

0 comments on commit 16fcb3f

Please sign in to comment.