mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile, cmd/compile/internal/syntax: print relative column info
This change enables printing of relative column information if a prior line directive specified a valid column. If there was no line directive, or the line directive didn't specify a column (or the -C flag is specified), no column information is shown in file positions. Implementation: Column values (and line values, for that matter) that are zero are interpreted as "unknown". A line directive that doesn't specify a column records that as a zero column in the respective PosBase data structure. When computing relative columns, a relative value is zero of the base's column value is zero. When formatting a position, a zero column value is not printed. To make this work without special cases, the PosBase for a file is given a concrete (non-0:0) position 1:1 with the PosBase's line and column also being 1:1. In other words, at the position 1:1 of a file, it's relative positions are starting with 1:1 as one would expect. In the package syntax, this requires self-recursive PosBases for file bases, matching what cmd/internal/src.PosBase was already doing. In src.PosBase, file and inlining bases also need to be based at 1:1 to indicate "known" positions. This change completes the cmd/compiler part of the issue below. Fixes #22662. Change-Id: I6c3d2dee26709581fba0d0261b1d12e93f1cba1a Reviewed-on: https://go-review.googlesource.com/97375 Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
b5bd5bfbc7
commit
0c884d0810
7 changed files with 272 additions and 151 deletions
|
|
@ -31,10 +31,26 @@ func (pos Pos) Base() *PosBase { return pos.base }
|
|||
func (pos Pos) Line() uint { return uint(pos.line) }
|
||||
func (pos Pos) Col() uint { return uint(pos.col) }
|
||||
|
||||
func (pos Pos) RelFilename() string { b := pos.Base(); return b.Filename() }
|
||||
func (pos Pos) RelLine() uint { b := pos.Base(); return b.Line() + (pos.Line() - b.Pos().Line()) }
|
||||
func (pos Pos) RelFilename() string { return pos.base.Filename() }
|
||||
|
||||
func (pos Pos) RelLine() uint {
|
||||
b := pos.base
|
||||
if b.Line() == 0 {
|
||||
// base line is unknown => relative line is unknown
|
||||
return 0
|
||||
}
|
||||
return b.Line() + (pos.Line() - b.Pos().Line())
|
||||
}
|
||||
|
||||
func (pos Pos) RelCol() uint {
|
||||
b := pos.Base()
|
||||
b := pos.base
|
||||
if b.Col() == 0 {
|
||||
// base column is unknown => relative column is unknown
|
||||
// (the current specification for line directives requires
|
||||
// this to apply until the next PosBase/line directive,
|
||||
// not just until the new newline)
|
||||
return 0
|
||||
}
|
||||
if pos.Line() == b.Pos().Line() {
|
||||
// pos on same line as pos base => column is relative to pos base
|
||||
return b.Col() + (pos.Col() - b.Pos().Col())
|
||||
|
|
@ -43,13 +59,34 @@ func (pos Pos) RelCol() uint {
|
|||
}
|
||||
|
||||
func (pos Pos) String() string {
|
||||
s := fmt.Sprintf("%s:%d:%d", pos.RelFilename(), pos.RelLine(), pos.RelCol())
|
||||
if bpos := pos.Base().Pos(); bpos.IsKnown() {
|
||||
s += fmt.Sprintf("[%s:%d:%d]", bpos.RelFilename(), pos.Line(), pos.Col())
|
||||
rel := position_{pos.RelFilename(), pos.RelLine(), pos.RelCol()}
|
||||
abs := position_{pos.Base().Pos().RelFilename(), pos.Line(), pos.Col()}
|
||||
s := rel.String()
|
||||
if rel != abs {
|
||||
s += "[" + abs.String() + "]"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// TODO(gri) cleanup: find better name, avoid conflict with position in error_test.go
|
||||
type position_ struct {
|
||||
filename string
|
||||
line, col uint
|
||||
}
|
||||
|
||||
func (p position_) String() string {
|
||||
if p.line == 0 {
|
||||
if p.filename == "" {
|
||||
return "<unknown position>"
|
||||
}
|
||||
return p.filename
|
||||
}
|
||||
if p.col == 0 {
|
||||
return fmt.Sprintf("%s:%d", p.filename, p.line)
|
||||
}
|
||||
return fmt.Sprintf("%s:%d:%d", p.filename, p.line, p.col)
|
||||
}
|
||||
|
||||
// A PosBase represents the base for relative position information:
|
||||
// At position pos, the relative position is filename:line:col.
|
||||
type PosBase struct {
|
||||
|
|
@ -59,9 +96,12 @@ type PosBase struct {
|
|||
}
|
||||
|
||||
// NewFileBase returns a new PosBase for the given filename.
|
||||
// The PosBase position is unknown in this case.
|
||||
// A file PosBase's position is relative to itself, with the
|
||||
// position being filename:1:1.
|
||||
func NewFileBase(filename string) *PosBase {
|
||||
return &PosBase{filename: filename}
|
||||
base := &PosBase{MakePos(nil, linebase, colbase), filename, linebase, colbase}
|
||||
base.pos.base = base
|
||||
return base
|
||||
}
|
||||
|
||||
// NewLineBase returns a new PosBase for a line directive "line filename:line:col"
|
||||
|
|
@ -73,6 +113,13 @@ func NewLineBase(pos Pos, filename string, line, col uint) *PosBase {
|
|||
return &PosBase{pos, filename, sat32(line), sat32(col)}
|
||||
}
|
||||
|
||||
func (base *PosBase) IsFileBase() bool {
|
||||
if base == nil {
|
||||
return false
|
||||
}
|
||||
return base.pos.base == base
|
||||
}
|
||||
|
||||
func (base *PosBase) Pos() (_ Pos) {
|
||||
if base == nil {
|
||||
return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue