Commit a0d20102 authored by Robert Griesemer's avatar Robert Griesemer

cmd/compile: implement fmt.Formatter for *Sym formats %s, %v

Change-Id: I0c362edba66c763e84990e3c5508013021f3e6fe
Reviewed-on: https://go-review.googlesource.com/28334Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
parent 8d0bbe2b
...@@ -469,7 +469,7 @@ func (p *importer) typ() *Type { ...@@ -469,7 +469,7 @@ func (p *importer) typ() *Type {
// during import unexported method names should be in the type's package // during import unexported method names should be in the type's package
if !exportname(sym.Name) && sym.Pkg != tsym.Pkg { if !exportname(sym.Name) && sym.Pkg != tsym.Pkg {
Fatalf("imported method name %v in wrong package %s\n", sconv(sym, FmtSign), tsym.Pkg.Name) Fatalf("imported method name %+v in wrong package %s\n", sym, tsym.Pkg.Name)
} }
recv := p.paramList() // TODO(gri) do we need a full param list for the receiver? recv := p.paramList() // TODO(gri) do we need a full param list for the receiver?
......
...@@ -542,7 +542,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node { ...@@ -542,7 +542,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node {
if exportname(meth.Name) { if exportname(meth.Name) {
p = fmt.Sprintf("(%-1v).%s-fm", rcvrtype, meth.Name) p = fmt.Sprintf("(%-1v).%s-fm", rcvrtype, meth.Name)
} else { } else {
p = fmt.Sprintf("(%-1v).(%v)-fm", rcvrtype, sconv(meth, FmtLeft)) p = fmt.Sprintf("(%-1v).(%-v)-fm", rcvrtype, meth)
} }
basetype := rcvrtype basetype := rcvrtype
if rcvrtype.IsPtr() { if rcvrtype.IsPtr() {
......
...@@ -213,7 +213,7 @@ var goopnames = []string{ ...@@ -213,7 +213,7 @@ var goopnames = []string{
} }
func (o Op) String() string { func (o Op) String() string {
return fmt.Sprintf("%v", o) return fmt.Sprint(o)
} }
func (o Op) GoString() string { func (o Op) GoString() string {
...@@ -518,28 +518,34 @@ func (et EType) String() string { ...@@ -518,28 +518,34 @@ func (et EType) String() string {
} }
// Fmt "%S": syms // Fmt "%S": syms
func (p *printer) symfmt(s *Sym, flag FmtFlag) *printer { func (s *Sym) symfmt(f fmt.State, flag FmtFlag) {
if s.Pkg != nil && flag&FmtShort == 0 { if s.Pkg != nil && flag&FmtShort == 0 {
switch fmtmode { switch fmtmode {
case FErr: // This is for the user case FErr: // This is for the user
if s.Pkg == builtinpkg || s.Pkg == localpkg { if s.Pkg == builtinpkg || s.Pkg == localpkg {
return p.s(s.Name) fmt.Fprint(f, s.Name)
return
} }
// If the name was used by multiple packages, display the full path, // If the name was used by multiple packages, display the full path,
if s.Pkg.Name != "" && numImport[s.Pkg.Name] > 1 { if s.Pkg.Name != "" && numImport[s.Pkg.Name] > 1 {
return p.f("%q.%s", s.Pkg.Path, s.Name) fmt.Fprintf(f, "%q.%s", s.Pkg.Path, s.Name)
return
} }
return p.s(s.Pkg.Name + "." + s.Name) fmt.Fprint(f, s.Pkg.Name+"."+s.Name)
return
case FDbg: case FDbg:
return p.s(s.Pkg.Name + "." + s.Name) fmt.Fprint(f, s.Pkg.Name+"."+s.Name)
return
case FTypeId: case FTypeId:
if flag&FmtUnsigned != 0 { if flag&FmtUnsigned != 0 {
return p.s(s.Pkg.Name + "." + s.Name) // dcommontype, typehash fmt.Fprint(f, s.Pkg.Name+"."+s.Name) // dcommontype, typehash
return
} }
return p.s(s.Pkg.Prefix + "." + s.Name) // (methodsym), typesym, weaksym fmt.Fprint(f, s.Pkg.Prefix+"."+s.Name) // (methodsym), typesym, weaksym
return
} }
} }
...@@ -552,13 +558,15 @@ func (p *printer) symfmt(s *Sym, flag FmtFlag) *printer { ...@@ -552,13 +558,15 @@ func (p *printer) symfmt(s *Sym, flag FmtFlag) *printer {
} }
if fmtmode == FDbg { if fmtmode == FDbg {
return p.f("@%q.%s", s.Pkg.Path, name) fmt.Fprintf(f, "@%q.%s", s.Pkg.Path, name)
return
} }
return p.s(name) fmt.Fprint(f, name)
return
} }
return p.s(s.Name) fmt.Fprint(f, s.Name)
} }
var basicnames = []string{ var basicnames = []string{
...@@ -611,15 +619,15 @@ func (t *Type) typefmt(s fmt.State, flag FmtFlag) { ...@@ -611,15 +619,15 @@ func (t *Type) typefmt(s fmt.State, flag FmtFlag) {
case FTypeId: case FTypeId:
if flag&FmtShort != 0 { if flag&FmtShort != 0 {
if t.Vargen != 0 { if t.Vargen != 0 {
fmt.Fprintf(s, "%v·%d", sconv(t.Sym, FmtShort), t.Vargen) fmt.Fprintf(s, "%1v·%d", t.Sym, t.Vargen)
return return
} }
fmt.Fprint(s, sconv(t.Sym, FmtShort)) fmt.Fprintf(s, "%1v", t.Sym)
return return
} }
if flag&FmtUnsigned != 0 { if flag&FmtUnsigned != 0 {
fmt.Fprint(s, sconv(t.Sym, FmtUnsigned)) fmt.Fprintf(s, "% v", t.Sym)
return return
} }
...@@ -629,7 +637,7 @@ func (t *Type) typefmt(s fmt.State, flag FmtFlag) { ...@@ -629,7 +637,7 @@ func (t *Type) typefmt(s fmt.State, flag FmtFlag) {
} }
} }
fmt.Fprint(s, sconv(t.Sym, 0)) fmt.Fprint(s, t.Sym)
return return
} }
...@@ -705,9 +713,9 @@ func (t *Type) typefmt(s fmt.State, flag FmtFlag) { ...@@ -705,9 +713,9 @@ func (t *Type) typefmt(s fmt.State, flag FmtFlag) {
// Wrong interface definitions may have types lacking a symbol. // Wrong interface definitions may have types lacking a symbol.
break break
case exportname(f.Sym.Name): case exportname(f.Sym.Name):
fmt.Fprint(s, sconv(f.Sym, FmtShort)) fmt.Fprintf(s, "%1v", f.Sym)
default: default:
fmt.Fprint(s, sconv(f.Sym, FmtUnsigned)) fmt.Fprintf(s, "% v", f.Sym)
} }
fmt.Fprintf(s, "%1v", f.Type) fmt.Fprintf(s, "%1v", f.Type)
} }
...@@ -1167,7 +1175,7 @@ func (p *printer) exprfmt(n *Node, prec int) *printer { ...@@ -1167,7 +1175,7 @@ func (p *printer) exprfmt(n *Node, prec int) *printer {
return p.exprfmt(n.Orig, prec) return p.exprfmt(n.Orig, prec)
} }
if n.Sym != nil { if n.Sym != nil {
return p.sconv(n.Sym, 0) return p.s(n.Sym.String())
} }
} }
if n.Val().Ctype() == CTNIL && n.Orig != nil && n.Orig != n { if n.Val().Ctype() == CTNIL && n.Orig != nil && n.Orig != n {
...@@ -1194,11 +1202,11 @@ func (p *printer) exprfmt(n *Node, prec int) *printer { ...@@ -1194,11 +1202,11 @@ func (p *printer) exprfmt(n *Node, prec int) *printer {
fallthrough fallthrough
case OPACK, ONONAME: case OPACK, ONONAME:
return p.sconv(n.Sym, 0) return p.s(n.Sym.String())
case OTYPE: case OTYPE:
if n.Type == nil && n.Sym != nil { if n.Type == nil && n.Sym != nil {
return p.sconv(n.Sym, 0) return p.s(n.Sym.String())
} }
return p.f("%v", n.Type) return p.f("%v", n.Type)
...@@ -1288,14 +1296,14 @@ func (p *printer) exprfmt(n *Node, prec int) *printer { ...@@ -1288,14 +1296,14 @@ func (p *printer) exprfmt(n *Node, prec int) *printer {
if n.Right == nil || n.Right.Sym == nil { if n.Right == nil || n.Right.Sym == nil {
return p.s(".<nil>") return p.s(".<nil>")
} }
return p.f(".%v", sconv(n.Right.Sym, FmtShort|FmtByte)) return p.f(".%01v", n.Right.Sym)
case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH: case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
p.exprfmt(n.Left, nprec) p.exprfmt(n.Left, nprec)
if n.Sym == nil { if n.Sym == nil {
return p.s(".<nil>") return p.s(".<nil>")
} }
return p.f(".%v", sconv(n.Sym, FmtShort|FmtByte)) return p.f(".%01v", n.Sym)
case ODOTTYPE, ODOTTYPE2: case ODOTTYPE, ODOTTYPE2:
p.exprfmt(n.Left, nprec) p.exprfmt(n.Left, nprec)
...@@ -1559,42 +1567,44 @@ func (p *printer) nodedump(n *Node, flag FmtFlag) *printer { ...@@ -1559,42 +1567,44 @@ func (p *printer) nodedump(n *Node, flag FmtFlag) *printer {
return p return p
} }
func (s *Sym) Print(p *printer) { func (s *Sym) Format(f fmt.State, format rune) {
p.sconv(s, 0) switch format {
} case 's', 'v':
s.sconv(f)
var _ Printable = new(Sym) // verify that Sym implements Printable default:
fmt.Fprintf(f, "%%!%c(*Sym=%p)", format, s)
}
}
func (s *Sym) String() string { func (s *Sym) String() string {
return sconv(s, 0) return fmt.Sprint(s)
} }
// Fmt "%S": syms // Fmt "%S": syms
// Flags: "%hS" suppresses qualifying with package // Flags: "%hS" suppresses qualifying with package
func sconv(s *Sym, flag FmtFlag) string { func (s *Sym) sconv(f fmt.State) {
return new(printer).sconv(s, flag).String() flag := fmtFlag(f)
}
func (p *printer) sconv(s *Sym, flag FmtFlag) *printer {
if flag&FmtLong != 0 { if flag&FmtLong != 0 {
panic("linksymfmt") panic("linksymfmt")
} }
if s == nil { if s == nil {
return p.s("<S>") fmt.Fprint(f, "<S>")
return
} }
if s.Name == "_" { if s.Name == "_" {
return p.s("_") fmt.Fprint(f, "_")
return
} }
sf := flag sf := flag
sm := setfmode(&flag) sm := setfmode(&flag)
p.symfmt(s, flag) s.symfmt(f, flag)
flag = sf flag = sf
fmtmode = sm fmtmode = sm
return p
} }
func (t *Type) String() string { func (t *Type) String() string {
...@@ -1641,12 +1651,12 @@ func Fldconv(f *Field, flag FmtFlag) string { ...@@ -1641,12 +1651,12 @@ func Fldconv(f *Field, flag FmtFlag) string {
if f.Funarg != FunargNone { if f.Funarg != FunargNone {
name = Nconv(f.Nname, 0) name = Nconv(f.Nname, 0)
} else if flag&FmtLong != 0 { } else if flag&FmtLong != 0 {
name = sconv(s, FmtShort|FmtByte) name = fmt.Sprintf("%01v", s)
if !exportname(name) && flag&FmtUnsigned == 0 { if !exportname(name) && flag&FmtUnsigned == 0 {
name = sconv(s, 0) // qualify non-exported names (used on structs, not on funarg) name = s.String() // qualify non-exported names (used on structs, not on funarg)
} }
} else { } else {
name = sconv(s, 0) name = s.String()
} }
} }
} }
...@@ -1759,7 +1769,7 @@ func (p *printer) Nconv(n *Node, flag FmtFlag) *printer { ...@@ -1759,7 +1769,7 @@ func (p *printer) Nconv(n *Node, flag FmtFlag) *printer {
dumpdepth-- dumpdepth--
default: default:
Fatalf("unhandled %%N mode") Fatalf("unhandled %%N mode: %d", fmtmode)
} }
flag = sf flag = sf
......
...@@ -861,7 +861,7 @@ OpSwitch: ...@@ -861,7 +861,7 @@ OpSwitch:
} }
if n.Type.Etype != TFUNC || n.Type.Recv() == nil { if n.Type.Etype != TFUNC || n.Type.Recv() == nil {
Yyerror("type %v has no method %v", n.Left.Type, sconv(n.Right.Sym, FmtShort)) Yyerror("type %v has no method %1v", n.Left.Type, n.Right.Sym)
n.Type = nil n.Type = nil
return n return n
} }
...@@ -2372,7 +2372,7 @@ func looktypedot(n *Node, t *Type, dostrcmp int) bool { ...@@ -2372,7 +2372,7 @@ func looktypedot(n *Node, t *Type, dostrcmp int) bool {
// disallow T.m if m requires *T receiver // disallow T.m if m requires *T receiver
if f2.Type.Recv().Type.IsPtr() && !t.IsPtr() && f2.Embedded != 2 && !isifacemethod(f2.Type) { if f2.Type.Recv().Type.IsPtr() && !t.IsPtr() && f2.Embedded != 2 && !isifacemethod(f2.Type) {
Yyerror("invalid method expression %v (needs pointer receiver: (*%v).%v)", n, t, sconv(f2.Sym, FmtShort)) Yyerror("invalid method expression %v (needs pointer receiver: (*%v).%1v)", n, t, f2.Sym)
return false return false
} }
......
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