]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: include package import path in NamedType.String().
authorAlan Donovan <adonovan@google.com>
Tue, 19 Feb 2013 19:42:05 +0000 (14:42 -0500)
committerAlan Donovan <adonovan@google.com>
Tue, 19 Feb 2013 19:42:05 +0000 (14:42 -0500)
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

src/pkg/exp/ssa/builder.go
src/pkg/exp/ssa/func.go
src/pkg/go/types/errors.go

index 3dcc16f22ea213ff41836bf17c8036a58ee19cb6..810f7840c46d9fc7902c5e19fa70b2e16689b84c 100644 (file)
@@ -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,
index dca3ca75104df0177de4a031ff9f21be0cef3ddc..f48c66aab93faca623400ea8f0227253ca4bd616 100644 (file)
@@ -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 {
index c8b420b4db6939b2b546446371e1e8caacc40ef7..6dd32849379c107f6fbd96e818f0162fe85ae749 100644 (file)
@@ -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)