mirror of
https://github.com/golang/go
synced 2024-11-23 20:00:04 -07:00
[dev.typeparams] cmd/compile: extract posMap from noder
This CL extracts the position mapping logic from noder and moves it into a new posMap type, which can be more easily reused. Passes toolstash -cmp. Change-Id: I87dec3a3d27779c5bcc838f2e36c3aa8fabad155 Reviewed-on: https://go-review.googlesource.com/c/go/+/282916 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Matthew Dempsky <mdempsky@google.com> Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
2e8f29b79d
commit
3e1a87ac2a
@ -59,7 +59,6 @@ func ParseFiles(filenames []string) (lines uint) {
|
||||
|
||||
for _, filename := range filenames {
|
||||
p := &noder{
|
||||
basemap: make(map[*syntax.PosBase]*src.PosBase),
|
||||
err: make(chan syntax.Error),
|
||||
trackScopes: base.Flag.Dwarf,
|
||||
}
|
||||
@ -271,42 +270,6 @@ func (m *gcimports) ImportFrom(path, srcDir string, mode types2.ImportMode) (*ty
|
||||
return importer.Import(m.packages, path, srcDir, m.lookup)
|
||||
}
|
||||
|
||||
// makeSrcPosBase translates from a *syntax.PosBase to a *src.PosBase.
|
||||
func (p *noder) makeSrcPosBase(b0 *syntax.PosBase) *src.PosBase {
|
||||
// fast path: most likely PosBase hasn't changed
|
||||
if p.basecache.last == b0 {
|
||||
return p.basecache.base
|
||||
}
|
||||
|
||||
b1, ok := p.basemap[b0]
|
||||
if !ok {
|
||||
fn := b0.Filename()
|
||||
if b0.IsFileBase() {
|
||||
b1 = src.NewFileBase(fn, absFilename(fn))
|
||||
} else {
|
||||
// line directive base
|
||||
p0 := b0.Pos()
|
||||
p0b := p0.Base()
|
||||
if p0b == b0 {
|
||||
panic("infinite recursion in makeSrcPosBase")
|
||||
}
|
||||
p1 := src.MakePos(p.makeSrcPosBase(p0b), p0.Line(), p0.Col())
|
||||
b1 = src.NewLinePragmaBase(p1, fn, fileh(fn), b0.Line(), b0.Col())
|
||||
}
|
||||
p.basemap[b0] = b1
|
||||
}
|
||||
|
||||
// update cache
|
||||
p.basecache.last = b0
|
||||
p.basecache.base = b1
|
||||
|
||||
return b1
|
||||
}
|
||||
|
||||
func (p *noder) makeXPos(pos syntax.Pos) (_ src.XPos) {
|
||||
return base.Ctxt.PosTable.XPos(src.MakePos(p.makeSrcPosBase(pos.Base()), pos.Line(), pos.Col()))
|
||||
}
|
||||
|
||||
func (p *noder) errorAt(pos syntax.Pos, format string, args ...interface{}) {
|
||||
base.ErrorfAt(p.makeXPos(pos), format, args...)
|
||||
}
|
||||
@ -322,11 +285,7 @@ func absFilename(name string) string {
|
||||
|
||||
// noder transforms package syntax's AST into a Node tree.
|
||||
type noder struct {
|
||||
basemap map[*syntax.PosBase]*src.PosBase
|
||||
basecache struct {
|
||||
last *syntax.PosBase
|
||||
base *src.PosBase
|
||||
}
|
||||
posMap
|
||||
|
||||
file *syntax.File
|
||||
linknames []linkname
|
||||
@ -900,7 +859,11 @@ func (p *noder) expr(expr syntax.Expr) ir.Node {
|
||||
case *syntax.Name:
|
||||
return p.mkname(expr)
|
||||
case *syntax.BasicLit:
|
||||
n := ir.NewBasicLit(p.pos(expr), p.basicLit(expr))
|
||||
pos := base.Pos
|
||||
if expr != syntax.ImplicitOne { // ImplicitOne doesn't have a unique position
|
||||
pos = p.pos(expr)
|
||||
}
|
||||
n := ir.NewBasicLit(pos, p.basicLit(expr))
|
||||
if expr.Kind == syntax.RuneLit {
|
||||
n.SetType(types.UntypedRune)
|
||||
}
|
||||
@ -1720,17 +1683,8 @@ func (p *noder) wrapname(n syntax.Node, x ir.Node) ir.Node {
|
||||
return x
|
||||
}
|
||||
|
||||
func (p *noder) pos(n syntax.Node) src.XPos {
|
||||
// TODO(gri): orig.Pos() should always be known - fix package syntax
|
||||
xpos := base.Pos
|
||||
if pos := n.Pos(); pos.IsKnown() {
|
||||
xpos = p.makeXPos(pos)
|
||||
}
|
||||
return xpos
|
||||
}
|
||||
|
||||
func (p *noder) setlineno(n syntax.Node) {
|
||||
if n != nil {
|
||||
if n != nil && n != syntax.ImplicitOne {
|
||||
base.Pos = p.pos(n)
|
||||
}
|
||||
}
|
||||
|
79
src/cmd/compile/internal/noder/posmap.go
Normal file
79
src/cmd/compile/internal/noder/posmap.go
Normal file
@ -0,0 +1,79 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package noder
|
||||
|
||||
import (
|
||||
"cmd/compile/internal/base"
|
||||
"cmd/compile/internal/syntax"
|
||||
"cmd/internal/src"
|
||||
)
|
||||
|
||||
// A posMap handles mapping from syntax.Pos to src.XPos.
|
||||
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) end(p ender) src.XPos { return m.makeXPos(p.End()) }
|
||||
|
||||
func (m *posMap) makeXPos(pos syntax.Pos) src.XPos {
|
||||
if !pos.IsKnown() {
|
||||
base.Fatalf("unknown position")
|
||||
}
|
||||
|
||||
posBase := m.makeSrcPosBase(pos.Base())
|
||||
return base.Ctxt.PosTable.XPos(src.MakePos(posBase, pos.Line(), pos.Col()))
|
||||
}
|
||||
|
||||
// makeSrcPosBase translates from a *syntax.PosBase to a *src.PosBase.
|
||||
func (m *posMap) makeSrcPosBase(b0 *syntax.PosBase) *src.PosBase {
|
||||
// fast path: most likely PosBase hasn't changed
|
||||
if m.cache.last == b0 {
|
||||
return m.cache.base
|
||||
}
|
||||
|
||||
b1, ok := m.bases[b0]
|
||||
if !ok {
|
||||
fn := b0.Filename()
|
||||
if b0.IsFileBase() {
|
||||
b1 = src.NewFileBase(fn, absFilename(fn))
|
||||
} else {
|
||||
// line directive base
|
||||
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, fileh(fn), b0.Line(), b0.Col())
|
||||
}
|
||||
if m.bases == nil {
|
||||
m.bases = make(map[*syntax.PosBase]*src.PosBase)
|
||||
}
|
||||
m.bases[b0] = b1
|
||||
}
|
||||
|
||||
// update cache
|
||||
m.cache.last = b0
|
||||
m.cache.base = b1
|
||||
|
||||
return b1
|
||||
}
|
||||
|
||||
func (m *posMap) join(other *posMap) {
|
||||
for k, v := range other.bases {
|
||||
if m.bases[k] != nil {
|
||||
base.Fatalf("duplicate posmap bases")
|
||||
}
|
||||
m.bases[k] = v
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user