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
Hide 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) {
check
.
valueSpec
(
spec
.
Pos
(),
obj
,
spec
.
Names
,
init
.
Type
,
init
.
Values
,
iota
)
case
ast
.
Typ
:
typ
:=
&
NamedType
{
o
bj
:
obj
}
typ
:=
&
NamedType
{
AstO
bj
:
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
...
...
src/pkg/go/types/errors.go
View file @
8b62f54e
...
...
@@ -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>"
}
...
...
src/pkg/go/types/expr.go
View file @
8b62f54e
...
...
@@ -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
...
...
src/pkg/go/types/operand.go
View file @
8b62f54e
...
...
@@ -265,11 +265,11 @@ func lookupFieldBreadthFirst(list []embeddedType, name QualifiedName) (res looku
visited
[
typ
]
=
true
// look for a matching attached method
if
typ
.
o
bj
!=
nil
{
assert
(
typ
.
o
bj
.
Data
==
nil
)
// methods must have been moved to typ.Methods
if
typ
.
AstO
bj
!=
nil
{
assert
(
typ
.
AstO
bj
.
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
.
o
bj
!=
nil
{
assert
(
t
.
o
bj
.
Data
==
nil
)
// methods must have been moved to t.Methods
if
t
.
AstO
bj
!=
nil
{
assert
(
t
.
AstO
bj
.
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
}
}
...
...
src/pkg/go/types/predicates.go
View file @
8b62f54e
...
...
@@ -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
{
...
...
src/pkg/go/types/types.go
View file @
8b62f54e
...
...
@@ -91,12 +91,37 @@ type Slice struct {
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
{
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
}
...
...
src/pkg/go/types/universe.go
View file @
8b62f54e
...
...
@@ -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
.
o
bj
=
obj
typ
.
AstO
bj
=
obj
}
if
Universe
.
Insert
(
obj
)
!=
nil
{
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