From bf090417da8b6150dcfe96795325f5aa78fff718 Mon Sep 17 00:00:00 2001 From: Rebecca Stambler Date: Fri, 11 Jan 2019 17:03:01 -0500 Subject: [PATCH] internal/lsp: fix a few nil pointer exceptions in definition Jumping to the definition of a builtin function or basic kind would cause a nil pointer because these have no position. Change-Id: I043a61a148757b127ff1123c8429ce23858bd13a Reviewed-on: https://go-review.googlesource.com/c/157597 Reviewed-by: Ian Cottrell Run-TryBot: Rebecca Stambler --- internal/lsp/position.go | 6 +++--- internal/lsp/source/definition.go | 15 +++++++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/internal/lsp/position.go b/internal/lsp/position.go index 692669256c4..2f9b4ae9af3 100644 --- a/internal/lsp/position.go +++ b/internal/lsp/position.go @@ -36,11 +36,11 @@ func fromProtocolLocation(ctx context.Context, v *cache.View, loc protocol.Locat // toProtocolLocation converts from a source range back to a protocol location. func toProtocolLocation(fset *token.FileSet, r source.Range) protocol.Location { - tokFile := fset.File(r.Start) - uri := source.ToURI(tokFile.Name()) + tok := fset.File(r.Start) + uri := source.ToURI(tok.Name()) return protocol.Location{ URI: protocol.DocumentURI(uri), - Range: toProtocolRange(tokFile, r), + Range: toProtocolRange(tok, r), } } diff --git a/internal/lsp/source/definition.go b/internal/lsp/source/definition.go index 89f038e542d..786372849dc 100644 --- a/internal/lsp/source/definition.go +++ b/internal/lsp/source/definition.go @@ -36,15 +36,15 @@ func Definition(ctx context.Context, v View, f File, pos token.Pos) (Range, erro return Range{}, fmt.Errorf("no object") } if i.wasEmbeddedField { - // the original position was on the embedded field declaration - // so we try to dig out the type and jump to that instead + // The original position was on the embedded field declaration, so we + // try to dig out the type and jump to that instead. if v, ok := obj.(*types.Var); ok { if n, ok := v.Type().(*types.Named); ok { obj = n.Obj() } } } - return objToRange(ctx, v, obj), nil + return objToRange(ctx, v, obj) } func TypeDefinition(ctx context.Context, v View, f File, pos token.Pos) (Range, error) { @@ -71,7 +71,7 @@ func TypeDefinition(ctx context.Context, v View, f File, pos token.Pos) (Range, if obj == nil { return Range{}, fmt.Errorf("no object for type %s", typ.String()) } - return objToRange(ctx, v, obj), nil + return objToRange(ctx, v, obj) } func typeToObject(typ types.Type) (obj types.Object) { @@ -129,8 +129,11 @@ func checkIdentifier(f *ast.File, pos token.Pos) (ident, error) { return result, nil } -func objToRange(ctx context.Context, v View, obj types.Object) Range { +func objToRange(ctx context.Context, v View, obj types.Object) (Range, error) { p := obj.Pos() + if !p.IsValid() { + return Range{}, fmt.Errorf("invalid position for %v", obj.Name()) + } tok := v.FileSet().File(p) pos := tok.Position(p) if pos.Column == 1 { @@ -161,7 +164,7 @@ Return: return Range{ Start: p, End: p + token.Pos(identifierLen(obj.Name())), - } + }, nil } // TODO: This needs to be fixed to address golang.org/issue/29149.