Skip to content

Commit

Permalink
feat(go_indexer): emit tapps for instantiated Named types (#5158)
Browse files Browse the repository at this point in the history
  • Loading branch information
schroederc committed Dec 21, 2021
1 parent 7dc3b79 commit dd574ee
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 6 deletions.
44 changes: 41 additions & 3 deletions kythe/go/indexer/emit.go
Expand Up @@ -168,6 +168,10 @@ func (pi *PackageInfo) Emit(ctx context.Context, sink Sink, opts *EmitOptions) e
e.visitRangeStmt(n, stack)
case *ast.CompositeLit:
e.visitCompositeLit(n, stack)
case *ast.IndexExpr:
e.visitIndexExpr(n, stack)
case *ast.IndexListExpr:
e.visitIndexListExpr(n, stack)
}
return true
}), file)
Expand Down Expand Up @@ -223,7 +227,14 @@ func (e *emitter) visitIdent(id *ast.Ident, stack stackFunc) {
return
}

target := e.pi.ObjectVName(obj)
var target *spb.VName
if n, ok := obj.(*types.TypeName); ok && obj.Pkg() == nil {
// Handle type arguments in instantiated types.
target = e.emitType(n.Type())
} else {
target = e.pi.ObjectVName(obj)
}

if target == nil {
// This should not happen in well-formed packages, but can if the
// extractor gets confused. Avoid emitting confusing references in such
Expand Down Expand Up @@ -293,7 +304,7 @@ func (e *emitter) visitFuncDecl(decl *ast.FuncDecl, stack stackFunc) {
// with given constructor and parameters. The constructor's kind is also
// emitted if this is the first time seeing it.
func (e *emitter) emitTApp(ms *cpb.MarkedSource, ctorKind string, ctor *spb.VName, params ...*spb.VName) *spb.VName {
if e.pi.typeEmitted.Add(ctor.Signature) {
if ctorKind != "" && e.pi.typeEmitted.Add(ctor.Signature) {
e.writeFact(ctor, facts.NodeKind, ctorKind)
if ctorKind == nodes.TBuiltin {
e.emitBuiltinMarkedSource(ctor)
Expand Down Expand Up @@ -330,7 +341,18 @@ func (e *emitter) emitType(typ types.Type) *spb.VName {

switch typ := typ.(type) {
case *types.Named:
v = e.pi.ObjectVName(typ.Obj())
if typ.TypeArgs().Len() == 0 {
v = e.pi.ObjectVName(typ.Obj())
} else {
// Instantiated Named types produce tapps
ctor := e.emitType(typ.Origin())
args := typ.TypeArgs()
var params []*spb.VName
for i := 0; i < args.Len(); i++ {
params = append(params, e.emitType(args.At(i)))
}
v = e.emitTApp(genericTAppMS, "", ctor, params...)
}
case *types.Basic:
v = govname.BasicType(typ)
if e.pi.typeEmitted.Add(v.Signature) {
Expand Down Expand Up @@ -694,6 +716,22 @@ func (e *emitter) visitCompositeLit(expr *ast.CompositeLit, stack stackFunc) {
}
}

// visitIndexExpr handles references to instantiated types with a single type
// parameter.
func (e *emitter) visitIndexExpr(expr *ast.IndexExpr, stack stackFunc) {
if n, ok := e.pi.Info.TypeOf(expr).(*types.Named); ok && n.TypeArgs().Len() > 0 {
e.writeRef(expr, e.emitType(n), edges.Ref)
}
}

// visitIndexListExpr handles references to instantiated types with multiple
// type parameters.
func (e *emitter) visitIndexListExpr(expr *ast.IndexListExpr, stack stackFunc) {
if n, ok := e.pi.Info.TypeOf(expr).(*types.Named); ok && n.TypeArgs().Len() > 0 {
e.writeRef(expr, e.emitType(n), edges.Ref)
}
}

// emitPosRef emits an anchor spanning loc, pointing to obj.
func (e *emitter) emitPosRef(loc ast.Node, obj types.Object, kind string) {
target := e.pi.ObjectVName(obj)
Expand Down
16 changes: 16 additions & 0 deletions kythe/go/indexer/markedsource.go
Expand Up @@ -334,6 +334,22 @@ var (
}},
PreText: "<-chan ",
}
genericTAppMS = &cpb.MarkedSource{
Kind: cpb.MarkedSource_TYPE,
Child: []*cpb.MarkedSource{{
Kind: cpb.MarkedSource_LOOKUP_BY_PARAM,
LookupIndex: 0,
}, {
Kind: cpb.MarkedSource_BOX,
PreText: "[",
PostText: "]",
Child: []*cpb.MarkedSource{{
Kind: cpb.MarkedSource_PARAMETER_LOOKUP_BY_PARAM,
LookupIndex: 1,
}},
PostChildText: ", ",
}},
}
)

func arrayTAppMS(length int64) *cpb.MarkedSource {
Expand Down
1 change: 0 additions & 1 deletion kythe/go/indexer/testdata/generics/genericmethod.go
@@ -1,7 +1,6 @@
package genericmethod

func main() {
//- @Container ref Container
c := &Container[string]{"element"}
//- @Get ref Get
c.Get()
Expand Down
27 changes: 25 additions & 2 deletions kythe/go/indexer/testdata/generics/genericstruct.go
@@ -1,5 +1,25 @@
package genericstruct

func main() {
//- @"Container[string]" ref ContainerApp
//- @Container ref Container
//- @string ref String
_ = &Container[string]{"element"}
//- ContainerApp.node/kind "tapp"
//- ContainerApp param.0 Container
//- ContainerApp param.1 String

//- @"Pair[string, int]" ref PairApp
//- @Pair ref Pair
//- @string ref String
//- @int ref Int
_ = &Pair[string, int]{"first", 2}
//- PairApp.node/kind "tapp"
//- PairApp param.0 Pair
//- PairApp param.1 String
//- PairApp param.2 Int
}

//- @Container defines/binding Container
//- Container.node/kind record
//- @T defines/binding TVar
Expand All @@ -11,13 +31,16 @@ type Container[T any] struct {
}

//- @T defines/binding TVar2
//- @U defines/binding UVar
//- !{@T defines/binding TVar}
//- !{@T ref TVar}
type Container2[T any] struct {
type Pair[T any, U any] struct {
//- @T ref TVar2
//- !{@T defines/binding TVar}
//- !{@T ref TVar}
Element T
First T
//- @U ref UVar
Second U
}

// kythe/go/indexer/genericstruct_test.Container.T
Expand Down

0 comments on commit dd574ee

Please sign in to comment.