@@ -477,6 +477,13 @@ func objectString(obj types.Object, qf types.Qualifier, inferred *types.Signatur
477
477
func FindHoverContext (ctx context.Context , s Snapshot , pkg Package , obj types.Object , pkgNode ast.Node , fullDecl ast.Decl ) (* HoverContext , error ) {
478
478
var info * HoverContext
479
479
480
+ // Type parameters get their signature from their declaration object.
481
+ if _ , isTypeName := obj .(* types.TypeName ); isTypeName {
482
+ if _ , isTypeParam := obj .Type ().(* typeparams.TypeParam ); isTypeParam {
483
+ return & HoverContext {signatureSource : obj }, nil
484
+ }
485
+ }
486
+
480
487
// This is problematic for a number of reasons. We really need to have a more
481
488
// general mechanism to validate the coherency of AST with type information,
482
489
// but absent that we must do our best to ensure that we don't use fullNode
@@ -555,15 +562,15 @@ func FindHoverContext(ctx context.Context, s Snapshot, pkg Package, obj types.Ob
555
562
}
556
563
}
557
564
558
- info , err = formatGenDecl (node , spec , fullPos , obj )
565
+ info , err = hoverGenDecl (node , spec , fullPos , obj )
559
566
if err != nil {
560
567
return nil , err
561
568
}
562
569
}
563
570
case * ast.TypeSpec :
564
571
if obj .Parent () == types .Universe {
565
572
if genDecl , ok := fullDecl .(* ast.GenDecl ); ok {
566
- info = formatTypeSpec (node , genDecl )
573
+ info = hoverTypeSpec (node , genDecl )
567
574
}
568
575
}
569
576
case * ast.FuncDecl :
@@ -620,24 +627,24 @@ func isFunctionParam(obj types.Object, node *ast.FuncDecl) bool {
620
627
return false
621
628
}
622
629
623
- // formatGenDecl returns hover information an object declared via spec inside
630
+ // hoverGenDecl returns hover information an object declared via spec inside
624
631
// of the GenDecl node. obj is the type-checked object corresponding to the
625
632
// declaration, but may have been type-checked using a different AST than the
626
633
// given nodes; fullPos is the position of obj in node's AST.
627
- func formatGenDecl (node * ast.GenDecl , spec ast.Spec , fullPos token.Pos , obj types.Object ) (* HoverContext , error ) {
634
+ func hoverGenDecl (node * ast.GenDecl , spec ast.Spec , fullPos token.Pos , obj types.Object ) (* HoverContext , error ) {
628
635
if spec == nil {
629
636
return nil , errors .Errorf ("no spec for node %v at position %v" , node , fullPos )
630
637
}
631
638
632
639
// If we have a field or method.
633
640
switch obj .(type ) {
634
641
case * types.Var , * types.Const , * types.Func :
635
- return formatVar (spec , fullPos , obj , node ), nil
642
+ return hoverVar (spec , fullPos , obj , node ), nil
636
643
}
637
644
// Handle types.
638
645
switch spec := spec .(type ) {
639
646
case * ast.TypeSpec :
640
- return formatTypeSpec (spec , node ), nil
647
+ return hoverTypeSpec (spec , node ), nil
641
648
case * ast.ValueSpec :
642
649
return & HoverContext {signatureSource : spec , Comment : spec .Doc }, nil
643
650
case * ast.ImportSpec :
@@ -646,7 +653,8 @@ func formatGenDecl(node *ast.GenDecl, spec ast.Spec, fullPos token.Pos, obj type
646
653
return nil , errors .Errorf ("unable to format spec %v (%T)" , spec , spec )
647
654
}
648
655
649
- func formatTypeSpec (spec * ast.TypeSpec , decl * ast.GenDecl ) * HoverContext {
656
+ // TODO(rfindley): rename this function.
657
+ func hoverTypeSpec (spec * ast.TypeSpec , decl * ast.GenDecl ) * HoverContext {
650
658
comment := spec .Doc
651
659
if comment == nil && decl != nil {
652
660
comment = decl .Doc
@@ -660,7 +668,7 @@ func formatTypeSpec(spec *ast.TypeSpec, decl *ast.GenDecl) *HoverContext {
660
668
}
661
669
}
662
670
663
- func formatVar (node ast.Spec , fullPos token.Pos , obj types.Object , decl * ast.GenDecl ) * HoverContext {
671
+ func hoverVar (node ast.Spec , fullPos token.Pos , obj types.Object , decl * ast.GenDecl ) * HoverContext {
664
672
var fieldList * ast.FieldList
665
673
switch spec := node .(type ) {
666
674
case * ast.TypeSpec :
0 commit comments