Skip to content

Commit a751b16

Browse files
GearsDatapackslpil
authored andcommitted
Use Position
1 parent 7bc5843 commit a751b16

File tree

6 files changed

+83
-48
lines changed

6 files changed

+83
-48
lines changed

compiler-core/src/language_server.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,8 @@ pub fn src_span_to_lsp_range(location: SrcSpan, line_numbers: &LineNumbers) -> R
5252
}
5353

5454
pub fn lsp_range_to_src_span(range: Range, line_numbers: &LineNumbers) -> SrcSpan {
55-
let Range { start, end } = range;
56-
let start = line_numbers.byte_index(start.line + 1, start.character + 1);
57-
let end = line_numbers.byte_index(end.line + 1, end.character + 1);
55+
let start = line_numbers.byte_index(range.start);
56+
let end = line_numbers.byte_index(range.end);
5857
SrcSpan { start, end }
5958
}
6059

compiler-core/src/language_server/completer.rs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,7 @@ where
130130
&'a self,
131131
valid_phrase_char: &impl Fn(char) -> bool,
132132
) -> (Range, String) {
133-
let cursor = self.src_line_numbers.byte_index(
134-
self.cursor_position.line + 1,
135-
self.cursor_position.character + 1,
136-
);
133+
let cursor = self.src_line_numbers.byte_index(*self.cursor_position);
137134

138135
// Get part of phrase prior to cursor
139136
let before = self
@@ -194,12 +191,14 @@ where
194191
/// If the line includes a dot then it provides unqualified import completions.
195192
/// Otherwise it provides direct module import completions.
196193
pub fn import_completions(&'a self) -> Option<Result<Option<Vec<CompletionItem>>>> {
197-
let start_of_line = self
198-
.src_line_numbers
199-
.byte_index(self.cursor_position.line + 1, 1);
200-
let end_of_line = self
201-
.src_line_numbers
202-
.byte_index(self.cursor_position.line + 2, 1);
194+
let start_of_line = self.src_line_numbers.byte_index(Position {
195+
line: self.cursor_position.line,
196+
character: 0,
197+
});
198+
let end_of_line = self.src_line_numbers.byte_index(Position {
199+
line: self.cursor_position.line + 1,
200+
character: 0,
201+
});
203202

204203
// Drop all lines except the line the cursor is on
205204
let src = self.src.get(start_of_line as usize..end_of_line as usize)?;
@@ -562,10 +561,7 @@ where
562561
// e.x. when the user has typed mymodule.| we know local module and prelude values are no longer
563562
// relevant.
564563
if module_select.is_none() {
565-
let cursor = self.src_line_numbers.byte_index(
566-
self.cursor_position.line + 1,
567-
self.cursor_position.character + 1,
568-
);
564+
let cursor = self.src_line_numbers.byte_index(*self.cursor_position);
569565

570566
// Find the function that the cursor is in and push completions for
571567
// its arguments and local variables.

compiler-core/src/language_server/edits.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ pub fn add_newlines_after_import(
4646
line_numbers: &LineNumbers,
4747
src: &str,
4848
) -> Newlines {
49-
let import_start_cursor =
50-
line_numbers.byte_index(import_location.line + 1, import_location.character + 1);
49+
let import_start_cursor = line_numbers.byte_index(import_location);
5150
let is_new_line = src
5251
.chars()
5352
.nth(import_start_cursor as usize)

compiler-core/src/language_server/engine.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -264,9 +264,7 @@ where
264264
};
265265

266266
let completer = Completer::new(&src, &params, &this.compiler, module);
267-
let byte_index = completer
268-
.module_line_numbers
269-
.byte_index(params.position.line + 1, params.position.character + 1);
267+
let byte_index = completer.module_line_numbers.byte_index(params.position);
270268

271269
// If in comment context, do not provide completions
272270
if module.extra.is_within_comment(byte_index) {
@@ -629,8 +627,7 @@ where
629627
)))
630628
};
631629

632-
let byte_index =
633-
lines.byte_index(params.position.line + 1, params.position.character + 1);
630+
let byte_index = lines.byte_index(params.position);
634631

635632
Ok(match reference_for_ast_node(found, &current_module.name) {
636633
Some(Referenced::LocalVariable {
@@ -763,8 +760,7 @@ where
763760
return Ok(None);
764761
};
765762

766-
let byte_index =
767-
lines.byte_index(position.position.line + 1, position.position.character + 1);
763+
let byte_index = lines.byte_index(position.position);
768764

769765
Ok(match reference_for_ast_node(found, &module.name) {
770766
Some(Referenced::LocalVariable {
@@ -998,8 +994,7 @@ Unused labelled fields:
998994
module: &'a Module,
999995
) -> Option<(LineNumbers, Located<'a>)> {
1000996
let line_numbers = LineNumbers::new(&module.code);
1001-
let byte_index =
1002-
line_numbers.byte_index(params.position.line + 1, params.position.character + 1);
997+
let byte_index = line_numbers.byte_index(params.position);
1003998
let node = module.find_node(byte_index);
1004999
let node = node?;
10051000
Some((line_numbers, node))

compiler-core/src/language_server/tests.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -831,13 +831,8 @@ pub fn apply_code_edit(src: &str, mut change: Vec<lsp_types::TextEdit>) -> Strin
831831

832832
change.sort_by_key(|edit| (edit.range.start.line, edit.range.start.character));
833833
for edit in change {
834-
let start = line_numbers
835-
.byte_index(edit.range.start.line + 1, edit.range.start.character + 1)
836-
as i32
837-
- offset;
838-
let end = line_numbers.byte_index(edit.range.end.line + 1, edit.range.end.character + 1)
839-
as i32
840-
- offset;
834+
let start = line_numbers.byte_index(edit.range.start) as i32 - offset;
835+
let end = line_numbers.byte_index(edit.range.end) as i32 - offset;
841836
let range = (start as usize)..(end as usize);
842837
offset += end - start;
843838
offset -= edit.new_text.len() as i32;

compiler-core/src/line_numbers.rs

Lines changed: 64 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use std::collections::HashMap;
22

3+
use lsp_types::Position;
4+
35
/// A struct which contains information about line numbers of a source file,
46
/// and can convert between byte offsets that are used in the compiler and
57
/// line-column pairs used in LSP.
@@ -107,10 +109,10 @@ impl LineNumbers {
107109
}
108110
}
109111

110-
/// Returns the byte index of the corresponding 1-indexed line and column
111-
/// numbers, translating from a UTF-16 character index to a UTF-8 byte index.
112-
pub fn byte_index(&self, line: u32, character: u32) -> u32 {
113-
let line_start = match self.line_starts.get(line as usize - 1) {
112+
/// Returns the byte index of the corresponding LSP line-column `Position`,
113+
/// translating from a UTF-16 character index to a UTF-8 byte index.
114+
pub fn byte_index(&self, position: Position) -> u32 {
115+
let line_start = match self.line_starts.get(position.line as usize) {
114116
Some(&line_start) => line_start,
115117
None => return self.length,
116118
};
@@ -119,7 +121,7 @@ impl LineNumbers {
119121
let mut u16_offset = 0;
120122

121123
loop {
122-
if u16_offset >= character - 1 {
124+
if u16_offset >= position.character {
123125
break;
124126
}
125127

@@ -146,10 +148,34 @@ pub fn main() {
146148
"#;
147149
let line_numbers = LineNumbers::new(src);
148150

149-
assert_eq!(line_numbers.byte_index(1, 1), 0);
150-
assert_eq!(line_numbers.byte_index(1, 5), 4);
151-
assert_eq!(line_numbers.byte_index(100, 1), src.len() as u32);
152-
assert_eq!(line_numbers.byte_index(3, 2), 18);
151+
assert_eq!(
152+
line_numbers.byte_index(Position {
153+
line: 0,
154+
character: 0
155+
}),
156+
0
157+
);
158+
assert_eq!(
159+
line_numbers.byte_index(Position {
160+
line: 0,
161+
character: 4
162+
}),
163+
4
164+
);
165+
assert_eq!(
166+
line_numbers.byte_index(Position {
167+
line: 100,
168+
character: 0
169+
}),
170+
src.len() as u32
171+
);
172+
assert_eq!(
173+
line_numbers.byte_index(Position {
174+
line: 2,
175+
character: 1
176+
}),
177+
18
178+
);
153179
}
154180

155181
// https://github.com/gleam-lang/gleam/issues/3628
@@ -165,10 +191,34 @@ pub fn main() {
165191
"#;
166192
let line_numbers = LineNumbers::new(src);
167193

168-
assert_eq!(line_numbers.byte_index(2, 7), 30);
169-
assert_eq!(line_numbers.byte_index(6, 3), 52);
170-
assert_eq!(line_numbers.byte_index(6, 18), 75);
171-
assert_eq!(line_numbers.byte_index(7, 2), 91);
194+
assert_eq!(
195+
line_numbers.byte_index(Position {
196+
line: 1,
197+
character: 6
198+
}),
199+
30
200+
);
201+
assert_eq!(
202+
line_numbers.byte_index(Position {
203+
line: 5,
204+
character: 2
205+
}),
206+
52
207+
);
208+
assert_eq!(
209+
line_numbers.byte_index(Position {
210+
line: 5,
211+
character: 17
212+
}),
213+
75
214+
);
215+
assert_eq!(
216+
line_numbers.byte_index(Position {
217+
line: 6,
218+
character: 1
219+
}),
220+
91
221+
);
172222
}
173223

174224
// https://github.com/gleam-lang/gleam/issues/3628
@@ -205,6 +255,7 @@ pub fn main() {
205255
);
206256
}
207257

258+
/// A 1-index line and column position
208259
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
209260
pub struct LineColumn {
210261
pub line: u32,

0 commit comments

Comments
 (0)