Skip to content

Commit 6a09953

Browse files
authored
fix(grainlsp): Properly surface errors in other files (#1490)
1 parent 3678eb5 commit 6a09953

File tree

3 files changed

+111
-20
lines changed

3 files changed

+111
-20
lines changed

compiler/src/language_server/code_file.re

Lines changed: 75 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,12 @@ let warning_to_diagnostic =
3939
},
4040
};
4141

42-
{range, severity: Warning, message: Grain_utils.Warnings.message(warn)};
42+
{
43+
range,
44+
severity: Warning,
45+
message: Grain_utils.Warnings.message(warn),
46+
related_information: [],
47+
};
4348
};
4449

4550
let compile_source = (uri, source) => {
@@ -57,30 +62,73 @@ let compile_source = (uri, source) => {
5762
| exception exn =>
5863
switch (Grain_parsing.Location.error_of_exn(exn)) {
5964
| Some(`Ok(e)) =>
60-
let (_, line, startchar) =
65+
let (file, line, startchar) =
6166
Grain_parsing.Location.get_pos_info(e.loc.loc_start);
6267
let (_, endline, endchar) =
6368
Grain_parsing.Location.get_pos_info(e.loc.loc_end);
6469

6570
let startchar = startchar < 0 ? 0 : startchar;
6671
let endchar = endchar < 0 ? 0 : endchar;
6772

68-
let range: Protocol.range = {
69-
range_start: {
70-
line: line - 1,
71-
character: startchar,
72-
},
73-
range_end: {
74-
line: endline - 1,
75-
character: endchar,
76-
},
77-
};
73+
let error: Protocol.diagnostic =
74+
if (filename == file) {
75+
let source_range: Protocol.range = {
76+
range_start: {
77+
line: line - 1,
78+
character: startchar,
79+
},
80+
range_end: {
81+
line: endline - 1,
82+
character: endchar,
83+
},
84+
};
7885

79-
{
80-
program: None,
81-
error: Some({range, severity: Error, message: e.msg}),
82-
warnings: [],
83-
};
86+
{
87+
range: source_range,
88+
severity: Error,
89+
message: e.msg,
90+
related_information: [],
91+
};
92+
} else {
93+
let source_range: Protocol.range = {
94+
range_start: {
95+
line: 0,
96+
character: 0,
97+
},
98+
range_end: {
99+
line: 0,
100+
character: 1,
101+
},
102+
};
103+
104+
let file_range: Protocol.range = {
105+
range_start: {
106+
line: line - 1,
107+
character: startchar,
108+
},
109+
range_end: {
110+
line: endline - 1,
111+
character: endchar,
112+
},
113+
};
114+
115+
{
116+
range: source_range,
117+
severity: Error,
118+
message: "Failed to compile " ++ file,
119+
related_information: [
120+
{
121+
location: {
122+
uri: Protocol.filename_to_uri(file),
123+
range: file_range,
124+
},
125+
message: e.msg,
126+
},
127+
],
128+
};
129+
};
130+
131+
{program: None, error: Some(error), warnings: []};
84132
| _ =>
85133
let range: Protocol.range = {
86134
range_start: {
@@ -89,13 +137,19 @@ let compile_source = (uri, source) => {
89137
},
90138
range_end: {
91139
line: 0,
92-
character: 0,
140+
character: 1,
93141
},
94142
};
95143

96144
{
97145
program: None,
98-
error: Some({range, severity: Error, message: "Unable to parse"}),
146+
error:
147+
Some({
148+
range,
149+
severity: Error,
150+
message: "Unable to parse",
151+
related_information: [],
152+
}),
99153
warnings: [],
100154
};
101155
}
@@ -112,7 +166,7 @@ let compile_source = (uri, source) => {
112166
},
113167
range_end: {
114168
line: 0,
115-
character: 0,
169+
character: 1,
116170
},
117171
};
118172

@@ -123,6 +177,7 @@ let compile_source = (uri, source) => {
123177
range,
124178
severity: Error,
125179
message: "Compilation failed with an internal error",
180+
related_information: [],
126181
}),
127182
warnings: [],
128183
};

compiler/src/language_server/protocol.re

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,29 @@ let diagnostic_severity_of_yojson = json =>
4747
}
4848
});
4949

50+
// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#location
51+
[@deriving yojson]
52+
type location = {
53+
uri,
54+
range,
55+
};
56+
57+
// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnosticRelatedInformation
58+
[@deriving yojson]
59+
type diagnostic_related_information = {
60+
location,
61+
message: string,
62+
};
63+
5064
// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic
5165
[@deriving yojson]
5266
type diagnostic = {
5367
// TODO: Implement the rest of the fields
5468
range,
5569
severity: diagnostic_severity,
5670
message: string,
71+
[@key "relatedInformation"]
72+
related_information: list(diagnostic_related_information),
5773
};
5874

5975
// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#command
@@ -283,3 +299,7 @@ let notification = (~method, params) => {
283299
let uri_to_filename = (uri: uri): string => {
284300
Uri.path(uri);
285301
};
302+
303+
let filename_to_uri = (filename: string): uri => {
304+
Uri.of_string(filename);
305+
};

compiler/src/language_server/protocol.rei

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,27 @@ type diagnostic_severity =
3333
| Information
3434
| Hint;
3535

36+
// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#location
37+
[@deriving yojson]
38+
type location = {
39+
uri,
40+
range,
41+
};
42+
43+
// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnosticRelatedInformation
44+
[@deriving yojson]
45+
type diagnostic_related_information = {
46+
location,
47+
message: string,
48+
};
49+
3650
// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic
3751
[@deriving yojson]
3852
type diagnostic = {
3953
range,
4054
severity: diagnostic_severity,
4155
message: string,
56+
related_information: list(diagnostic_related_information),
4257
};
4358

4459
// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#command
@@ -138,3 +153,4 @@ let error: (~id: message_id=?, response_error) => unit;
138153
let notification: (~method: string, Yojson.Safe.t) => unit;
139154

140155
let uri_to_filename: uri => string;
156+
let filename_to_uri: string => uri;

0 commit comments

Comments
 (0)