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 <iancottrell@google.com>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
diff --git a/internal/lsp/position.go b/internal/lsp/position.go
index 6926692..2f9b4ae 100644
--- a/internal/lsp/position.go
+++ b/internal/lsp/position.go
@@ -36,11 +36,11 @@
 
 // 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 89f038e..7863728 100644
--- a/internal/lsp/source/definition.go
+++ b/internal/lsp/source/definition.go
@@ -36,15 +36,15 @@
 		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 @@
 	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 @@
 	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 Range{
 		Start: p,
 		End:   p + token.Pos(identifierLen(obj.Name())),
-	}
+	}, nil
 }
 
 // TODO: This needs to be fixed to address golang.org/issue/29149.