all: update dependencies in go.mod file

CL 226639 changed the positions of the go.mod diagnostics (in a
negligible way), but the tests are quite brittle and can't handle the
different position. Rewrite this test as a regression test to handle it.

The special // indirect marker can be removed from the go/expect package
as a result, since it was only used in this one place.

Change-Id: I7d9a62e32e53d477838e65673635ed231c07b659
Reviewed-on: https://go-review.googlesource.com/c/tools/+/240691
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
diff --git a/go.mod b/go.mod
index 861f9ec..63d6df2 100644
--- a/go.mod
+++ b/go.mod
@@ -3,9 +3,9 @@
 go 1.11
 
 require (
-	github.com/yuin/goldmark v1.1.27
-	golang.org/x/mod v0.2.0
-	golang.org/x/net v0.0.0-20200226121028-0de0cce0169b
-	golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
+	github.com/yuin/goldmark v1.1.32
+	golang.org/x/mod v0.3.0
+	golang.org/x/net v0.0.0-20200625001655-4c5254603344
+	golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208
 	golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
 )
diff --git a/go.sum b/go.sum
index a33f273..c0ceb3d 100644
--- a/go.sum
+++ b/go.sum
@@ -1,21 +1,23 @@
-github.com/yuin/goldmark v1.1.27 h1:nqDD4MMMQA0lmWq03Z2/myGPYLQoXtmi0rGVs95ntbo=
-github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.32 h1:5tjfNdR2ki3yYQ842+eX2sQHeiwpKJ0RnHO4IYOc4V8=
+github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
-golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
-golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
+golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
-golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
+golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/go/expect/expect.go b/go/expect/expect.go
index 672c3a3..bb203f5 100644
--- a/go/expect/expect.go
+++ b/go/expect/expect.go
@@ -56,7 +56,6 @@
 	"bytes"
 	"fmt"
 	"go/token"
-	"path/filepath"
 	"regexp"
 )
 
@@ -96,14 +95,6 @@
 	matchStart, matchEnd := -1, -1
 	switch pattern := pattern.(type) {
 	case string:
-		// If the file is a go.mod and we are matching // indirect, then we
-		// need to look for it on the line after the current line.
-		// TODO(golang/go#36894): have a more intuitive approach for // indirect
-		if filepath.Ext(f.Name()) == ".mod" && pattern == "// indirect" {
-			startOffset = f.Offset(f.LineStart(position.Line + 1))
-			endOffset = f.Offset(lineEnd(f, position.Line+1))
-			line = content[startOffset:endOffset]
-		}
 		bytePattern := []byte(pattern)
 		matchStart = bytes.Index(line, bytePattern)
 		if matchStart >= 0 {
diff --git a/go/expect/expect_test.go b/go/expect/expect_test.go
index bd6e437..bd25ef8 100644
--- a/go/expect/expect_test.go
+++ b/go/expect/expect_test.go
@@ -38,17 +38,16 @@
 			},
 			expectChecks: map[string][]interface{}{
 				"αSimpleMarker": nil,
-				"StringAndInt":  []interface{}{"Number %d", int64(12)},
-				"Bool":          []interface{}{true},
+				"StringAndInt":  {"Number %d", int64(12)},
+				"Bool":          {true},
 			},
 		},
 		{
 			filename:    "testdata/go.mod",
-			expectNotes: 3,
+			expectNotes: 2,
 			expectMarkers: map[string]string{
-				"αMarker":        "αfake1α",
-				"IndirectMarker": "// indirect",
-				"βMarker":        "require golang.org/modfile v0.0.0",
+				"αMarker": "αfake1α",
+				"βMarker": "require golang.org/modfile v0.0.0",
 			},
 		},
 	} {
@@ -62,11 +61,6 @@
 			markers := make(map[string]token.Pos)
 			for name, tok := range tt.expectMarkers {
 				offset := bytes.Index(content, []byte(tok))
-				// Handle special case where we look for // indirect and we
-				// need to search the next line.
-				if tok == "// indirect" {
-					offset = bytes.Index(content, []byte(" "+tok)) + 1
-				}
 				markers[name] = token.Pos(offset + 1)
 				end := bytes.Index(content[offset:], []byte(tok))
 				if end > 0 {
diff --git a/go/expect/testdata/go.mod b/go/expect/testdata/go.mod
index d3c4f87..d0323ea 100644
--- a/go/expect/testdata/go.mod
+++ b/go/expect/testdata/go.mod
@@ -3,5 +3,3 @@
 go 1.14
 
 require golang.org/modfile v0.0.0 //@mark(βMarker, "require golang.org/modfile v0.0.0")
-//@mark(IndirectMarker, "// indirect")
-require example.com/extramodule v1.0.0 // indirect
\ No newline at end of file
diff --git a/gopls/go.sum b/gopls/go.sum
index 4c91be0..4580821 100644
--- a/gopls/go.sum
+++ b/gopls/go.sum
@@ -19,19 +19,21 @@
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
-golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
-golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
-golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
+golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
diff --git a/internal/lsp/cache/mod_tidy.go b/internal/lsp/cache/mod_tidy.go
index d00f36f..d57b616 100644
--- a/internal/lsp/cache/mod_tidy.go
+++ b/internal/lsp/cache/mod_tidy.go
@@ -352,22 +352,20 @@
 }
 
 func rangeFromPositions(uri span.URI, m *protocol.ColumnMapper, s, e modfile.Position) (protocol.Range, error) {
-	line, col, err := m.Converter.ToPosition(s.Byte)
+	toPoint := func(offset int) (span.Point, error) {
+		l, c, err := m.Converter.ToPosition(offset)
+		if err != nil {
+			return span.Point{}, err
+		}
+		return span.NewPoint(l, c, offset), nil
+	}
+	start, err := toPoint(s.Byte)
 	if err != nil {
 		return protocol.Range{}, err
 	}
-	start := span.NewPoint(line, col, s.Byte)
-
-	line, col, err = m.Converter.ToPosition(e.Byte)
+	end, err := toPoint(e.Byte)
 	if err != nil {
 		return protocol.Range{}, err
 	}
-	end := span.NewPoint(line, col, e.Byte)
-
-	spn := span.New(uri, start, end)
-	rng, err := m.Range(spn)
-	if err != nil {
-		return protocol.Range{}, err
-	}
-	return rng, nil
+	return m.Range(span.New(uri, start, end))
 }
diff --git a/internal/lsp/regtest/modfile_test.go b/internal/lsp/regtest/modfile_test.go
index 188818e..c0dcfe9 100644
--- a/internal/lsp/regtest/modfile_test.go
+++ b/internal/lsp/regtest/modfile_test.go
@@ -7,14 +7,12 @@
 import (
 	"testing"
 
+	"golang.org/x/tools/internal/lsp/protocol"
 	"golang.org/x/tools/internal/lsp/tests"
 	"golang.org/x/tools/internal/testenv"
 )
 
-func TestModFileModification(t *testing.T) {
-	testenv.NeedsGo1Point(t, 14)
-
-	const proxy = `
+const proxy = `
 -- example.com@v1.2.3/go.mod --
 module example.com
 
@@ -24,6 +22,10 @@
 
 const Name = "Blah"
 `
+
+func TestModFileModification(t *testing.T) {
+	testenv.NeedsGo1Point(t, 14)
+
 	const untidyModule = `
 -- go.mod --
 module mod.com
@@ -58,3 +60,46 @@
 		}
 	}, WithProxy(proxy))
 }
+
+func TestIndirectDependencyFix(t *testing.T) {
+	testenv.NeedsGo1Point(t, 14)
+
+	const mod = `
+-- go.mod --
+module mod.com
+
+go 1.12
+
+require example.com v1.2.3 // indirect
+-- main.go --
+package main
+
+import "example.com/blah"
+
+func main() {
+	fmt.Println(blah.Name)
+`
+	const want = `module mod.com
+
+go 1.12
+
+require example.com v1.2.3
+`
+	runner.Run(t, mod, func(t *testing.T, env *Env) {
+		env.OpenFile("go.mod")
+		d := env.Await(
+			env.DiagnosticAtRegexp("go.mod", "// indirect"),
+		)
+		if len(d) == 0 {
+			t.Fatalf("no diagnostics")
+		}
+		params, ok := d[0].(*protocol.PublishDiagnosticsParams)
+		if !ok {
+			t.Fatalf("expected diagnostic of type PublishDiagnosticParams, got %T", d[0])
+		}
+		env.ApplyQuickFixes("go.mod", params.Diagnostics)
+		if got := env.Editor.BufferText("go.mod"); got != want {
+			t.Fatalf("unexpected go.mod content:\n%s", tests.Diff(want, got))
+		}
+	}, WithProxy(proxy))
+}
diff --git a/internal/lsp/testdata/indirect/modules/example.com/extramodule/pkg/x.go b/internal/lsp/testdata/indirect/modules/example.com/extramodule/pkg/x.go
deleted file mode 100644
index cf7fc67..0000000
--- a/internal/lsp/testdata/indirect/modules/example.com/extramodule/pkg/x.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package pkg
-
-const Test = 1
\ No newline at end of file
diff --git a/internal/lsp/testdata/indirect/primarymod/go.mod b/internal/lsp/testdata/indirect/primarymod/go.mod
deleted file mode 100644
index 9c24e47..0000000
--- a/internal/lsp/testdata/indirect/primarymod/go.mod
+++ /dev/null
@@ -1,5 +0,0 @@
-module indirect
-
-go 1.12
-//@diag("// indirect", "go mod tidy", "example.com/extramodule should be a direct dependency.", "warning"),suggestedfix("// indirect", "quickfix")
-require example.com/extramodule v1.0.0 // indirect
diff --git a/internal/lsp/testdata/indirect/primarymod/go.mod.golden b/internal/lsp/testdata/indirect/primarymod/go.mod.golden
deleted file mode 100644
index 3e707df..0000000
--- a/internal/lsp/testdata/indirect/primarymod/go.mod.golden
+++ /dev/null
@@ -1,8 +0,0 @@
--- suggestedfix_go.mod_5_40 --
-module indirect
-
-go 1.12
-
-//@diag("// indirect", "go mod tidy", "example.com/extramodule should be a direct dependency.", "warning"),suggestedfix("// indirect", "quickfix")
-require example.com/extramodule v1.0.0
-
diff --git a/internal/lsp/testdata/indirect/primarymod/main.go b/internal/lsp/testdata/indirect/primarymod/main.go
deleted file mode 100644
index 2fb1cc8..0000000
--- a/internal/lsp/testdata/indirect/primarymod/main.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Package indirect does something
-package indirect
-
-import (
-	"example.com/extramodule/pkg"
-)
-
-func Yo() {
-	var _ pkg.Test
-}
diff --git a/internal/lsp/testdata/indirect/summary.txt.golden b/internal/lsp/testdata/indirect/summary.txt.golden
deleted file mode 100644
index 5c4f74a..0000000
--- a/internal/lsp/testdata/indirect/summary.txt.golden
+++ /dev/null
@@ -1,28 +0,0 @@
--- summary --
-CodeLensCount = 0
-CompletionsCount = 0
-CompletionSnippetCount = 0
-UnimportedCompletionsCount = 0
-DeepCompletionsCount = 0
-FuzzyCompletionsCount = 0
-RankedCompletionsCount = 0
-CaseSensitiveCompletionsCount = 0
-DiagnosticsCount = 1
-FoldingRangesCount = 0
-FormatCount = 0
-ImportCount = 0
-SuggestedFixCount = 1
-DefinitionsCount = 0
-TypeDefinitionsCount = 0
-HighlightsCount = 0
-ReferencesCount = 0
-RenamesCount = 0
-PrepareRenamesCount = 0
-SymbolsCount = 0
-WorkspaceSymbolsCount = 0
-FuzzyWorkspaceSymbolsCount = 0
-CaseSensitiveWorkspaceSymbolsCount = 0
-SignaturesCount = 0
-LinksCount = 0
-ImplementationsCount = 0
-