Skip to content

Commit 1e3f103

Browse files
committed
Only extract transparent-alias versions of types when necessary
1 parent 7fd060b commit 1e3f103

File tree

1 file changed

+87
-3
lines changed

1 file changed

+87
-3
lines changed

go/extractor/extractor.go

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,17 +1513,96 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
15131513
return extractTypeWithFlags(tw, tp, false)
15141514
}
15151515

1516+
func containsAliasTypes(tp types.Type) bool {
1517+
switch tp := tp.(type) {
1518+
case *types.Basic:
1519+
return false
1520+
case *types.Array:
1521+
return containsAliasTypes(tp.Elem())
1522+
case *types.Slice:
1523+
return containsAliasTypes(tp.Elem())
1524+
case *types.Struct:
1525+
for i := 0; i < tp.NumFields(); i++ {
1526+
field := tp.Field(i)
1527+
if containsAliasTypes(field.Type()) {
1528+
return true
1529+
}
1530+
}
1531+
return false
1532+
case *types.Pointer:
1533+
return containsAliasTypes(tp.Elem())
1534+
case *types.Interface:
1535+
for i := 0; i < tp.NumMethods(); i++ {
1536+
meth := tp.Method(i)
1537+
if containsAliasTypes(meth.Type()) {
1538+
return true
1539+
}
1540+
}
1541+
for i := 0; i < tp.NumEmbeddeds(); i++ {
1542+
if containsAliasTypes(tp.EmbeddedType(i)) {
1543+
return true
1544+
}
1545+
}
1546+
return false
1547+
case *types.Tuple:
1548+
for i := 0; i < tp.Len(); i++ {
1549+
if containsAliasTypes(tp.At(i).Type()) {
1550+
return true
1551+
}
1552+
}
1553+
return false
1554+
case *types.Signature:
1555+
params, results := tp.Params(), tp.Results()
1556+
if params != nil {
1557+
for i := 0; i < params.Len(); i++ {
1558+
param := params.At(i)
1559+
if containsAliasTypes(param.Type()) {
1560+
return true
1561+
}
1562+
}
1563+
}
1564+
if results != nil {
1565+
for i := 0; i < results.Len(); i++ {
1566+
result := results.At(i)
1567+
if containsAliasTypes(result.Type()) {
1568+
return true
1569+
}
1570+
}
1571+
}
1572+
return false
1573+
case *types.Map:
1574+
return containsAliasTypes(tp.Key()) || containsAliasTypes(tp.Elem())
1575+
case *types.Chan:
1576+
return containsAliasTypes(tp.Elem())
1577+
case *types.Named:
1578+
return false
1579+
case *types.TypeParam:
1580+
return false
1581+
case *types.Union:
1582+
for i := 0; i < tp.Len(); i++ {
1583+
term := tp.Term(i)
1584+
if containsAliasTypes(term.Type()) {
1585+
return true
1586+
}
1587+
}
1588+
return false
1589+
case *types.Alias:
1590+
return true
1591+
default:
1592+
log.Fatalf("unexpected type %T", tp)
1593+
}
1594+
return false
1595+
}
1596+
15161597
func extractTypeWithFlags(tw *trap.Writer, tp types.Type, transparentAliases bool) trap.Label {
15171598
lbl, exists := getTypeLabelWithFlags(tw, tp, transparentAliases)
15181599
if !exists {
1519-
if !transparentAliases {
1600+
if !transparentAliases && containsAliasTypes(tp) {
15201601
// Ensure the (deep) underlying type is also extracted, so that it is
15211602
// possible to implement deepUnalias in QL.
15221603
// For example, if we had type A = int and type B = string, we would need
15231604
// to extract map[string]int so that deepUnalias(map[B]A) has a real member
15241605
// of @type to return.
1525-
//
1526-
// TODO: consider using a newtype to do this instead.
15271606
extractTypeWithFlags(tw, tp, true)
15281607
}
15291608
var kind int
@@ -1709,6 +1788,11 @@ func getTypeLabelWithFlags(tw *trap.Writer, tp types.Type, transparentAliases bo
17091788
typeLabelKey := trap.TypeLabelsKey{Type: tp, TransparentAliases: transparentAliases}
17101789
lbl, exists := tw.Labeler.TypeLabels[typeLabelKey]
17111790
if !exists {
1791+
if transparentAliases && !containsAliasTypes(tp) {
1792+
// No aliases involved, so the label is the same as the non-transparent version
1793+
// of the same type.
1794+
return getTypeLabelWithFlags(tw, tp, false)
1795+
}
17121796
switch tp := tp.(type) {
17131797
case *types.Basic:
17141798
lbl = tw.Labeler.GlobalID(fmt.Sprintf("%d;basictype", tp.Kind()))

0 commit comments

Comments
 (0)