github.com/ltltlt/go-source-code@v0.0.0-20190830023027-95be009773aa/cmd/internal/src/xpos.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // This file implements the compressed encoding of source 6 // positions using a lookup table. 7 8 package src 9 10 // XPos is a more compact representation of Pos. 11 type XPos struct { 12 index int32 13 lico 14 } 15 16 // NoXPos is a valid unknown position. 17 var NoXPos XPos 18 19 // IsKnown reports whether the position p is known. 20 // XPos.IsKnown() matches Pos.IsKnown() for corresponding 21 // positions. 22 func (p XPos) IsKnown() bool { 23 return p.index != 0 || p.Line() != 0 24 } 25 26 // Before reports whether the position p comes before q in the source. 27 // For positions with different bases, ordering is by base index. 28 func (p XPos) Before(q XPos) bool { 29 n, m := p.index, q.index 30 return n < m || n == m && p.lico < q.lico 31 } 32 33 // After reports whether the position p comes after q in the source. 34 // For positions with different bases, ordering is by base index. 35 func (p XPos) After(q XPos) bool { 36 n, m := p.index, q.index 37 return n > m || n == m && p.lico > q.lico 38 } 39 40 // A PosTable tracks Pos -> XPos conversions and vice versa. 41 // Its zero value is a ready-to-use PosTable. 42 type PosTable struct { 43 baseList []*PosBase 44 indexMap map[*PosBase]int 45 } 46 47 // XPos returns the corresponding XPos for the given pos, 48 // adding pos to t if necessary. 49 func (t *PosTable) XPos(pos Pos) XPos { 50 m := t.indexMap 51 if m == nil { 52 // Create new list and map and populate with nil 53 // base so that NoPos always gets index 0. 54 t.baseList = append(t.baseList, nil) 55 m = map[*PosBase]int{nil: 0} 56 t.indexMap = m 57 } 58 i, ok := m[pos.base] 59 if !ok { 60 i = len(t.baseList) 61 t.baseList = append(t.baseList, pos.base) 62 t.indexMap[pos.base] = i 63 } 64 return XPos{int32(i), pos.lico} 65 } 66 67 // Pos returns the corresponding Pos for the given p. 68 // If p cannot be translated via t, the function panics. 69 func (t *PosTable) Pos(p XPos) Pos { 70 var base *PosBase 71 if p.index != 0 { 72 base = t.baseList[p.index] 73 } 74 return Pos{base, p.lico} 75 }