Commit a17c4616 authored by Alan Donovan's avatar Alan Donovan

go/types: include package import path in NamedType.String().

This avoids ambiguity and makes the diagnostics closer to
those issued by gc, but it is more verbose since it qualifies
intra-package references.

Without extra context---e.g. a 'from *Package' parameter to
Type.String()---we are forced to err on one side or the other.

Also, cosmetic changes to exp/ssa:
- Remove package-qualification workaround in Function.FullName.
- Always set go/types.Package.Path field to the import path,
  since we know the correct path at this point.
- In Function.DumpTo, show variadic '...' and result type info,
  and delete now-redundant "# Type: " line.

R=gri
CC=golang-dev
https://golang.org/cl/7325051
parent 5c3fb96b
......@@ -2570,11 +2570,13 @@ func (b *Builder) CreatePackage(importPath string, files []*ast.File) (*Package,
// from the gc compiler's object files; no code will be available.
//
func (b *Builder) createPackageImpl(typkg *types.Package, importPath string, files []*ast.File) *Package {
// TODO(gri): make this an invariant and eliminate importPath
// param and Package field.
// if importPath != p.Types.Path {
// panic(importPath + " != " + p.Types.Path)
// }
// The typechecker sets types.Package.Path only for GcImported
// packages, since it doesn't know import path until after typechecking is done.
// Here we ensure it is always set, since we know the correct path.
// TODO(adonovan): eliminate redundant ssa.Package.ImportPath field.
if typkg.Path == "" {
typkg.Path = importPath
}
p := &Package{
Prog: b.Prog,
......
......@@ -255,6 +255,7 @@ func (f *Function) finish() {
}
}
}
optimizeBlocks(f)
// Build immediate-use (referrers) graph.
......@@ -351,8 +352,11 @@ func (f *Function) emit(instr Instruction) Value {
// FullName returns the full name of this function, qualified by
// package name, receiver type, etc.
//
// The specific formatting rules are not guaranteed and may change.
//
// Examples:
// "math.IsNaN" // a package-level function
// "IsNaN" // intra-package reference to same
// "(*sync.WaitGroup).Add" // a declared method
// "(*exp/ssa.Ret).Block" // a bridge method
// "(ssa.Instruction).Block" // an interface method thunk
......@@ -379,27 +383,20 @@ func (f *Function) fullName(from *Package) string {
} else {
recvType = f.Params[0].Type() // interface method thunk
}
// TODO(adonovan): print type package-qualified, if NamedType.
return fmt.Sprintf("(%s).%s", recvType, f.Name_)
}
// "pkg." prefix for cross-package references only.
var pkgQual string
if from != f.Pkg {
pkgQual = f.Pkg.ImportPath + "."
}
// Declared method?
if recv != nil {
star := ""
if isPointer(recv.Type) {
star = "*"
}
return fmt.Sprintf("(%s%s%s).%s", star, pkgQual, deref(recv.Type), f.Name_)
return fmt.Sprintf("(%s).%s", recv.Type, f.Name_)
}
// Package-level function.
return pkgQual + f.Name_
// Prefix with package name for cross-package references only.
if from != f.Pkg {
return fmt.Sprintf("%s.%s", f.Pkg.ImportPath, f.Name_)
}
return f.Name_
}
// DumpTo prints to w a human readable "disassembly" of the SSA code of
......@@ -408,7 +405,6 @@ func (f *Function) fullName(from *Package) string {
func (f *Function) DumpTo(w io.Writer) {
fmt.Fprintf(w, "# Name: %s\n", f.FullName())
fmt.Fprintf(w, "# Declared at %s\n", f.Prog.Files.Position(f.Pos))
fmt.Fprintf(w, "# Type: %s\n", f.Signature)
if f.Enclosing != nil {
fmt.Fprintf(w, "# Parent: %s\n", f.Enclosing.Name())
......@@ -421,6 +417,7 @@ func (f *Function) DumpTo(w io.Writer) {
}
}
// Function Signature in declaration syntax; derived from types.Signature.String().
io.WriteString(w, "func ")
params := f.Params
if f.Signature.Recv != nil {
......@@ -435,9 +432,23 @@ func (f *Function) DumpTo(w io.Writer) {
}
io.WriteString(w, v.Name())
io.WriteString(w, " ")
if f.Signature.IsVariadic && i == len(params)-1 {
io.WriteString(w, "...")
}
io.WriteString(w, v.Type().String())
}
io.WriteString(w, "):\n")
io.WriteString(w, ")")
if res := f.Signature.Results; res != nil {
io.WriteString(w, " ")
var t types.Type
if len(res) == 1 && res[0].Name == "" {
t = res[0].Type
} else {
t = &types.Result{Values: res}
}
io.WriteString(w, t.String())
}
io.WriteString(w, ":\n")
for _, b := range f.Blocks {
if b == nil {
......
......@@ -307,7 +307,11 @@ func writeType(buf *bytes.Buffer, typ Type) {
case *NamedType:
s := "<NamedType w/o object>"
if t.Obj != nil {
if obj := t.Obj; obj != nil {
if obj.Pkg != nil && obj.Pkg.Path != "" {
buf.WriteString(obj.Pkg.Path)
buf.WriteString(".")
}
s = t.Obj.GetName()
}
buf.WriteString(s)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment