Skip to content

Commit

Permalink
Fix various edge cases at the end of file
Browse files Browse the repository at this point in the history
  • Loading branch information
VonTum committed Mar 4, 2024
1 parent ebe0108 commit caabc42
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 12 deletions.
4 changes: 2 additions & 2 deletions src/dev_aid/lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ fn get_hover_info<'l>(file_cache : &'l LoadedFileCache, text_pos : &lsp_types::T

let file_data = &file_cache.linker.files[uuid];

let byte_pos = file_data.file_text.linecol_to_byte(from_position(text_pos.position));
let byte_pos = file_data.file_text.linecol_to_byte_clamp(from_position(text_pos.position));

let (info, span) = file_cache.linker.get_info_about_source_location(byte_pos, uuid)?;
//let span = Span::new_single_token(token_idx);
Expand Down Expand Up @@ -458,7 +458,7 @@ fn handle_request(method : &str, params : serde_json::Value, file_cache : &mut L

let file_data = &file_cache.linker.files[uuid];

let position = file_data.file_text.linecol_to_byte(from_position(params.text_document_position.position));
let position = file_data.file_text.linecol_to_byte_clamp(from_position(params.text_document_position.position));

serde_json::to_value(&CompletionResponse::Array(gather_completions(&file_cache.linker, uuid, position)))
}
Expand Down
28 changes: 21 additions & 7 deletions src/file_position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ impl Span {
pub const MAX_POSSIBLE_SPAN : Span = Span(0, usize::MAX);
pub const INVALID_SPAN : Span = Span(usize::MAX, usize::MAX);

#[track_caller]
pub fn new_from_byte_range(rng : Range<usize>) -> Span {
assert!(rng.end >= rng.start);
Span(rng.start, rng.end)
}
pub fn into_range(&self) -> Range<usize> {
self.0..self.1
}
#[track_caller]
pub fn new_overarching(left : Span, right : Span) -> Span {
assert!(left.0 <= right.0);
assert!(left.1 <= right.1);
Expand All @@ -28,18 +30,21 @@ impl Span {
pub fn size(&self) -> usize {
self.1 - self.0
}
#[track_caller]
pub fn difference_left(outer : Span, inner : Span) -> Span {
assert!(outer.0 <= inner.0);
assert!(outer.1 >= inner.1);

Span(outer.0, inner.0)
}
#[track_caller]
pub fn difference_right(outer : Span, inner : Span) -> Span {
assert!(outer.0 <= inner.0);
assert!(outer.1 >= inner.1);

Span(inner.1, outer.1)
}
#[track_caller]
pub fn into_single_char_span(self) -> SingleCharSpan {
assert!(self.1 == self.0+1);
SingleCharSpan{char_idx: self.0}
Expand Down Expand Up @@ -134,9 +139,9 @@ impl FileText {

FileText{file_text, lines_start_at}
}

/// Errors when byte is outside of file
pub fn byte_to_linecol(&self, byte_pos : usize) -> LineCol {
assert!(byte_pos < self.file_text.len());
assert!(byte_pos <= self.file_text.len());
let line = match self.lines_start_at.binary_search(&byte_pos) {
Ok(exact_newline) => exact_newline,
Err(before_newline) => before_newline - 1
Expand All @@ -145,25 +150,34 @@ impl FileText {

LineCol{line, col : text_before.chars().count()}
}
pub fn linecol_to_byte(&self, linecol : LineCol) -> usize {
/// Clamps the linecol to be within the file, so cannot error.
pub fn linecol_to_byte_clamp(&self, linecol : LineCol) -> usize {
let line_end = if linecol.line+1 < self.lines_start_at.len() {
self.lines_start_at[linecol.line+1] - 1
} else if linecol.line+1 == self.lines_start_at.len() {
self.file_text.len()
} else {
return self.file_text.len()
};
let line_start = self.lines_start_at[linecol.line];
let line_text = &self.file_text[line_start..self.lines_start_at[linecol.line+1]];
let line_text = &self.file_text[line_start..line_end];

let mut cols_left = linecol.col;
for (byte, _) in line_text.char_indices() {
let mut char_indices = line_text.char_indices();
for (byte, _) in &mut char_indices {
if cols_left == 0 {
return line_start + byte;
}
cols_left -= 1;
}
unreachable!()
line_end
}
pub fn get_span_linecol_range(&self, span : Span) -> Range<LineCol> {
self.byte_to_linecol(span.0)..self.byte_to_linecol(span.1)
}

pub fn whole_file_span(&self) -> Span {
Span(0, self.file_text.len() - 1)
Span(0, self.file_text.len())
}

pub fn is_span_valid(&self, span : Span) -> bool {
Expand Down
4 changes: 4 additions & 0 deletions src/instantiation/latency_algorithm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ fn extract_solution<'d>(mut latencies : Vec<i64>, fanins : &'d ListOfLists<FanIn

pub fn solve_latencies<'d>(fanins : &'d ListOfLists<FanInOut>, fanouts : &'d ListOfLists<FanInOut>, inputs : &'d [usize], outputs : &'d [usize], mut specified_latencies : Vec<SpecifiedLatency>) -> Result<Vec<i64>, LatencyCountingError> {
assert!(fanins.len() == fanouts.len());
if fanins.len() == 0 {
return Ok(Vec::new());
}

let mut input_side = LatencySolverSide::new(fanouts, inputs);
let mut output_side = LatencySolverSide::new(fanins, outputs);

Expand Down
6 changes: 3 additions & 3 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -703,9 +703,9 @@ impl<'file> ASTParserContext<'file> {



pub fn parse<'nums, 'g, 'file>(token_hierarchy : &Vec<TokenTreeNode>, file_text : &'file FileText, whole_file_span : Span, errors : ErrorCollector) -> ASTRoot {
pub fn parse<'nums, 'g, 'file>(token_hierarchy : &Vec<TokenTreeNode>, file_text : &'file FileText, errors : ErrorCollector) -> ASTRoot {
let context = ASTParserContext{errors, file_text};
let mut token_stream = TokenStream::new(&token_hierarchy, whole_file_span);
let mut token_stream = TokenStream::new(&token_hierarchy, file_text.whole_file_span());
context.parse_ast(&mut token_stream)
}

Expand All @@ -727,7 +727,7 @@ pub fn perform_full_semantic_parse<'txt>(file_text : String, file : FileUUID) ->

let token_hierarchy = to_token_hierarchy(&tokens, &token_spans, &errors);

let ast = parse(&token_hierarchy, &file_text, file_text.whole_file_span(), errors);
let ast = parse(&token_hierarchy, &file_text, errors);

FullParseResult{
file_text,
Expand Down

0 comments on commit caabc42

Please sign in to comment.