go/gcimporter: update importer to match latest gc export data changes
Adjustments taken from https://golang.org/cl/22580. Change-Id: Ic88137b410767bd17e3d6142cec2b5a112df56be Reviewed-on: https://go-review.googlesource.com/22582 Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
14480f21a0
commit
c5c16cf68a
|
@ -37,14 +37,6 @@ import (
|
||||||
// (suspected) format errors, and whenever a change is made to the format.
|
// (suspected) format errors, and whenever a change is made to the format.
|
||||||
const debugFormat = false // default: false
|
const debugFormat = false // default: false
|
||||||
|
|
||||||
// If posInfoFormat is set, position information (file, lineno) is written
|
|
||||||
// for each exported object, including methods and struct fields. Currently
|
|
||||||
// disabled because it may lead to different object files depending on which
|
|
||||||
// directory they are built under, which causes tests checking for hermetic
|
|
||||||
// builds to fail (e.g. TestCgoConsistentResults for cmd/go).
|
|
||||||
// TODO(gri) determine what to do here.
|
|
||||||
const posInfoFormat = false
|
|
||||||
|
|
||||||
// If trace is set, debugging output is printed to std out.
|
// If trace is set, debugging output is printed to std out.
|
||||||
const trace = false // default: false
|
const trace = false // default: false
|
||||||
|
|
||||||
|
@ -60,8 +52,9 @@ type exporter struct {
|
||||||
typIndex map[types.Type]int
|
typIndex map[types.Type]int
|
||||||
|
|
||||||
// position encoding
|
// position encoding
|
||||||
prevFile string
|
posInfoFormat bool
|
||||||
prevLine int
|
prevFile string
|
||||||
|
prevLine int
|
||||||
|
|
||||||
// debugging support
|
// debugging support
|
||||||
written int // bytes written
|
written int // bytes written
|
||||||
|
@ -72,10 +65,11 @@ type exporter struct {
|
||||||
// If no file set is provided, position info will be missing.
|
// If no file set is provided, position info will be missing.
|
||||||
func BExportData(fset *token.FileSet, pkg *types.Package) []byte {
|
func BExportData(fset *token.FileSet, pkg *types.Package) []byte {
|
||||||
p := exporter{
|
p := exporter{
|
||||||
fset: fset,
|
fset: fset,
|
||||||
strIndex: map[string]int{"": 0}, // empty string is mapped to 0
|
strIndex: map[string]int{"": 0}, // empty string is mapped to 0
|
||||||
pkgIndex: make(map[*types.Package]int),
|
pkgIndex: make(map[*types.Package]int),
|
||||||
typIndex: make(map[types.Type]int),
|
typIndex: make(map[types.Type]int),
|
||||||
|
posInfoFormat: true, // TODO(gri) might become a flag, eventually
|
||||||
}
|
}
|
||||||
|
|
||||||
// first byte indicates low-level encoding format
|
// first byte indicates low-level encoding format
|
||||||
|
@ -86,7 +80,7 @@ func BExportData(fset *token.FileSet, pkg *types.Package) []byte {
|
||||||
p.rawByte(format)
|
p.rawByte(format)
|
||||||
|
|
||||||
// posInfo exported or not?
|
// posInfo exported or not?
|
||||||
p.bool(posInfoFormat)
|
p.bool(p.posInfoFormat)
|
||||||
|
|
||||||
// --- generic export data ---
|
// --- generic export data ---
|
||||||
|
|
||||||
|
@ -211,29 +205,56 @@ func (p *exporter) obj(obj types.Object) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *exporter) pos(obj types.Object) {
|
func (p *exporter) pos(obj types.Object) {
|
||||||
if !posInfoFormat {
|
if !p.posInfoFormat {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var file string
|
file, line := p.fileLine(obj)
|
||||||
var line int
|
if file == p.prevFile {
|
||||||
|
// common case: write line delta
|
||||||
|
// delta == 0 means different file or no line change
|
||||||
|
delta := line - p.prevLine
|
||||||
|
p.int(delta)
|
||||||
|
if delta == 0 {
|
||||||
|
p.int(-1) // -1 means no file change
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// different file
|
||||||
|
p.int(0)
|
||||||
|
// Encode filename as length of common prefix with previous
|
||||||
|
// filename, followed by (possibly empty) suffix. Filenames
|
||||||
|
// frequently share path prefixes, so this can save a lot
|
||||||
|
// of space and make export data size less dependent on file
|
||||||
|
// path length. The suffix is unlikely to be empty because
|
||||||
|
// file names tend to end in ".go".
|
||||||
|
n := commonPrefixLen(p.prevFile, file)
|
||||||
|
p.int(n) // n >= 0
|
||||||
|
p.string(file[n:]) // write suffix only
|
||||||
|
p.prevFile = file
|
||||||
|
p.int(line)
|
||||||
|
}
|
||||||
|
p.prevLine = line
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *exporter) fileLine(obj types.Object) (file string, line int) {
|
||||||
if p.fset != nil {
|
if p.fset != nil {
|
||||||
pos := p.fset.Position(obj.Pos())
|
pos := p.fset.Position(obj.Pos())
|
||||||
file = pos.Filename
|
file = pos.Filename
|
||||||
line = pos.Line
|
line = pos.Line
|
||||||
}
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if file == p.prevFile && line != p.prevLine {
|
func commonPrefixLen(a, b string) int {
|
||||||
// common case: write delta-encoded line number
|
if len(a) > len(b) {
|
||||||
p.int(line - p.prevLine) // != 0
|
a, b = b, a
|
||||||
} else {
|
|
||||||
// uncommon case: filename changed, or line didn't change
|
|
||||||
p.int(0)
|
|
||||||
p.string(file)
|
|
||||||
p.int(line)
|
|
||||||
p.prevFile = file
|
|
||||||
}
|
}
|
||||||
p.prevLine = line
|
// len(a) <= len(b)
|
||||||
|
i := 0
|
||||||
|
for i < len(a) && a[i] == b[i] {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *exporter) qualifiedName(obj types.Object) {
|
func (p *exporter) qualifiedName(obj types.Object) {
|
||||||
|
|
|
@ -208,13 +208,14 @@ func (p *importer) pos() {
|
||||||
|
|
||||||
file := p.prevFile
|
file := p.prevFile
|
||||||
line := p.prevLine
|
line := p.prevLine
|
||||||
|
|
||||||
if delta := p.int(); delta != 0 {
|
if delta := p.int(); delta != 0 {
|
||||||
|
// line changed
|
||||||
line += delta
|
line += delta
|
||||||
} else {
|
} else if n := p.int(); n >= 0 {
|
||||||
file = p.string()
|
// file changed
|
||||||
line = p.int()
|
file = p.prevFile[:n] + p.string()
|
||||||
p.prevFile = file
|
p.prevFile = file
|
||||||
|
line = p.int()
|
||||||
}
|
}
|
||||||
p.prevLine = line
|
p.prevLine = line
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue