Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit 8c15199

Browse files
owen-mcsmowton
authored andcommitted
Use generic struct field not instantiated one in Uses
We do not extract instantiated named types, and instead use the generic type. But fields of the underlying struct of an instantiated named types are obtained from the Uses map. We solve this keeping track of which objects should be overridden by which other objects.
1 parent 8276ca0 commit 8c15199

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

extractor/extractor.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,6 +1531,7 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
15311531
dbscheme.TypeNameTable.Emit(tw, lbl, origintp.Obj().Name())
15321532
underlying := origintp.Underlying()
15331533
extractUnderlyingType(tw, lbl, underlying)
1534+
trackInstantiatedStructFields(tw, tp, origintp)
15341535

15351536
entitylbl, exists := tw.Labeler.LookupObjectID(origintp.Obj(), lbl)
15361537
if entitylbl == trap.InvalidLabel {
@@ -1902,6 +1903,9 @@ func getObjectBeingUsed(tw *trap.Writer, ident *ast.Ident) types.Object {
19021903
if obj == nil {
19031904
return nil
19041905
}
1906+
if override, ok := tw.ObjectsOverride[obj]; ok {
1907+
return override
1908+
}
19051909
if funcObj, ok := obj.(*types.Func); ok {
19061910
sig := funcObj.Type().(*types.Signature)
19071911
if recv := sig.Recv(); recv != nil {
@@ -1948,3 +1952,33 @@ func tryGetGenericType(tp types.Type) (*types.Named, bool) {
19481952
}
19491953
return nil, false
19501954
}
1955+
1956+
// trackInstantiatedStructFields tries to give the fields of an instantiated
1957+
// struct type underlying `tp` the same labels as the corresponding fields of
1958+
// the generic struct type. This is so that when we come across the
1959+
// instantiated field in `tw.Package.TypesInfo.Uses` we will get the label for
1960+
// the generic field instead.
1961+
func trackInstantiatedStructFields(tw *trap.Writer, tp, origintp *types.Named) {
1962+
if tp == origintp {
1963+
return
1964+
}
1965+
1966+
if instantiatedStruct, ok := tp.Underlying().(*types.Struct); ok {
1967+
genericStruct, ok2 := origintp.Underlying().(*types.Struct)
1968+
if !ok2 {
1969+
log.Fatalf(
1970+
"Error: underlying type of instantiated type is a struct but underlying type of generic type is %s",
1971+
origintp.Underlying())
1972+
}
1973+
1974+
if instantiatedStruct.NumFields() != genericStruct.NumFields() {
1975+
log.Fatalf(
1976+
"Error: instantiated struct %s has different number of fields than the generic version %s (%d != %d)",
1977+
instantiatedStruct, genericStruct, instantiatedStruct.NumFields(), genericStruct.NumFields())
1978+
}
1979+
1980+
for i := 0; i < instantiatedStruct.NumFields(); i++ {
1981+
tw.ObjectsOverride[instantiatedStruct.Field(i)] = genericStruct.Field(i)
1982+
}
1983+
}
1984+
}

extractor/trap/trapwriter.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type Writer struct {
2727
Package *packages.Package
2828
TypesOverride map[ast.Expr]types.Type
2929
TypeParamParent map[*types.TypeParam]Label
30+
ObjectsOverride map[types.Object]types.Object
3031
}
3132

3233
func FileFor(path string) (string, error) {
@@ -66,6 +67,7 @@ func NewWriter(path string, pkg *packages.Package) (*Writer, error) {
6667
pkg,
6768
make(map[ast.Expr]types.Type),
6869
make(map[*types.TypeParam]Label),
70+
make(map[types.Object]types.Object),
6971
}
7072
tw.Labeler = newLabeler(tw)
7173
return tw, nil

0 commit comments

Comments
 (0)