mirror of
https://github.com/golang/go.git
synced 2024-09-21 10:28:27 +00:00
cmd/compile: add package height to export data
A package's height is defined as the length of the longest import path between itself and a leaf package (i.e., package with no imports). We can't rely on knowing the path of the package being compiled, so package height is useful for defining a package ordering. Updates #24693. Change-Id: I965162c440b6c5397db91b621ea0be7fa63881f1 Reviewed-on: https://go-review.googlesource.com/105038 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
fe77a5413e
commit
07029254a0
@ -135,13 +135,14 @@ import (
|
||||
const debugFormat = false // default: false
|
||||
|
||||
// Current export format version. Increase with each format change.
|
||||
// 6: package height (CL 105038)
|
||||
// 5: improved position encoding efficiency (issue 20080, CL 41619)
|
||||
// 4: type name objects support type aliases, uses aliasTag
|
||||
// 3: Go1.8 encoding (same as version 2, aliasTag defined but never used)
|
||||
// 2: removed unused bool in ODCL export (compiler only)
|
||||
// 1: header format change (more regular), export package for _ struct fields
|
||||
// 0: Go1.7 encoding
|
||||
const exportVersion = 5
|
||||
const exportVersion = 6
|
||||
|
||||
// exportInlined enables the export of inlined function bodies and related
|
||||
// dependencies. The compiler should work w/o any loss of functionality with
|
||||
@ -428,6 +429,7 @@ func (p *exporter) pkg(pkg *types.Pkg) {
|
||||
p.tag(packageTag)
|
||||
p.string(pkg.Name)
|
||||
p.path(pkg.Path)
|
||||
p.int(pkg.Height)
|
||||
}
|
||||
|
||||
func unidealType(typ *types.Type, val Val) *types.Type {
|
||||
|
@ -96,10 +96,10 @@ func Import(imp *types.Pkg, in *bufio.Reader) {
|
||||
|
||||
// read version specific flags - extend as necessary
|
||||
switch p.version {
|
||||
// case 6:
|
||||
// case 7:
|
||||
// ...
|
||||
// fallthrough
|
||||
case 5, 4, 3, 2, 1:
|
||||
case 6, 5, 4, 3, 2, 1:
|
||||
p.debugFormat = p.rawStringln(p.rawByte()) == "debug"
|
||||
p.trackAllTypes = p.bool()
|
||||
p.posInfoFormat = p.bool()
|
||||
@ -281,6 +281,10 @@ func (p *importer) pkg() *types.Pkg {
|
||||
} else {
|
||||
path = p.string()
|
||||
}
|
||||
var height int
|
||||
if p.version >= 6 {
|
||||
height = p.int()
|
||||
}
|
||||
|
||||
// we should never see an empty package name
|
||||
if name == "" {
|
||||
@ -298,6 +302,18 @@ func (p *importer) pkg() *types.Pkg {
|
||||
p.formatErrorf("package path %q for pkg index %d", path, len(p.pkgList))
|
||||
}
|
||||
|
||||
if p.version >= 6 {
|
||||
if height < 0 || height >= types.MaxPkgHeight {
|
||||
p.formatErrorf("bad package height %v for package %s", height, name)
|
||||
}
|
||||
|
||||
// reexported packages should always have a lower height than
|
||||
// the main package
|
||||
if len(p.pkgList) != 0 && height >= p.imp.Height {
|
||||
p.formatErrorf("package %q (height %d) reexports package %q (height %d)", p.imp.Path, p.imp.Height, path, height)
|
||||
}
|
||||
}
|
||||
|
||||
// add package to pkgList
|
||||
pkg := p.imp
|
||||
if path != "" {
|
||||
@ -313,6 +329,7 @@ func (p *importer) pkg() *types.Pkg {
|
||||
yyerror("import %q: package depends on %q (import cycle)", p.imp.Path, path)
|
||||
errorexit()
|
||||
}
|
||||
pkg.Height = height
|
||||
p.pkgList = append(p.pkgList, pkg)
|
||||
|
||||
return pkg
|
||||
|
@ -141,6 +141,11 @@ func Main(archInit func(*Arch)) {
|
||||
localpkg = types.NewPkg("", "")
|
||||
localpkg.Prefix = "\"\""
|
||||
|
||||
// We won't know localpkg's height until after import
|
||||
// processing. In the mean time, set to MaxPkgHeight to ensure
|
||||
// height comparisons at least work until then.
|
||||
localpkg.Height = types.MaxPkgHeight
|
||||
|
||||
// pseudo-package, for scoping
|
||||
builtinpkg = types.NewPkg("go.builtin", "") // TODO(gri) name this package go.builtin?
|
||||
builtinpkg.Prefix = "go.builtin" // not go%2ebuiltin
|
||||
@ -925,6 +930,10 @@ func loadsys() {
|
||||
inimport = false
|
||||
}
|
||||
|
||||
// myheight tracks the local package's height based on packages
|
||||
// imported so far.
|
||||
var myheight int
|
||||
|
||||
func importfile(f *Val) *types.Pkg {
|
||||
path_, ok := f.U.(string)
|
||||
if !ok {
|
||||
@ -1117,6 +1126,10 @@ func importfile(f *Val) *types.Pkg {
|
||||
errorexit()
|
||||
}
|
||||
|
||||
if importpkg.Height >= myheight {
|
||||
myheight = importpkg.Height + 1
|
||||
}
|
||||
|
||||
return importpkg
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,8 @@ func parseFiles(filenames []string) uint {
|
||||
testdclstack()
|
||||
}
|
||||
|
||||
localpkg.Height = myheight
|
||||
|
||||
return lines
|
||||
}
|
||||
|
||||
|
@ -15,14 +15,24 @@ import (
|
||||
// pkgMap maps a package path to a package.
|
||||
var pkgMap = make(map[string]*Pkg)
|
||||
|
||||
// MaxPkgHeight is a height greater than any likely package height.
|
||||
const MaxPkgHeight = 1e9
|
||||
|
||||
type Pkg struct {
|
||||
Path string // string literal used in import statement, e.g. "runtime/internal/sys"
|
||||
Name string // package name, e.g. "sys"
|
||||
Pathsym *obj.LSym
|
||||
Prefix string // escaped path for use in symbol table
|
||||
Imported bool // export data of this package was parsed
|
||||
Direct bool // imported directly
|
||||
Syms map[string]*Sym
|
||||
Path string // string literal used in import statement, e.g. "runtime/internal/sys"
|
||||
Name string // package name, e.g. "sys"
|
||||
Prefix string // escaped path for use in symbol table
|
||||
Syms map[string]*Sym
|
||||
Pathsym *obj.LSym
|
||||
|
||||
// Height is the package's height in the import graph. Leaf
|
||||
// packages (i.e., packages with no imports) have height 0,
|
||||
// and all other packages have height 1 plus the maximum
|
||||
// height of their imported packages.
|
||||
Height int
|
||||
|
||||
Imported bool // export data of this package was parsed
|
||||
Direct bool // imported directly
|
||||
}
|
||||
|
||||
// NewPkg returns a new Pkg for the given package path and name.
|
||||
|
@ -102,10 +102,10 @@ func BImportData(fset *token.FileSet, imports map[string]*types.Package, data []
|
||||
|
||||
// read version specific flags - extend as necessary
|
||||
switch p.version {
|
||||
// case 6:
|
||||
// case 7:
|
||||
// ...
|
||||
// fallthrough
|
||||
case 5, 4, 3, 2, 1:
|
||||
case 6, 5, 4, 3, 2, 1:
|
||||
p.debugFormat = p.rawStringln(p.rawByte()) == "debug"
|
||||
p.trackAllTypes = p.int() != 0
|
||||
p.posInfoFormat = p.int() != 0
|
||||
@ -182,6 +182,9 @@ func (p *importer) pkg() *types.Package {
|
||||
} else {
|
||||
path = p.string()
|
||||
}
|
||||
if p.version >= 6 {
|
||||
p.int() // package height; unused by go/types
|
||||
}
|
||||
|
||||
// we should never see an empty package name
|
||||
if name == "" {
|
||||
|
Loading…
Reference in New Issue
Block a user