]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: export QualifiedName.IsSame and NamedType.AstObj
authorRobert Griesemer <gri@golang.org>
Fri, 11 Jan 2013 22:55:49 +0000 (14:55 -0800)
committerRobert Griesemer <gri@golang.org>
Fri, 11 Jan 2013 22:55:49 +0000 (14:55 -0800)
R=adonovan
CC=golang-dev
https://golang.org/cl/7103047

src/pkg/go/types/check.go
src/pkg/go/types/errors.go
src/pkg/go/types/expr.go
src/pkg/go/types/operand.go
src/pkg/go/types/predicates.go
src/pkg/go/types/types.go
src/pkg/go/types/universe.go

index 158941b05329928352d9b7555ae274743a1225e0..bf28ca12da642536a9a40dd62ece2af37c907f3d 100644 (file)
@@ -163,7 +163,7 @@ func (check *checker) object(obj *ast.Object, cycleOk bool) {
                check.valueSpec(spec.Pos(), obj, spec.Names, init.Type, init.Values, iota)
 
        case ast.Typ:
-               typ := &NamedType{obj: obj}
+               typ := &NamedType{AstObj: obj}
                obj.Type = typ // "mark" object so recursion terminates
                typ.Underlying = underlying(check.typ(obj.Decl.(*ast.TypeSpec).Type, cycleOk))
                // typecheck associated method signatures
@@ -194,7 +194,7 @@ func (check *checker) object(obj *ast.Object, cycleOk bool) {
                                params, _ := check.collectParams(mdecl.Recv, false)
                                sig.Recv = params[0] // the parser/assocMethod ensure there is exactly one parameter
                                obj.Type = sig
-                               methods = append(methods, &Method{QualifiedName{check.pkg, obj.Name}, sig})
+                               methods = append(methods, &Method{QualifiedName{nil, obj.Name}, sig})
                                check.later(obj, sig, mdecl.Body)
                        }
                        typ.Methods = methods
index 96446949b4c87529befdf46fdcc11335c27de594..b2a66e4dd207c3d02730a8dba894116d97842b18 100644 (file)
@@ -313,10 +313,10 @@ func writeType(buf *bytes.Buffer, typ Type) {
        case *NamedType:
                var s string
                switch {
-               case t.obj != nil:
-                       s = t.obj.Name
                case t.Obj != nil:
                        s = t.Obj.GetName()
+               case t.AstObj != nil:
+                       s = t.AstObj.Name
                default:
                        s = "<NamedType w/o object>"
                }
index 99a038e26d8e6177e6c03056cf4a658d4e059fbe..c6fa84dda7fca976c098827bda864cb91743f662 100644 (file)
@@ -84,7 +84,7 @@ func (check *checker) collectMethods(list *ast.FieldList) (methods []*Method) {
                                continue
                        }
                        for _, name := range f.Names {
-                               methods = append(methods, &Method{QualifiedName{check.pkg, name.Name}, sig})
+                               methods = append(methods, &Method{QualifiedName{nil, name.Name}, sig})
                        }
                } else {
                        // embedded interface
@@ -137,24 +137,24 @@ func (check *checker) collectFields(list *ast.FieldList, cycleOk bool) (fields [
                if len(f.Names) > 0 {
                        // named fields
                        for _, name := range f.Names {
-                               fields = append(fields, &Field{QualifiedName{check.pkg, name.Name}, typ, tag, false})
+                               fields = append(fields, &Field{QualifiedName{nil, name.Name}, typ, tag, false})
                        }
                } else {
                        // anonymous field
                        switch t := deref(typ).(type) {
                        case *Basic:
-                               fields = append(fields, &Field{QualifiedName{check.pkg, t.Name}, typ, tag, true})
+                               fields = append(fields, &Field{QualifiedName{nil, t.Name}, typ, tag, true})
                        case *NamedType:
                                var name string
                                switch {
-                               case t.obj != nil:
-                                       name = t.obj.Name
                                case t.Obj != nil:
                                        name = t.Obj.GetName()
+                               case t.AstObj != nil:
+                                       name = t.AstObj.Name
                                default:
                                        unreachable()
                                }
-                               fields = append(fields, &Field{QualifiedName{check.pkg, name}, typ, tag, true})
+                               fields = append(fields, &Field{QualifiedName{nil, name}, typ, tag, true})
                        default:
                                if typ != Typ[Invalid] {
                                        check.invalidAST(f.Type.Pos(), "anonymous field type %s must be named", typ)
@@ -913,7 +913,7 @@ func (check *checker) rawExpr(x *operand, e ast.Expr, hint Type, iota int, cycle
                if x.mode == invalid {
                        goto Error
                }
-               mode, typ := lookupField(x.typ, QualifiedName{check.pkg, sel})
+               mode, typ := lookupField(x.typ, QualifiedName{nil, sel})
                if mode == invalid {
                        check.invalidOp(e.Pos(), "%s has no single field or method %s", x, sel)
                        goto Error
index 77aacacdc9a5d1272ca24e64428221937ad93cfd..1c8f35291eb812c54052d8873026fd823f53530e 100644 (file)
@@ -265,11 +265,11 @@ func lookupFieldBreadthFirst(list []embeddedType, name QualifiedName) (res looku
                        visited[typ] = true
 
                        // look for a matching attached method
-                       if typ.obj != nil {
-                               assert(typ.obj.Data == nil) // methods must have been moved to typ.Methods
+                       if typ.AstObj != nil {
+                               assert(typ.AstObj.Data == nil) // methods must have been moved to typ.Methods
                        }
                        for _, m := range typ.Methods {
-                               if identicalNames(name, m.QualifiedName) {
+                               if name.IsSame(m.QualifiedName) {
                                        assert(m.Type != nil)
                                        if !potentialMatch(e.multiples, value, m.Type) {
                                                return // name collision
@@ -281,7 +281,7 @@ func lookupFieldBreadthFirst(list []embeddedType, name QualifiedName) (res looku
                        case *Struct:
                                // look for a matching field and collect embedded types
                                for _, f := range t.Fields {
-                                       if identicalNames(name, f.QualifiedName) {
+                                       if name.IsSame(f.QualifiedName) {
                                                assert(f.Type != nil)
                                                if !potentialMatch(e.multiples, variable, f.Type) {
                                                        return // name collision
@@ -305,7 +305,7 @@ func lookupFieldBreadthFirst(list []embeddedType, name QualifiedName) (res looku
                        case *Interface:
                                // look for a matching method
                                for _, m := range t.Methods {
-                                       if identicalNames(name, m.QualifiedName) {
+                                       if name.IsSame(m.QualifiedName) {
                                                assert(m.Type != nil)
                                                if !potentialMatch(e.multiples, value, m.Type) {
                                                        return // name collision
@@ -355,11 +355,11 @@ func lookupField(typ Type, name QualifiedName) (operandMode, Type) {
        typ = deref(typ)
 
        if t, ok := typ.(*NamedType); ok {
-               if t.obj != nil {
-                       assert(t.obj.Data == nil) // methods must have been moved to t.Methods
+               if t.AstObj != nil {
+                       assert(t.AstObj.Data == nil) // methods must have been moved to t.Methods
                }
                for _, m := range t.Methods {
-                       if identicalNames(name, m.QualifiedName) {
+                       if name.IsSame(m.QualifiedName) {
                                assert(m.Type != nil)
                                return value, m.Type
                        }
@@ -371,7 +371,7 @@ func lookupField(typ Type, name QualifiedName) (operandMode, Type) {
        case *Struct:
                var next []embeddedType
                for _, f := range t.Fields {
-                       if identicalNames(name, f.QualifiedName) {
+                       if name.IsSame(f.QualifiedName) {
                                return variable, f.Type
                        }
                        if f.IsAnonymous {
@@ -388,7 +388,7 @@ func lookupField(typ Type, name QualifiedName) (operandMode, Type) {
 
        case *Interface:
                for _, m := range t.Methods {
-                       if identicalNames(name, m.QualifiedName) {
+                       if name.IsSame(m.QualifiedName) {
                                return value, m.Type
                        }
                }
index b16b8ce7b06898602bc82f537bbaf7914635f90f..e8ffb3647783cde824a7a8d0b3dd67376f814279 100644 (file)
@@ -6,8 +6,6 @@
 
 package types
 
-import "go/ast"
-
 func isNamed(typ Type) bool {
        if _, ok := typ.(*Basic); ok {
                return ok
@@ -131,7 +129,7 @@ func isIdentical(x, y Type) bool {
                        if len(x.Fields) == len(y.Fields) {
                                for i, f := range x.Fields {
                                        g := y.Fields[i]
-                                       if !identicalNames(f.QualifiedName, g.QualifiedName) ||
+                                       if !f.QualifiedName.IsSame(g.QualifiedName) ||
                                                !isIdentical(f.Type, g.Type) ||
                                                f.Tag != g.Tag ||
                                                f.IsAnonymous != g.IsAnonymous {
@@ -185,10 +183,10 @@ func isIdentical(x, y Type) bool {
                // in the same type declaration.
                if y, ok := y.(*NamedType); ok {
                        switch {
-                       case x.obj != nil:
-                               return x.obj == y.obj
                        case x.Obj != nil:
                                return x.Obj == y.Obj
+                       case x.AstObj != nil:
+                               return x.AstObj == y.AstObj
                        default:
                                unreachable()
                        }
@@ -198,17 +196,6 @@ func isIdentical(x, y Type) bool {
        return false
 }
 
-// identicalNames returns true if the names a and b are equal.
-func identicalNames(a, b QualifiedName) bool {
-       if a.Name != b.Name {
-               return false
-       }
-       // a.Name == b.Name
-       // TODO(gri) Guarantee that packages are canonicalized
-       //           and then we can compare p == q directly.
-       return ast.IsExported(a.Name) || a.Pkg.Path == b.Pkg.Path
-}
-
 // identicalTypes returns true if both lists a and b have the
 // same length and corresponding objects have identical types.
 func identicalTypes(a, b []*Var) bool {
index 69ea32701db2560d46b58bc21838db89d6d1165a..fa120fd9e95e25189346c19dfd69204838631911 100644 (file)
@@ -91,12 +91,37 @@ type Slice struct {
        Elt Type
 }
 
-// A QualifiedName is a name qualified with the package the declared the name.
+// A QualifiedName is a name qualified with the package that declared the name.
 type QualifiedName struct {
-       Pkg  *Package // Pkg.Path == "" for current (non-imported) package
+       Pkg  *Package // nil for current (non-imported) package
        Name string   // unqualified type name for anonymous fields
 }
 
+// IsSame reports whether p and q are the same.
+func (p QualifiedName) IsSame(q QualifiedName) bool {
+       // spec:
+       // "Two identifiers are different if they are spelled differently,
+       // or if they appear in different packages and are not exported.
+       // Otherwise, they are the same."
+       if p.Name != q.Name {
+               return false
+       }
+       // p.Name == q.Name
+       if !ast.IsExported(p.Name) {
+               // TODO(gri) just compare packages once we guarantee that they are canonicalized
+               pp := ""
+               if p.Pkg != nil {
+                       pp = p.Pkg.Path
+               }
+               qp := ""
+               if q.Pkg != nil {
+                       qp = q.Pkg.Path
+               }
+               return pp == qp
+       }
+       return true
+}
+
 // A Field represents a field of a struct.
 type Field struct {
        QualifiedName
@@ -211,9 +236,9 @@ type Chan struct {
 // A NamedType represents a named type as declared in a type declaration.
 type NamedType struct {
        implementsType
-       // TODO(gri) remove obj once we have moved away from ast.Objects
-       obj        *ast.Object // corresponding declared object (current package)
+       // TODO(gri) remove AstObj once we have moved away from ast.Objects
        Obj        Object      // corresponding declared object (imported package)
+       AstObj     *ast.Object // corresponding declared object (current package)
        Underlying Type        // nil if not fully declared yet; never a *NamedType
        Methods    []*Method   // TODO(gri) consider keeping them in sorted order
 }
index bbc33795d98aa57a9aec6894c0ce442428c026a0..43fe39046a2e9ea15cd3ca9692ac658afcab5169 100644 (file)
@@ -159,7 +159,7 @@ func def(kind ast.ObjKind, name string, typ Type) *ast.Object {
                        obj.Decl = Universe
                        obj.Type = typ
                        if typ, ok := typ.(*NamedType); ok {
-                               typ.obj = obj
+                               typ.AstObj = obj
                        }
                        if Universe.Insert(obj) != nil {
                                panic("internal error: double declaration")