internal/lsp/cache: parse filenames from go list errors correctly

go/packages.Error has filenames relative to the go command's working
directory. We need to interpret them as such.

This would perhaps be better done in go/packages but with no release
process in place I'm leery of making changes to it.

Updates golang/go#44342.

Change-Id: I95bcdff0368efe09ec7059394e59a39bf195310b
Reviewed-on: https://go-review.googlesource.com/c/tools/+/295412
Trust: Heschi Kreinick <heschi@google.com>
Run-TryBot: Heschi Kreinick <heschi@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
diff --git a/internal/lsp/cache/errors.go b/internal/lsp/cache/errors.go
index 148fbda..b6e7d23 100644
--- a/internal/lsp/cache/errors.go
+++ b/internal/lsp/cache/errors.go
@@ -63,7 +63,7 @@
 				return diags, nil
 			}
 		} else {
-			spn = span.Parse(e.Pos)
+			spn = span.ParseInDir(e.Pos, pkg.m.config.Dir)
 		}
 	case *scanner.Error:
 		msg = e.Msg
diff --git a/internal/span/parse.go b/internal/span/parse.go
index aa17c84..c4cec16 100644
--- a/internal/span/parse.go
+++ b/internal/span/parse.go
@@ -5,6 +5,7 @@
 package span
 
 import (
+	"path/filepath"
 	"strconv"
 	"strings"
 	"unicode/utf8"
@@ -15,6 +16,17 @@
 // The returned span will be normalized, and thus if printed may produce a
 // different string.
 func Parse(input string) Span {
+	return ParseInDir(input, ".")
+}
+
+// ParseInDir is like Parse, but interprets paths relative to wd.
+func ParseInDir(input, wd string) Span {
+	uri := func(path string) URI {
+		if !filepath.IsAbs(path) {
+			path = filepath.Join(wd, path)
+		}
+		return URIFromPath(path)
+	}
 	// :0:0#0-0:0#0
 	valid := input
 	var hold, offset int
@@ -32,12 +44,12 @@
 	}
 	switch {
 	case suf.sep == ":":
-		return New(URIFromPath(suf.remains), NewPoint(suf.num, hold, offset), Point{})
+		return New(uri(suf.remains), NewPoint(suf.num, hold, offset), Point{})
 	case suf.sep == "-":
 		// we have a span, fall out of the case to continue
 	default:
 		// separator not valid, rewind to either the : or the start
-		return New(URIFromPath(valid), NewPoint(hold, 0, offset), Point{})
+		return New(uri(valid), NewPoint(hold, 0, offset), Point{})
 	}
 	// only the span form can get here
 	// at this point we still don't know what the numbers we have mean
@@ -53,20 +65,20 @@
 	}
 	if suf.sep != ":" {
 		// turns out we don't have a span after all, rewind
-		return New(URIFromPath(valid), end, Point{})
+		return New(uri(valid), end, Point{})
 	}
 	valid = suf.remains
 	hold = suf.num
 	suf = rstripSuffix(suf.remains)
 	if suf.sep != ":" {
 		// line#offset only
-		return New(URIFromPath(valid), NewPoint(hold, 0, offset), end)
+		return New(uri(valid), NewPoint(hold, 0, offset), end)
 	}
 	// we have a column, so if end only had one number, it is also the column
 	if !hadCol {
 		end = NewPoint(suf.num, end.v.Line, end.v.Offset)
 	}
-	return New(URIFromPath(suf.remains), NewPoint(suf.num, hold, offset), end)
+	return New(uri(suf.remains), NewPoint(suf.num, hold, offset), end)
 }
 
 type suffix struct {