Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting custom line numbers #157

Closed
jyn514 opened this issue Feb 8, 2020 · 5 comments · Fixed by #167
Closed

Allow setting custom line numbers #157

jyn514 opened this issue Feb 8, 2020 · 5 comments · Fixed by #167

Comments

@jyn514
Copy link
Collaborator

jyn514 commented Feb 8, 2020

This is a bit of an edge case ... In C there is a #line macro that allows setting the current line number, it looks like this:

void f();
int main() {
    #line 1
    return f();
}
<stdin>:1:12: error: returning 'void' from a function with incompatible result type
      'int'

Note how the error message says the error occurs on line 1, not line 4.

Currently, it looks like the lines in a file are calculated once and can't be modified. Would it be possible to make the line numbers configurable?

This has the unfortunate complication that there's no longer a 1-1 mapping between the line numbers displayed to the user and the lines in a file: in my example above, there are 2 lines with line number 1. However, this corresponds pretty closely to the current difference between LineIndex (internal) and LineNumber (user-facing) so I don't forsee it being a giant deal.

@brendanzab
Copy link
Owner

Ahh wow! That is a pretty challenging use case? Any idea how we might be able to support this?

@jyn514
Copy link
Collaborator Author

jyn514 commented Feb 19, 2020

It looks like for compute_line_starts() we currently store a Vec, where finding the start of the line is found by indexing into the vec using the line index. I think this is fine: the frontend wants to know the span for the physical line, not for the logical line.

The only thing that needs to change is LineIndex::number(). Currently that just returns self.0 + 1. Maybe instead we could store a BTreeMap of physical lines -> offsets, where the offset records the difference between the physical line and the logical line (line changes within a column is way more than I need and would be harder, I don't think we need to support it). For example, given the following code:

// blank
#line 1
int main() {}
#line 10
int f() {}

the offsets would look like { 2: -1, 4: 6 }. Then to find the logical line for a physical line, you look up the first entry before and add that value to the physical line. So to get the logical line for physical line 6 (int f() {}), we'd find the first entry before was 4: 6 and return 6 + 6 = 12 for the logical line.

Let me know if that sounds doable.

@jyn514
Copy link
Collaborator Author

jyn514 commented Feb 19, 2020

Oh forgot to mention: the API would look something like Files::add_line_offset(&mut self, file: FileId, byte_index: ByteIndex) and we would look up the appropriate physical line number for that index. I have no opinions on what should happen if it's called multiple times for the same line, maybe just overwrite the existing offset?

@brendanzab
Copy link
Owner

@Marwes would this help you out with macro support on Gluon?

@brendanzab
Copy link
Owner

Wondering if we could have a Files::line_number method:

pub trait Files {/// The line number of the line at the given line index.
    fn line_number(&self, id: Self::FileId, line_index: usize) -> Option<usize>;}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants