| | |
| | |
| | |
| |
|
| | package noder |
| |
|
| | import ( |
| | "cmd/compile/internal/base" |
| | "cmd/compile/internal/syntax" |
| | "cmd/internal/src" |
| | ) |
| |
|
| | |
| | type posMap struct { |
| | bases map[*syntax.PosBase]*src.PosBase |
| | cache struct { |
| | last *syntax.PosBase |
| | base *src.PosBase |
| | } |
| | } |
| |
|
| | type poser interface{ Pos() syntax.Pos } |
| | type ender interface{ End() syntax.Pos } |
| |
|
| | func (m *posMap) pos(p poser) src.XPos { return m.makeXPos(p.Pos()) } |
| |
|
| | func (m *posMap) makeXPos(pos syntax.Pos) src.XPos { |
| | |
| | |
| | if !pos.IsKnown() { |
| | return src.NoXPos |
| | } |
| |
|
| | posBase := m.makeSrcPosBase(pos.Base()) |
| | return base.Ctxt.PosTable.XPos(src.MakePos(posBase, pos.Line(), pos.Col())) |
| | } |
| |
|
| | |
| | func (m *posMap) makeSrcPosBase(b0 *syntax.PosBase) *src.PosBase { |
| | |
| | if m.cache.last == b0 { |
| | return m.cache.base |
| | } |
| |
|
| | b1, ok := m.bases[b0] |
| | if !ok { |
| | fn := b0.Filename() |
| | absfn := trimFilename(b0) |
| |
|
| | if b0.IsFileBase() { |
| | b1 = src.NewFileBase(fn, absfn) |
| | } else { |
| | |
| | p0 := b0.Pos() |
| | p0b := p0.Base() |
| | if p0b == b0 { |
| | panic("infinite recursion in makeSrcPosBase") |
| | } |
| | p1 := src.MakePos(m.makeSrcPosBase(p0b), p0.Line(), p0.Col()) |
| | b1 = src.NewLinePragmaBase(p1, fn, absfn, b0.Line(), b0.Col()) |
| | } |
| | if m.bases == nil { |
| | m.bases = make(map[*syntax.PosBase]*src.PosBase) |
| | } |
| | m.bases[b0] = b1 |
| | } |
| |
|
| | |
| | m.cache.last = b0 |
| | m.cache.base = b1 |
| |
|
| | return b1 |
| | } |
| |
|