Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
8b62f54e
Commit
8b62f54e
authored
Jan 11, 2013
by
Robert Griesemer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
go/types: export QualifiedName.IsSame and NamedType.AstObj
R=adonovan CC=golang-dev
https://golang.org/cl/7103047
parent
20130f14
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
54 additions
and
42 deletions
+54
-42
src/pkg/go/types/check.go
src/pkg/go/types/check.go
+2
-2
src/pkg/go/types/errors.go
src/pkg/go/types/errors.go
+2
-2
src/pkg/go/types/expr.go
src/pkg/go/types/expr.go
+7
-7
src/pkg/go/types/operand.go
src/pkg/go/types/operand.go
+10
-10
src/pkg/go/types/predicates.go
src/pkg/go/types/predicates.go
+3
-16
src/pkg/go/types/types.go
src/pkg/go/types/types.go
+29
-4
src/pkg/go/types/universe.go
src/pkg/go/types/universe.go
+1
-1
No files found.
src/pkg/go/types/check.go
View file @
8b62f54e
...
@@ -163,7 +163,7 @@ func (check *checker) object(obj *ast.Object, cycleOk bool) {
...
@@ -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
)
check
.
valueSpec
(
spec
.
Pos
(),
obj
,
spec
.
Names
,
init
.
Type
,
init
.
Values
,
iota
)
case
ast
.
Typ
:
case
ast
.
Typ
:
typ
:=
&
NamedType
{
o
bj
:
obj
}
typ
:=
&
NamedType
{
AstO
bj
:
obj
}
obj
.
Type
=
typ
// "mark" object so recursion terminates
obj
.
Type
=
typ
// "mark" object so recursion terminates
typ
.
Underlying
=
underlying
(
check
.
typ
(
obj
.
Decl
.
(
*
ast
.
TypeSpec
)
.
Type
,
cycleOk
))
typ
.
Underlying
=
underlying
(
check
.
typ
(
obj
.
Decl
.
(
*
ast
.
TypeSpec
)
.
Type
,
cycleOk
))
// typecheck associated method signatures
// typecheck associated method signatures
...
@@ -194,7 +194,7 @@ func (check *checker) object(obj *ast.Object, cycleOk bool) {
...
@@ -194,7 +194,7 @@ func (check *checker) object(obj *ast.Object, cycleOk bool) {
params
,
_
:=
check
.
collectParams
(
mdecl
.
Recv
,
false
)
params
,
_
:=
check
.
collectParams
(
mdecl
.
Recv
,
false
)
sig
.
Recv
=
params
[
0
]
// the parser/assocMethod ensure there is exactly one parameter
sig
.
Recv
=
params
[
0
]
// the parser/assocMethod ensure there is exactly one parameter
obj
.
Type
=
sig
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
)
check
.
later
(
obj
,
sig
,
mdecl
.
Body
)
}
}
typ
.
Methods
=
methods
typ
.
Methods
=
methods
...
...
src/pkg/go/types/errors.go
View file @
8b62f54e
...
@@ -313,10 +313,10 @@ func writeType(buf *bytes.Buffer, typ Type) {
...
@@ -313,10 +313,10 @@ func writeType(buf *bytes.Buffer, typ Type) {
case
*
NamedType
:
case
*
NamedType
:
var
s
string
var
s
string
switch
{
switch
{
case
t
.
obj
!=
nil
:
s
=
t
.
obj
.
Name
case
t
.
Obj
!=
nil
:
case
t
.
Obj
!=
nil
:
s
=
t
.
Obj
.
GetName
()
s
=
t
.
Obj
.
GetName
()
case
t
.
AstObj
!=
nil
:
s
=
t
.
AstObj
.
Name
default
:
default
:
s
=
"<NamedType w/o object>"
s
=
"<NamedType w/o object>"
}
}
...
...
src/pkg/go/types/expr.go
View file @
8b62f54e
...
@@ -84,7 +84,7 @@ func (check *checker) collectMethods(list *ast.FieldList) (methods []*Method) {
...
@@ -84,7 +84,7 @@ func (check *checker) collectMethods(list *ast.FieldList) (methods []*Method) {
continue
continue
}
}
for
_
,
name
:=
range
f
.
Names
{
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
{
}
else
{
// embedded interface
// embedded interface
...
@@ -137,24 +137,24 @@ func (check *checker) collectFields(list *ast.FieldList, cycleOk bool) (fields [
...
@@ -137,24 +137,24 @@ func (check *checker) collectFields(list *ast.FieldList, cycleOk bool) (fields [
if
len
(
f
.
Names
)
>
0
{
if
len
(
f
.
Names
)
>
0
{
// named fields
// named fields
for
_
,
name
:=
range
f
.
Names
{
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
{
}
else
{
// anonymous field
// anonymous field
switch
t
:=
deref
(
typ
)
.
(
type
)
{
switch
t
:=
deref
(
typ
)
.
(
type
)
{
case
*
Basic
:
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
:
case
*
NamedType
:
var
name
string
var
name
string
switch
{
switch
{
case
t
.
obj
!=
nil
:
name
=
t
.
obj
.
Name
case
t
.
Obj
!=
nil
:
case
t
.
Obj
!=
nil
:
name
=
t
.
Obj
.
GetName
()
name
=
t
.
Obj
.
GetName
()
case
t
.
AstObj
!=
nil
:
name
=
t
.
AstObj
.
Name
default
:
default
:
unreachable
()
unreachable
()
}
}
fields
=
append
(
fields
,
&
Field
{
QualifiedName
{
check
.
pkg
,
name
},
typ
,
tag
,
true
})
fields
=
append
(
fields
,
&
Field
{
QualifiedName
{
nil
,
name
},
typ
,
tag
,
true
})
default
:
default
:
if
typ
!=
Typ
[
Invalid
]
{
if
typ
!=
Typ
[
Invalid
]
{
check
.
invalidAST
(
f
.
Type
.
Pos
(),
"anonymous field type %s must be named"
,
typ
)
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
...
@@ -913,7 +913,7 @@ func (check *checker) rawExpr(x *operand, e ast.Expr, hint Type, iota int, cycle
if
x
.
mode
==
invalid
{
if
x
.
mode
==
invalid
{
goto
Error
goto
Error
}
}
mode
,
typ
:=
lookupField
(
x
.
typ
,
QualifiedName
{
check
.
pkg
,
sel
})
mode
,
typ
:=
lookupField
(
x
.
typ
,
QualifiedName
{
nil
,
sel
})
if
mode
==
invalid
{
if
mode
==
invalid
{
check
.
invalidOp
(
e
.
Pos
(),
"%s has no single field or method %s"
,
x
,
sel
)
check
.
invalidOp
(
e
.
Pos
(),
"%s has no single field or method %s"
,
x
,
sel
)
goto
Error
goto
Error
...
...
src/pkg/go/types/operand.go
View file @
8b62f54e
...
@@ -265,11 +265,11 @@ func lookupFieldBreadthFirst(list []embeddedType, name QualifiedName) (res looku
...
@@ -265,11 +265,11 @@ func lookupFieldBreadthFirst(list []embeddedType, name QualifiedName) (res looku
visited
[
typ
]
=
true
visited
[
typ
]
=
true
// look for a matching attached method
// look for a matching attached method
if
typ
.
o
bj
!=
nil
{
if
typ
.
AstO
bj
!=
nil
{
assert
(
typ
.
o
bj
.
Data
==
nil
)
// methods must have been moved to typ.Methods
assert
(
typ
.
AstO
bj
.
Data
==
nil
)
// methods must have been moved to typ.Methods
}
}
for
_
,
m
:=
range
typ
.
Methods
{
for
_
,
m
:=
range
typ
.
Methods
{
if
identicalNames
(
name
,
m
.
QualifiedName
)
{
if
name
.
IsSame
(
m
.
QualifiedName
)
{
assert
(
m
.
Type
!=
nil
)
assert
(
m
.
Type
!=
nil
)
if
!
potentialMatch
(
e
.
multiples
,
value
,
m
.
Type
)
{
if
!
potentialMatch
(
e
.
multiples
,
value
,
m
.
Type
)
{
return
// name collision
return
// name collision
...
@@ -281,7 +281,7 @@ func lookupFieldBreadthFirst(list []embeddedType, name QualifiedName) (res looku
...
@@ -281,7 +281,7 @@ func lookupFieldBreadthFirst(list []embeddedType, name QualifiedName) (res looku
case
*
Struct
:
case
*
Struct
:
// look for a matching field and collect embedded types
// look for a matching field and collect embedded types
for
_
,
f
:=
range
t
.
Fields
{
for
_
,
f
:=
range
t
.
Fields
{
if
identicalNames
(
name
,
f
.
QualifiedName
)
{
if
name
.
IsSame
(
f
.
QualifiedName
)
{
assert
(
f
.
Type
!=
nil
)
assert
(
f
.
Type
!=
nil
)
if
!
potentialMatch
(
e
.
multiples
,
variable
,
f
.
Type
)
{
if
!
potentialMatch
(
e
.
multiples
,
variable
,
f
.
Type
)
{
return
// name collision
return
// name collision
...
@@ -305,7 +305,7 @@ func lookupFieldBreadthFirst(list []embeddedType, name QualifiedName) (res looku
...
@@ -305,7 +305,7 @@ func lookupFieldBreadthFirst(list []embeddedType, name QualifiedName) (res looku
case
*
Interface
:
case
*
Interface
:
// look for a matching method
// look for a matching method
for
_
,
m
:=
range
t
.
Methods
{
for
_
,
m
:=
range
t
.
Methods
{
if
identicalNames
(
name
,
m
.
QualifiedName
)
{
if
name
.
IsSame
(
m
.
QualifiedName
)
{
assert
(
m
.
Type
!=
nil
)
assert
(
m
.
Type
!=
nil
)
if
!
potentialMatch
(
e
.
multiples
,
value
,
m
.
Type
)
{
if
!
potentialMatch
(
e
.
multiples
,
value
,
m
.
Type
)
{
return
// name collision
return
// name collision
...
@@ -355,11 +355,11 @@ func lookupField(typ Type, name QualifiedName) (operandMode, Type) {
...
@@ -355,11 +355,11 @@ func lookupField(typ Type, name QualifiedName) (operandMode, Type) {
typ
=
deref
(
typ
)
typ
=
deref
(
typ
)
if
t
,
ok
:=
typ
.
(
*
NamedType
);
ok
{
if
t
,
ok
:=
typ
.
(
*
NamedType
);
ok
{
if
t
.
o
bj
!=
nil
{
if
t
.
AstO
bj
!=
nil
{
assert
(
t
.
o
bj
.
Data
==
nil
)
// methods must have been moved to t.Methods
assert
(
t
.
AstO
bj
.
Data
==
nil
)
// methods must have been moved to t.Methods
}
}
for
_
,
m
:=
range
t
.
Methods
{
for
_
,
m
:=
range
t
.
Methods
{
if
identicalNames
(
name
,
m
.
QualifiedName
)
{
if
name
.
IsSame
(
m
.
QualifiedName
)
{
assert
(
m
.
Type
!=
nil
)
assert
(
m
.
Type
!=
nil
)
return
value
,
m
.
Type
return
value
,
m
.
Type
}
}
...
@@ -371,7 +371,7 @@ func lookupField(typ Type, name QualifiedName) (operandMode, Type) {
...
@@ -371,7 +371,7 @@ func lookupField(typ Type, name QualifiedName) (operandMode, Type) {
case
*
Struct
:
case
*
Struct
:
var
next
[]
embeddedType
var
next
[]
embeddedType
for
_
,
f
:=
range
t
.
Fields
{
for
_
,
f
:=
range
t
.
Fields
{
if
identicalNames
(
name
,
f
.
QualifiedName
)
{
if
name
.
IsSame
(
f
.
QualifiedName
)
{
return
variable
,
f
.
Type
return
variable
,
f
.
Type
}
}
if
f
.
IsAnonymous
{
if
f
.
IsAnonymous
{
...
@@ -388,7 +388,7 @@ func lookupField(typ Type, name QualifiedName) (operandMode, Type) {
...
@@ -388,7 +388,7 @@ func lookupField(typ Type, name QualifiedName) (operandMode, Type) {
case
*
Interface
:
case
*
Interface
:
for
_
,
m
:=
range
t
.
Methods
{
for
_
,
m
:=
range
t
.
Methods
{
if
identicalNames
(
name
,
m
.
QualifiedName
)
{
if
name
.
IsSame
(
m
.
QualifiedName
)
{
return
value
,
m
.
Type
return
value
,
m
.
Type
}
}
}
}
...
...
src/pkg/go/types/predicates.go
View file @
8b62f54e
...
@@ -6,8 +6,6 @@
...
@@ -6,8 +6,6 @@
package
types
package
types
import
"go/ast"
func
isNamed
(
typ
Type
)
bool
{
func
isNamed
(
typ
Type
)
bool
{
if
_
,
ok
:=
typ
.
(
*
Basic
);
ok
{
if
_
,
ok
:=
typ
.
(
*
Basic
);
ok
{
return
ok
return
ok
...
@@ -131,7 +129,7 @@ func isIdentical(x, y Type) bool {
...
@@ -131,7 +129,7 @@ func isIdentical(x, y Type) bool {
if
len
(
x
.
Fields
)
==
len
(
y
.
Fields
)
{
if
len
(
x
.
Fields
)
==
len
(
y
.
Fields
)
{
for
i
,
f
:=
range
x
.
Fields
{
for
i
,
f
:=
range
x
.
Fields
{
g
:=
y
.
Fields
[
i
]
g
:=
y
.
Fields
[
i
]
if
!
identicalNames
(
f
.
QualifiedName
,
g
.
QualifiedName
)
||
if
!
f
.
QualifiedName
.
IsSame
(
g
.
QualifiedName
)
||
!
isIdentical
(
f
.
Type
,
g
.
Type
)
||
!
isIdentical
(
f
.
Type
,
g
.
Type
)
||
f
.
Tag
!=
g
.
Tag
||
f
.
Tag
!=
g
.
Tag
||
f
.
IsAnonymous
!=
g
.
IsAnonymous
{
f
.
IsAnonymous
!=
g
.
IsAnonymous
{
...
@@ -185,10 +183,10 @@ func isIdentical(x, y Type) bool {
...
@@ -185,10 +183,10 @@ func isIdentical(x, y Type) bool {
// in the same type declaration.
// in the same type declaration.
if
y
,
ok
:=
y
.
(
*
NamedType
);
ok
{
if
y
,
ok
:=
y
.
(
*
NamedType
);
ok
{
switch
{
switch
{
case
x
.
obj
!=
nil
:
return
x
.
obj
==
y
.
obj
case
x
.
Obj
!=
nil
:
case
x
.
Obj
!=
nil
:
return
x
.
Obj
==
y
.
Obj
return
x
.
Obj
==
y
.
Obj
case
x
.
AstObj
!=
nil
:
return
x
.
AstObj
==
y
.
AstObj
default
:
default
:
unreachable
()
unreachable
()
}
}
...
@@ -198,17 +196,6 @@ func isIdentical(x, y Type) bool {
...
@@ -198,17 +196,6 @@ func isIdentical(x, y Type) bool {
return
false
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
// identicalTypes returns true if both lists a and b have the
// same length and corresponding objects have identical types.
// same length and corresponding objects have identical types.
func
identicalTypes
(
a
,
b
[]
*
Var
)
bool
{
func
identicalTypes
(
a
,
b
[]
*
Var
)
bool
{
...
...
src/pkg/go/types/types.go
View file @
8b62f54e
...
@@ -91,12 +91,37 @@ type Slice struct {
...
@@ -91,12 +91,37 @@ type Slice struct {
Elt
Type
Elt
Type
}
}
// A QualifiedName is a name qualified with the package th
e
declared the name.
// A QualifiedName is a name qualified with the package th
at
declared the name.
type
QualifiedName
struct
{
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
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.
// A Field represents a field of a struct.
type
Field
struct
{
type
Field
struct
{
QualifiedName
QualifiedName
...
@@ -211,9 +236,9 @@ type Chan struct {
...
@@ -211,9 +236,9 @@ type Chan struct {
// A NamedType represents a named type as declared in a type declaration.
// A NamedType represents a named type as declared in a type declaration.
type
NamedType
struct
{
type
NamedType
struct
{
implementsType
implementsType
// TODO(gri) remove obj once we have moved away from ast.Objects
// TODO(gri) remove AstObj once we have moved away from ast.Objects
obj
*
ast
.
Object
// corresponding declared object (current package)
Obj
Object
// corresponding declared object (imported package)
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
Underlying
Type
// nil if not fully declared yet; never a *NamedType
Methods
[]
*
Method
// TODO(gri) consider keeping them in sorted order
Methods
[]
*
Method
// TODO(gri) consider keeping them in sorted order
}
}
...
...
src/pkg/go/types/universe.go
View file @
8b62f54e
...
@@ -159,7 +159,7 @@ func def(kind ast.ObjKind, name string, typ Type) *ast.Object {
...
@@ -159,7 +159,7 @@ func def(kind ast.ObjKind, name string, typ Type) *ast.Object {
obj
.
Decl
=
Universe
obj
.
Decl
=
Universe
obj
.
Type
=
typ
obj
.
Type
=
typ
if
typ
,
ok
:=
typ
.
(
*
NamedType
);
ok
{
if
typ
,
ok
:=
typ
.
(
*
NamedType
);
ok
{
typ
.
o
bj
=
obj
typ
.
AstO
bj
=
obj
}
}
if
Universe
.
Insert
(
obj
)
!=
nil
{
if
Universe
.
Insert
(
obj
)
!=
nil
{
panic
(
"internal error: double declaration"
)
panic
(
"internal error: double declaration"
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment