internal/importers: reverse bind types from unexported struct fields

Before this CL, unexported fields were ignored for the purposes of
determining which classes a Go struct should extend or implement.
However, the field types were also ignored, resulting in the types
not being generated at all. This CL adds the types of unexported
fields to the set of types to be generated.

Fixes golang/go#17945

Change-Id: I5c6c44b7cdfe0c3d4c4dc44863ae201dca7ae9a4
Reviewed-on: https://go-review.googlesource.com/38635
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/internal/importers/ast.go b/internal/importers/ast.go
index 91a4f31..7f1759b 100644
--- a/internal/importers/ast.go
+++ b/internal/importers/ast.go
@@ -150,16 +150,18 @@
 		}
 		var refs []PkgRef
 		for _, f := range t.Fields.List {
-			if len(f.Names) > 0 && !f.Names[0].IsExported() {
-				continue
-			}
 			sel, ok := f.Type.(*ast.SelectorExpr)
 			if !ok {
 				continue
 			}
-			if ref, ok := v.parseRef(sel); ok {
-				refs = append(refs, ref)
+			ref, ok := v.addRef(sel)
+			if !ok {
+				continue
 			}
+			if len(f.Names) > 0 && !f.Names[0].IsExported() {
+				continue
+			}
+			refs = append(refs, ref)
 		}
 		if len(refs) > 0 {
 			v.Embedders = append(v.Embedders, Struct{
@@ -197,7 +199,7 @@
 	}
 }
 
-func (v *refsSaver) parseRef(sel *ast.SelectorExpr) (PkgRef, bool) {
+func (v *refsSaver) addRef(sel *ast.SelectorExpr) (PkgRef, bool) {
 	x, ok := sel.X.(*ast.Ident)
 	if !ok || x.Obj == nil {
 		return PkgRef{}, false
@@ -214,7 +216,12 @@
 		return PkgRef{}, false
 	}
 	pkgPath = pkgPath[len(v.pkgPrefix):]
-	return PkgRef{Pkg: pkgPath, Name: sel.Sel.Name}, true
+	ref := PkgRef{Pkg: pkgPath, Name: sel.Sel.Name}
+	if _, exists := v.refMap[ref]; !exists {
+		v.refMap[ref] = struct{}{}
+		v.Refs = append(v.Refs, ref)
+	}
+	return ref, true
 }
 
 func (v *refsSaver) Visit(n ast.Node) ast.Visitor {
@@ -231,11 +238,7 @@
 		}
 	case *ast.SelectorExpr:
 		v.Names[n.Sel.Name] = struct{}{}
-		if ref, ok := v.parseRef(n); ok {
-			if _, exists := v.refMap[ref]; !exists {
-				v.refMap[ref] = struct{}{}
-				v.Refs = append(v.Refs, ref)
-			}
+		if _, ok := v.addRef(n); ok {
 			return nil
 		}
 	case *ast.FuncDecl:
diff --git a/internal/importers/ast_test.go b/internal/importers/ast_test.go
index b879216..8e32994 100644
--- a/internal/importers/ast_test.go
+++ b/internal/importers/ast_test.go
@@ -17,7 +17,7 @@
 
 type T struct {
 	Name.Type
-	hidden Name.Type2
+	unexported Name.Type2
 }
 
 func f() {
@@ -37,6 +37,7 @@
 		{Pkg: "some/pkg/Name", Name: "Constant"},
 		{Pkg: "some/pkg/Name", Name: "Type"},
 		{Pkg: "some/pkg/Name2", Name: "Func"},
+		{Pkg: "some/pkg/Name", Name: "Type2"},
 	}
 	if len(refs.Refs) != len(exps) {
 		t.Fatalf("expected %d references; got %d", len(exps), len(refs.Refs))