Specify how location ranges are reported in the ASG
An implementation can optionally include location information in the ASG of the parsed document. If it does include this location information, the values must match the location information in the expected data. The purpose of this issue is to specify the logic for how these location ranges are reported.
The optional loc
property on every element in the ASG reports the location range of that node in the source. The range consists of the starting line, column, and file position of the element and the ending line, column, and file position of the element. Both the line and column values are 1-based. The column is meant to represent a visible column in the source. The file property captures the include target stack, when applicable, starting from the first include in the stack. (It's up to code analyzing the ASG to resolve the file value to an absolute representation).
Here's an example:
"location": [{ "line": 1, "col": 1 }, { "line": 3, "col": 4 }]
We're not tracking newline characters when calculating end locations, nor are we tracking empty lines that separate blocks in the ASG.
When computing the end location of a block, the column of the trailing newline is not included. The block ends at the visible location in the source document, not at the newline that follows it. For a delimited block with a delimiter length of 4, the end column is 4, not 5. There are two reasons for this. First, it points to a column in the source that the cursor can go. Second, it ensures that the end column for a block is consistent regardless of whether it's at the end of the document or somewhere in the middle of it.
The tracked location of the document is all the lines in the document, even those that proceed or follow the first and last block, respectively.
The tracked start location of a delimited block is the start of the opening delimiter line (e.g., line: 1, col: 1) and the tracked end location of a delimited block is the end of the closing delimiter line (e.g., line: 3, col: 4).
The tracked start location of a paragraph or named non-delimited block is the start of the first line of content and tracked end location of a paragraph or named non-delimited block is the last visible character of the last line of content.
The tracked start location of block metadata is the first column of the first block attribute line and the tracked end location is the last column of the last block attribute line. The location of the block metadata comes before the start of the block itself (so the entire range of the block is the start location of the metadata to the end location of the block).
Normally, the lowest column value is 1. However, there are two cases when the column must be 0. First, if a document has no blocks, then the start and end column is 0. The 0 column indicates that the source does not occupy any space. If the first line of the document is empty, then the start column is 0. The 0 column indicates that there is no content on the first line, only a newline that follows it. Similarly, if the contents of a verbatim block starts with an empty line, then the start column of the content is 0, again indicating that there is no content on the first line, only the newline that follows it. If the content has a trailing empty line, then the end column is 0 for the same reason.
For an inline element, if the beginning or end of the element was resolved from an attribute reference, the location should be the start or end of the attribute reference, respectively. That's because the location range is meant to track the offsets in the source, not in the resolved value.
Any other nuances of the location range should be covered by this SDR.