startColumn computes visual column using int(pos - ancestor) - the byte distance between two token.Pos values. token.Pos values are byte offsets into the original source, fixed at parse time. They are never updated.
After removeLines merges lines, the line table is updated (so tokenFile.Line(pos) returns correct line numbers), but the byte offsets remain unchanged. The byte distance between two positions on a now-merged line still includes the original \n and leading whitespace characters, producing inflated column values.
Example:
Given a multi-line function signature that gets condensed:
// Before condensing:
func interfaceType(
a interface{ Error() string },
b interface{ Error() string },
) {
}
After removeLines merges the signature onto one line, startColumn for the { computes int(Lbrace - FuncDecl.Pos()) ≈ 90 bytes (includes original \n\t characters), even though the visual column is ~53.
Impact:
Any code that calls startColumn on a position sitting on a previously-merged line will get wrong results. Currently startColumn is only called from canCondense, where it works because the node being condensed hasn't been affected by prior merging. However, this limits us to performing exactly one single change on a node.
startColumncomputes visual column usingint(pos - ancestor)- the byte distance between twotoken.Posvalues.token.Posvalues are byte offsets into the original source, fixed at parse time. They are never updated.After
removeLinesmerges lines, the line table is updated (sotokenFile.Line(pos)returns correct line numbers), but the byte offsets remain unchanged. The byte distance between two positions on a now-merged line still includes the original\nand leading whitespace characters, producing inflated column values.Example:
Given a multi-line function signature that gets condensed:
After
removeLinesmerges the signature onto one line,startColumnfor the{computesint(Lbrace - FuncDecl.Pos())≈ 90 bytes (includes original\n\tcharacters), even though the visual column is ~53.Impact:
Any code that calls
startColumnon a position sitting on a previously-merged line will get wrong results. CurrentlystartColumnis only called fromcanCondense, where it works because the node being condensed hasn't been affected by prior merging. However, this limits us to performing exactly one single change on a node.