Skip to content

Commit 5eeabfa

Browse files
authored
Fix method-name collisions (#17)
* Fix a bug that caused method names to collide with other top-level identifiers. * A little more bulletproofing.
1 parent bf5b672 commit 5eeabfa

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

compare.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ func (c *comparer) compareMajor(older, newer map[string]*packages.Package) Resul
127127
)
128128

129129
for id, obj := range topObjs {
130-
if !ast.IsExported(id) {
130+
if !isExported(id) {
131131
continue
132132
}
133133
if newPkg == nil {
@@ -162,7 +162,7 @@ func (c *comparer) compareMinor(older, newer map[string]*packages.Package) Resul
162162
)
163163

164164
for id, obj := range topObjs {
165-
if !ast.IsExported(id) {
165+
if !isExported(id) {
166166
continue
167167
}
168168
if oldPkg == nil {
@@ -352,3 +352,12 @@ func (cb cloneBugErr) Error() string {
352352
func (cb cloneBugErr) Unwrap() error {
353353
return cb.err
354354
}
355+
356+
// Calls ast.IsExported on the final element of name
357+
// (which may be package/type-qualified).
358+
func isExported(name string) bool {
359+
if i := strings.LastIndex(name, "."); i > 0 {
360+
name = name[i+1:]
361+
}
362+
return ast.IsExported(name)
363+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//// -*- mode: go -*-
2+
3+
//// {{ define "older" }}
4+
5+
package familiarmethodname
6+
7+
type Val int
8+
9+
const String Val = 1
10+
11+
//// {{ end }}
12+
13+
//// {{ define "newer" }}
14+
15+
package familiarmethodname
16+
17+
type Val int
18+
19+
const String Val = 1
20+
21+
func (v *Val) String() string {
22+
switch *v {
23+
case String: return "string"
24+
}
25+
return "<unknown>"
26+
}
27+
28+
//// {{ end }}

types.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,16 @@ func makeTopObjs(pkg *packages.Package) map[string]types.Object {
611611
}
612612

613613
case *ast.FuncDecl:
614-
res[decl.Name.Name] = pkg.TypesInfo.Defs[decl.Name]
614+
// If decl is a method, qualify the name with the receiver type.
615+
name := decl.Name.Name
616+
if decl.Recv != nil && len(decl.Recv.List) > 0 {
617+
recv := decl.Recv.List[0].Type
618+
if info := pkg.TypesInfo.Types[recv]; info.Type != nil {
619+
name = types.TypeString(info.Type, types.RelativeTo(pkg.Types)) + "." + name
620+
}
621+
}
622+
623+
res[name] = pkg.TypesInfo.Defs[decl.Name]
615624
}
616625
}
617626
}

0 commit comments

Comments
 (0)