diff options
| author | Robert Griesemer <gri@golang.org> | 2016-12-09 15:38:23 -0800 |
|---|---|---|
| committer | Robert Griesemer <gri@golang.org> | 2016-12-10 01:21:20 +0000 |
| commit | 2d429f01bd917c42e66e1991eab9c2e33d813d16 (patch) | |
| tree | bec2587cc0489bd64bbe317869b9d67344df9251 /src/cmd | |
| parent | a0c5405c18568900a9b7365297adc1cd846bbdac (diff) | |
| download | go-2d429f01bd917c42e66e1991eab9c2e33d813d16.tar.xz | |
[dev.inline] cmd/compile/internal/syntax: add predicates to syntax.Pos
This moves syntax.Pos closer to cmd/internal/src.Pos so that
we can more easily replace src.Pos with syntax.Pos going forward.
Change-Id: I9f93a65fecb4c22591edca4b9d6cda39cf0e872e
Reviewed-on: https://go-review.googlesource.com/34270
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd')
| -rw-r--r-- | src/cmd/compile/internal/syntax/pos.go | 30 | ||||
| -rw-r--r-- | src/cmd/compile/internal/syntax/pos_test.go | 42 |
2 files changed, 68 insertions, 4 deletions
diff --git a/src/cmd/compile/internal/syntax/pos.go b/src/cmd/compile/internal/syntax/pos.go index 01a03ff30c..98cdae9327 100644 --- a/src/cmd/compile/internal/syntax/pos.go +++ b/src/cmd/compile/internal/syntax/pos.go @@ -9,12 +9,12 @@ package syntax import "strconv" // A Pos encodes a source position consisting of a (line, column) number pair -// and a position base. A zero Pos is a ready to use "unknown" position (empty -// filename, and unknown line and column number). +// and a position base. A zero Pos is a ready to use "unknown" position (nil +// position base and zero line number). // // The (line, column) values refer to a position in a file independent of any -// position base ("absolute" position). They start at 1, and they are unknown -// if 0. +// position base ("absolute" position). Line numbers start at 1, column values +// start at 0 and are byte offsets from the beginning of the line. // // The position base is used to determine the "relative" position, that is the // filename and line number relative to the position base. If the base refers @@ -27,12 +27,34 @@ type Pos struct { lico } +// NoPos is a valid unknown position. +var NoPos Pos + // MakePos creates a new Pos value with the given base, and (file-absolute) // line and column. func MakePos(base *PosBase, line, col uint) Pos { return Pos{base, makeLico(line, col)} } +// IsKnown reports whether the position p is known. +func (p Pos) IsKnown() bool { + return p.base != nil || p.Line() != 0 +} + +// Before reports whether the position p comes before q in the source. +// For positions in different files, ordering is by filename. +func (p Pos) Before(q Pos) bool { + n, m := p.Filename(), q.Filename() + return n < m || n == m && p.lico < q.lico +} + +// After reports whether the position p comes after q in the source. +// For positions in different files, ordering is by filename. +func (p Pos) After(q Pos) bool { + n, m := p.Filename(), q.Filename() + return n > m || n == m && p.lico > q.lico +} + // Filename returns the name of the actual file containing this position. func (p Pos) Filename() string { return p.base.Pos().RelFilename() } diff --git a/src/cmd/compile/internal/syntax/pos_test.go b/src/cmd/compile/internal/syntax/pos_test.go index c9ecd3de68..bf2a0c1dfa 100644 --- a/src/cmd/compile/internal/syntax/pos_test.go +++ b/src/cmd/compile/internal/syntax/pos_test.go @@ -62,6 +62,48 @@ func TestPos(t *testing.T) { } } +func TestPredicates(t *testing.T) { + b1 := NewFileBase("b1") + b2 := NewFileBase("b2") + for _, test := range []struct { + p, q Pos + known, before, after bool + }{ + {NoPos, NoPos, false, false, false}, + {NoPos, MakePos(nil, 1, 0), false, true, false}, + {MakePos(b1, 0, 0), NoPos, true, false, true}, + {MakePos(nil, 1, 0), NoPos, true, false, true}, + + {MakePos(nil, 1, 1), MakePos(nil, 1, 1), true, false, false}, + {MakePos(nil, 1, 1), MakePos(nil, 1, 2), true, true, false}, + {MakePos(nil, 1, 2), MakePos(nil, 1, 1), true, false, true}, + {MakePos(nil, 123, 1), MakePos(nil, 1, 123), true, false, true}, + + {MakePos(b1, 1, 1), MakePos(b1, 1, 1), true, false, false}, + {MakePos(b1, 1, 1), MakePos(b1, 1, 2), true, true, false}, + {MakePos(b1, 1, 2), MakePos(b1, 1, 1), true, false, true}, + {MakePos(b1, 123, 1), MakePos(b1, 1, 123), true, false, true}, + + {MakePos(b1, 1, 1), MakePos(b2, 1, 1), true, true, false}, + {MakePos(b1, 1, 1), MakePos(b2, 1, 2), true, true, false}, + {MakePos(b1, 1, 2), MakePos(b2, 1, 1), true, true, false}, + {MakePos(b1, 123, 1), MakePos(b2, 1, 123), true, true, false}, + + // special case: unknown column (column too large to represent) + {MakePos(nil, 1, colMax+10), MakePos(nil, 1, colMax+20), true, false, false}, + } { + if got := test.p.IsKnown(); got != test.known { + t.Errorf("%s known: got %v; want %v", test.p, got, test.known) + } + if got := test.p.Before(test.q); got != test.before { + t.Errorf("%s < %s: got %v; want %v", test.p, test.q, got, test.before) + } + if got := test.p.After(test.q); got != test.after { + t.Errorf("%s > %s: got %v; want %v", test.p, test.q, got, test.after) + } + } +} + func TestLico(t *testing.T) { for _, test := range []struct { x lico |
