aboutsummaryrefslogtreecommitdiff
path: root/src/go/types/object.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/go/types/object.go')
-rw-r--r--src/go/types/object.go105
1 files changed, 56 insertions, 49 deletions
diff --git a/src/go/types/object.go b/src/go/types/object.go
index 6c0c5c4a24..3c44348696 100644
--- a/src/go/types/object.go
+++ b/src/go/types/object.go
@@ -25,7 +25,7 @@ type Object interface {
Name() string // package local object name
Type() Type // object type
Exported() bool // reports whether the name starts with a capital letter
- Id() string // object id (see Id below)
+ Id() string // object name if exported, qualified name if not exported (see func Id)
// String returns a human-readable string of the object.
String() string
@@ -64,15 +64,10 @@ func Id(pkg *Package, name string) string {
// inside a package and outside a package - which breaks some
// tests)
path := "_"
- // TODO(gri): shouldn't !ast.IsExported(name) => pkg != nil be an precondition?
- // if pkg == nil {
- // panic("nil package in lookup of unexported name")
- // }
- if pkg != nil {
+ // pkg is nil for objects in Universe scope and possibly types
+ // introduced via Eval (see also comment in object.sameId)
+ if pkg != nil && pkg.path != "" {
path = pkg.path
- if path == "" {
- path = "_"
- }
}
return path + "." + name
}
@@ -154,7 +149,7 @@ func NewConst(pos token.Pos, pkg *Package, name string, typ Type, val constant.V
func (obj *Const) Val() constant.Value { return obj.val }
func (*Const) isDependency() {} // a constant may be a dependency of an initialization expression
-// A TypeName represents a declared type.
+// A TypeName represents a name for a (named or alias) type.
type TypeName struct {
object
}
@@ -163,6 +158,26 @@ func NewTypeName(pos token.Pos, pkg *Package, name string, typ Type) *TypeName {
return &TypeName{object{nil, pos, pkg, name, typ, 0, token.NoPos}}
}
+// IsAlias reports whether obj is an alias name for a type.
+func (obj *TypeName) IsAlias() bool {
+ switch t := obj.typ.(type) {
+ case nil:
+ return false
+ case *Basic:
+ // Any user-defined type name for a basic type is an alias for a
+ // basic type (because basic types are pre-declared in the Universe
+ // scope, outside any package scope), and so is any type name with
+ // a different name than the name of the basic type it refers to.
+ // Additionaly, we need to look for "byte" and "rune" because they
+ // are aliases but have the same names (for better error messages).
+ return obj.pkg != nil || t.name != obj.name || t == universeByte || t == universeRune
+ case *Named:
+ return obj != t.obj
+ default:
+ return true
+ }
+}
+
// A Variable represents a declared variable (including function parameters and results, and struct fields).
type Var struct {
object
@@ -215,28 +230,6 @@ func (obj *Func) FullName() string {
func (obj *Func) Scope() *Scope { return obj.typ.(*Signature).scope }
func (*Func) isDependency() {} // a function may be a dependency of an initialization expression
-// An Alias represents a declared alias.
-type disabledAlias struct {
- object
- orig Object // aliased constant, type, variable, or function; never an alias
- kind token.Token // token.CONST, token.TYPE, token.VAR, or token.FUNC (only needed during resolve phase)
-}
-
-func disabledNewAlias(pos token.Pos, pkg *Package, name string, orig Object) *disabledAlias {
- var typ Type = Typ[Invalid]
- if orig != nil {
- typ = orig.Type()
- }
- // No need to set a valid Alias.kind - that field is only used during identifier
- // resolution (1st type-checker pass). We could store the field outside but it's
- // easier to keep it here.
- return &disabledAlias{object{nil, pos, pkg, name, typ, 0, token.NoPos}, orig, token.ILLEGAL}
-}
-
-// Orig returns the aliased object, or nil if there was an error.
-// The returned object is never an Alias.
-func (obj *disabledAlias) disabledOrig() Object { return obj.orig }
-
// A Label represents a declared label.
type Label struct {
object
@@ -264,7 +257,9 @@ type Nil struct {
}
func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
+ var tname *TypeName
typ := obj.Type()
+
switch obj := obj.(type) {
case *PkgName:
fmt.Fprintf(buf, "package %s", obj.Name())
@@ -277,8 +272,8 @@ func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
buf.WriteString("const")
case *TypeName:
+ tname = obj
buf.WriteString("type")
- typ = typ.Underlying()
case *Var:
if obj.isField {
@@ -295,10 +290,6 @@ func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
}
return
- // Alias-related code. Keep for now.
- // case *Alias:
- // buf.WriteString("alias")
-
case *Label:
buf.WriteString("label")
typ = nil
@@ -322,10 +313,27 @@ func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
writePackage(buf, obj.Pkg(), qf)
}
buf.WriteString(obj.Name())
- if typ != nil {
- buf.WriteByte(' ')
- WriteType(buf, typ, qf)
+
+ if typ == nil {
+ return
+ }
+
+ if tname != nil {
+ // We have a type object: Don't print anything more for
+ // basic types since there's no more information (names
+ // are the same; see also comment in TypeName.IsAlias).
+ if _, ok := typ.(*Basic); ok {
+ return
+ }
+ if tname.IsAlias() {
+ buf.WriteString(" =")
+ } else {
+ typ = typ.Underlying()
+ }
}
+
+ buf.WriteByte(' ')
+ WriteType(buf, typ, qf)
}
func writePackage(buf *bytes.Buffer, pkg *Package, qf Qualifier) {
@@ -353,15 +361,14 @@ func ObjectString(obj Object, qf Qualifier) string {
return buf.String()
}
-func (obj *PkgName) String() string { return ObjectString(obj, nil) }
-func (obj *Const) String() string { return ObjectString(obj, nil) }
-func (obj *TypeName) String() string { return ObjectString(obj, nil) }
-func (obj *Var) String() string { return ObjectString(obj, nil) }
-func (obj *Func) String() string { return ObjectString(obj, nil) }
-func (obj *disabledAlias) String() string { return ObjectString(obj, nil) }
-func (obj *Label) String() string { return ObjectString(obj, nil) }
-func (obj *Builtin) String() string { return ObjectString(obj, nil) }
-func (obj *Nil) String() string { return ObjectString(obj, nil) }
+func (obj *PkgName) String() string { return ObjectString(obj, nil) }
+func (obj *Const) String() string { return ObjectString(obj, nil) }
+func (obj *TypeName) String() string { return ObjectString(obj, nil) }
+func (obj *Var) String() string { return ObjectString(obj, nil) }
+func (obj *Func) String() string { return ObjectString(obj, nil) }
+func (obj *Label) String() string { return ObjectString(obj, nil) }
+func (obj *Builtin) String() string { return ObjectString(obj, nil) }
+func (obj *Nil) String() string { return ObjectString(obj, nil) }
func writeFuncName(buf *bytes.Buffer, f *Func, qf Qualifier) {
if f.typ != nil {