cmd/go: move modfetch.modPath to modfile.ModulePath, fix // handling

Replacement for CL 116836.

For golang/go#25501.

Change-Id: Ie4f15dc11d9499aeeb497b7aceff2efd2bcd7ce3
Reviewed-on: https://go-review.googlesource.com/118718
Reviewed-by: Daniel Theophanes <kardianos@gmail.com>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
diff --git a/vendor/cmd/go/internal/modfetch/coderepo.go b/vendor/cmd/go/internal/modfetch/coderepo.go
index bb6e8ac..c208fb2 100644
--- a/vendor/cmd/go/internal/modfetch/coderepo.go
+++ b/vendor/cmd/go/internal/modfetch/coderepo.go
@@ -6,7 +6,6 @@
 
 import (
 	"archive/zip"
-	"bytes"
 	"errors"
 	"fmt"
 	"io"
@@ -15,7 +14,6 @@
 	"path"
 	"path/filepath"
 	"regexp"
-	"strconv"
 	"strings"
 	"time"
 
@@ -238,40 +236,7 @@
 }
 
 func isMajor(gomod []byte, pathMajor string) bool {
-	return strings.HasSuffix(modPath(gomod), pathMajor)
-}
-
-var moduleStr = []byte("module")
-
-func modPath(mod []byte) string {
-	for len(mod) > 0 {
-		line := mod
-		mod = nil
-		if i := bytes.IndexByte(line, '\n'); i >= 0 {
-			line, mod = line[:i], line[i+1:]
-		}
-		line = bytes.TrimSpace(line)
-		if !bytes.HasPrefix(line, moduleStr) {
-			continue
-		}
-		line = line[len(moduleStr):]
-		n := len(line)
-		line = bytes.TrimSpace(line)
-		if len(line) == n || len(line) == 0 {
-			continue
-		}
-
-		if line[0] == '"' || line[0] == '`' {
-			p, err := strconv.Unquote(string(line))
-			if err != nil {
-				return "" // malformed quoted string or multiline module path
-			}
-			return p
-		}
-
-		return string(line)
-	}
-	return "" // missing module path
+	return strings.HasSuffix(modfile.ModulePath(gomod), pathMajor)
 }
 
 func (r *codeRepo) GoMod(version string) (data []byte, err error) {
diff --git a/vendor/cmd/go/internal/modfetch/coderepo_test.go b/vendor/cmd/go/internal/modfetch/coderepo_test.go
index e3b106e..999e6b3 100644
--- a/vendor/cmd/go/internal/modfetch/coderepo_test.go
+++ b/vendor/cmd/go/internal/modfetch/coderepo_test.go
@@ -650,39 +650,3 @@
 		t.Fatal("unexpected versions returned:", v)
 	}
 }
-
-var modPathTests = []struct {
-	input    []byte
-	expected string
-}{
-	{input: []byte("module \"github.com/rsc/vgotest\""), expected: "github.com/rsc/vgotest"},
-	{input: []byte("module github.com/rsc/vgotest"), expected: "github.com/rsc/vgotest"},
-	{input: []byte("module  \"github.com/rsc/vgotest\""), expected: "github.com/rsc/vgotest"},
-	{input: []byte("module  github.com/rsc/vgotest"), expected: "github.com/rsc/vgotest"},
-	{input: []byte("module `github.com/rsc/vgotest`"), expected: "github.com/rsc/vgotest"},
-	{input: []byte("module \"github.com/rsc/vgotest/v2\""), expected: "github.com/rsc/vgotest/v2"},
-	{input: []byte("module github.com/rsc/vgotest/v2"), expected: "github.com/rsc/vgotest/v2"},
-	{input: []byte("module \"gopkg.in/yaml.v2\""), expected: "gopkg.in/yaml.v2"},
-	{input: []byte("module gopkg.in/yaml.v2"), expected: "gopkg.in/yaml.v2"},
-	{input: []byte("module \"gopkg.in/check.v1\"\n"), expected: "gopkg.in/check.v1"},
-	{input: []byte("module \"gopkg.in/check.v1\n\""), expected: ""},
-	{input: []byte("module gopkg.in/check.v1\n"), expected: "gopkg.in/check.v1"},
-	{input: []byte("module \"gopkg.in/check.v1\"\r\n"), expected: "gopkg.in/check.v1"},
-	{input: []byte("module gopkg.in/check.v1\r\n"), expected: "gopkg.in/check.v1"},
-	{input: []byte("module \"gopkg.in/check.v1\"\n\n"), expected: "gopkg.in/check.v1"},
-	{input: []byte("module gopkg.in/check.v1\n\n"), expected: "gopkg.in/check.v1"},
-	{input: []byte("module \n\"gopkg.in/check.v1\"\n\n"), expected: ""},
-	{input: []byte("module \ngopkg.in/check.v1\n\n"), expected: ""},
-	{input: []byte("module \"gopkg.in/check.v1\"asd"), expected: ""},
-}
-
-func TestModPath(t *testing.T) {
-	for _, test := range modPathTests {
-		t.Run(string(test.input), func(t *testing.T) {
-			result := modPath(test.input)
-			if result != test.expected {
-				t.Fatalf("modPath(%s): %s, want %s", string(test.input), result, test.expected)
-			}
-		})
-	}
-}
diff --git a/vendor/cmd/go/internal/modfile/read.go b/vendor/cmd/go/internal/modfile/read.go
index a0c88d6..f4a3926 100644
--- a/vendor/cmd/go/internal/modfile/read.go
+++ b/vendor/cmd/go/internal/modfile/read.go
@@ -11,6 +11,7 @@
 	"bytes"
 	"fmt"
 	"os"
+	"strconv"
 	"strings"
 	"unicode"
 	"unicode/utf8"
@@ -697,3 +698,45 @@
 	_STRING
 	_COMMENT
 )
+
+var (
+	slashSlash = []byte("//")
+	moduleStr  = []byte("module")
+)
+
+// ModulePath returns the module path from the gomod file text.
+// If it cannot find a module path, it returns an empty string.
+// It is tolerant of unrelated problems in the go.mod file.
+func ModulePath(mod []byte) string {
+	for len(mod) > 0 {
+		line := mod
+		mod = nil
+		if i := bytes.IndexByte(line, '\n'); i >= 0 {
+			line, mod = line[:i], line[i+1:]
+		}
+		if i := bytes.Index(line, slashSlash); i >= 0 {
+			line = line[:i]
+		}
+		line = bytes.TrimSpace(line)
+		if !bytes.HasPrefix(line, moduleStr) {
+			continue
+		}
+		line = line[len(moduleStr):]
+		n := len(line)
+		line = bytes.TrimSpace(line)
+		if len(line) == n || len(line) == 0 {
+			continue
+		}
+
+		if line[0] == '"' || line[0] == '`' {
+			p, err := strconv.Unquote(string(line))
+			if err != nil {
+				return "" // malformed quoted string or multiline module path
+			}
+			return p
+		}
+
+		return string(line)
+	}
+	return "" // missing module path
+}
diff --git a/vendor/cmd/go/internal/modfile/read_test.go b/vendor/cmd/go/internal/modfile/read_test.go
index 2c617b8..254e549 100644
--- a/vendor/cmd/go/internal/modfile/read_test.go
+++ b/vendor/cmd/go/internal/modfile/read_test.go
@@ -304,3 +304,47 @@
 	}
 	t.Error(string(data))
 }
+
+var modulePathTests = []struct {
+	input    []byte
+	expected string
+}{
+	{input: []byte("module \"github.com/rsc/vgotest\""), expected: "github.com/rsc/vgotest"},
+	{input: []byte("module github.com/rsc/vgotest"), expected: "github.com/rsc/vgotest"},
+	{input: []byte("module  \"github.com/rsc/vgotest\""), expected: "github.com/rsc/vgotest"},
+	{input: []byte("module  github.com/rsc/vgotest"), expected: "github.com/rsc/vgotest"},
+	{input: []byte("module `github.com/rsc/vgotest`"), expected: "github.com/rsc/vgotest"},
+	{input: []byte("module \"github.com/rsc/vgotest/v2\""), expected: "github.com/rsc/vgotest/v2"},
+	{input: []byte("module github.com/rsc/vgotest/v2"), expected: "github.com/rsc/vgotest/v2"},
+	{input: []byte("module \"gopkg.in/yaml.v2\""), expected: "gopkg.in/yaml.v2"},
+	{input: []byte("module gopkg.in/yaml.v2"), expected: "gopkg.in/yaml.v2"},
+	{input: []byte("module \"gopkg.in/check.v1\"\n"), expected: "gopkg.in/check.v1"},
+	{input: []byte("module \"gopkg.in/check.v1\n\""), expected: ""},
+	{input: []byte("module gopkg.in/check.v1\n"), expected: "gopkg.in/check.v1"},
+	{input: []byte("module \"gopkg.in/check.v1\"\r\n"), expected: "gopkg.in/check.v1"},
+	{input: []byte("module gopkg.in/check.v1\r\n"), expected: "gopkg.in/check.v1"},
+	{input: []byte("module \"gopkg.in/check.v1\"\n\n"), expected: "gopkg.in/check.v1"},
+	{input: []byte("module gopkg.in/check.v1\n\n"), expected: "gopkg.in/check.v1"},
+	{input: []byte("module \n\"gopkg.in/check.v1\"\n\n"), expected: ""},
+	{input: []byte("module \ngopkg.in/check.v1\n\n"), expected: ""},
+	{input: []byte("module \"gopkg.in/check.v1\"asd"), expected: ""},
+	{input: []byte("module \n\"gopkg.in/check.v1\"\n\n"), expected: ""},
+	{input: []byte("module \ngopkg.in/check.v1\n\n"), expected: ""},
+	{input: []byte("module \"gopkg.in/check.v1\"asd"), expected: ""},
+	{input: []byte("module  \nmodule a/b/c "), expected: "a/b/c"},
+	{input: []byte("module \"   \""), expected: "   "},
+	{input: []byte("module   "), expected: ""},
+	{input: []byte("module \"  a/b/c  \""), expected: "  a/b/c  "},
+	{input: []byte("module \"github.com/rsc/vgotest1\" // with a comment"), expected: "github.com/rsc/vgotest1"},
+}
+
+func TestModulePath(t *testing.T) {
+	for _, test := range modulePathTests {
+		t.Run(string(test.input), func(t *testing.T) {
+			result := ModulePath(test.input)
+			if result != test.expected {
+				t.Fatalf("ModulePath(%q): %s, want %s", string(test.input), result, test.expected)
+			}
+		})
+	}
+}