Skip to content

Commit 14ef824

Browse files
smowtonowen-mc
authored andcommitted
Ensure fields are created for de-aliased struct types
This means that there is a target for defs and refs to refer to after the original fields go away because their corresponding structs have also gone away on a database downgrade.
1 parent f837504 commit 14ef824

File tree

2 files changed

+31
-19
lines changed

2 files changed

+31
-19
lines changed

go/extractor/extractor.go

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1702,21 +1702,29 @@ func extractTypeWithFlags(tw *trap.Writer, tp types.Type, transparentAliases boo
17021702
for i := 0; i < tp.NumFields(); i++ {
17031703
field := tp.Field(i).Origin()
17041704

1705-
if !transparentAliases {
1706-
// ensure the field is associated with a label - note that
1707-
// struct fields do not have a parent scope, so they are not
1708-
// dealt with by `extractScopes`.
1709-
1710-
// Skip this when extracting a type with transparent aliases;
1711-
// this is not the definitive version of the type.
1712-
fieldlbl, exists := tw.Labeler.FieldID(field, i, lbl)
1713-
if !exists {
1714-
extractObject(tw, field, fieldlbl)
1715-
}
1705+
// ensure the field is associated with a label - note that
1706+
// struct fields do not have a parent scope, so they are not
1707+
// dealt with by `extractScopes`.
1708+
1709+
// For the transparentAliases case we bypass the object-label cache
1710+
// because we're extracting a field relative to a synthetic field
1711+
// that has a different type and therefore label, whereas the label
1712+
// cache is indexed by object, not type-label.
1713+
var fieldlbl trap.Label
1714+
var exists bool
1715+
if transparentAliases {
1716+
fieldlbl = tw.Labeler.FieldIDNoCache(field, i, lbl)
1717+
exists = false
1718+
} else {
1719+
fieldlbl, exists = tw.Labeler.FieldID(field, i, lbl)
1720+
}
17161721

1717-
dbscheme.FieldStructsTable.Emit(tw, fieldlbl, lbl)
1722+
if !exists {
1723+
extractObject(tw, field, fieldlbl)
17181724
}
17191725

1726+
dbscheme.FieldStructsTable.Emit(tw, fieldlbl, lbl)
1727+
17201728
name := field.Name()
17211729
if field.Embedded() {
17221730
name = ""

go/extractor/trap/labels.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,16 @@ func (l *Labeler) ReceiverObjectID(object types.Object, methlbl Label) (Label, b
210210
return label, exists
211211
}
212212

213+
func (l *Labeler) FieldIDNoCache(field *types.Var, idx int, structlbl Label) Label {
214+
name := field.Name()
215+
// there can be multiple fields with the blank identifier, so use index to
216+
// distinguish them
217+
if field.Name() == "_" {
218+
name = fmt.Sprintf("_%d", idx)
219+
}
220+
return l.GlobalID(fmt.Sprintf("{%v},%s;field", structlbl, name))
221+
}
222+
213223
// FieldID associates a label with the given field and returns it, together with
214224
// a flag indicating whether the field already had a label associated with it;
215225
// the field must belong to `structlbl`, since that label is used to construct
@@ -218,13 +228,7 @@ func (l *Labeler) ReceiverObjectID(object types.Object, methlbl Label) (Label, b
218228
func (l *Labeler) FieldID(field *types.Var, idx int, structlbl Label) (Label, bool) {
219229
label, exists := l.objectLabels[field]
220230
if !exists {
221-
name := field.Name()
222-
// there can be multiple fields with the blank identifier, so use index to
223-
// distinguish them
224-
if field.Name() == "_" {
225-
name = fmt.Sprintf("_%d", idx)
226-
}
227-
label = l.GlobalID(fmt.Sprintf("{%v},%s;field", structlbl, name))
231+
label = l.FieldIDNoCache(field, idx, structlbl)
228232
l.objectLabels[field] = label
229233
}
230234
return label, exists

0 commit comments

Comments
 (0)