-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Description
Background: The BasicLit.End method computes the end position of a literal by adding its start position to the length of the BasicLit.Value string, which is assumed to be the complete raw text of the literal. However, for multiline raw string literals, the spec requires that carriage returns (as used in text files on Windows) are discarded, and this process occurs in the scanner, so the Value string in the syntax tree is shorter than the actual string, causing the End position to be computed incorrectly.
Proposal: We propose to record the actual end position of the token in a new field, BasicLit.ValueEnd.
package ast // "go/ast"
type BasicLit struct {
- ValuePos token.Pos // literal position
+ ValuePos, ValueEnd token.Pos // literal position
Kind token.Token // token.INT, token.FLOAT, token.IMAG, token.CHAR, or token.STRING
Value string // literal string; e.g. 42, 0x7f, 3.14, 1e-9, 2.4i, 'a', '\x7f', "foo" or `\m\n\o`
}The implementation is trivial. The only real downside is that the new field pushes the size of the struct up from 4 words to 5, and its size class from 4 words to 6 words. BasicLits are very numerous, about 10% of all tokens according to the nodecount command, so adding this field may cause ASTs to increase space usage by about 2%.
Relatively few programs use the parser and are long running (and therefore care about memory pressure and GC costs). Gopls is arguably the most important among them. We gopls maintainers are willing to pay the memory price for the AST to record the input in greater fidelity, not just as it relates to this issue, but in a number of other ways as well. The way we see it is that there will be no go/ast v2 since it defines the entire Go tooling ecosystem, so we need to make incremental improvements. Computers have also gotten bigger and faster since go/ast was designed.
cc: @griesemer @findleyr
Metadata
Metadata
Assignees
Labels
Type
Projects
Status