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 8package src 9 10// XPos is a more compact representation of Pos. 11type XPos struct { 12 index int32 13 lico 14} 15 16// NoXPos is a valid unknown position. 17var NoXPos XPos 18 19// IsKnown reports whether the position p is known. 20// XPos.IsKnown() matches Pos.IsKnown() for corresponding 21// positions. 22func (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. 28func (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. 35func (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. 42type 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. 49func (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. 69func (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} 76