internal/govulncheck,result: move functions

Move functions out of package result into package govulncheck, as a step
towards reducing the package to being only structs with no dependencies.

Change-Id: I7bb40af3395cd5210fd3e2077f616984098276d6
Reviewed-on: https://go-review.googlesource.com/c/vuln/+/474757
Reviewed-by: Julie Qiu <julieqiu@google.com>
Run-TryBot: Julie Qiu <julieqiu@google.com>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/internal/govulncheck/callstacks.go b/internal/govulncheck/callstacks.go
index 14a7ce2..f9b1f2b 100644
--- a/internal/govulncheck/callstacks.go
+++ b/internal/govulncheck/callstacks.go
@@ -141,7 +141,7 @@
 		return ""
 	}
 
-	topPos := internal.AbsRelShorter(result.Pos(cs.Frames[iTop]))
+	topPos := internal.AbsRelShorter(Pos(cs.Frames[iTop]))
 	if topPos != "" {
 		topPos += ": "
 	}
@@ -159,7 +159,7 @@
 	if iVulnStart != iTopEnd+1 {
 		// If there is something in between top and vuln segments of
 		// the stack, then also summarize that intermediate segment.
-		return fmt.Sprintf("%s%s calls %s, which eventually calls %s", topPos, topFunc, result.FuncName(cs.Frames[iTopEnd+1]), vulnFunc)
+		return fmt.Sprintf("%s%s calls %s, which eventually calls %s", topPos, topFunc, FuncName(cs.Frames[iTopEnd+1]), vulnFunc)
 	}
 	if vulnStartFunc != vulnFunc {
 		// The first function of the vuln segment is anonymous.
@@ -185,7 +185,7 @@
 		return -1, -1, "", ""
 	}
 
-	topEndFunc = result.FuncName(frames[iTopEnd])
+	topEndFunc = FuncName(frames[iTopEnd])
 	if !isAnonymousFunction(topEndFunc) {
 		iTop = iTopEnd
 		topFunc = topEndFunc
@@ -203,7 +203,7 @@
 		return
 	}
 
-	topFunc = result.FuncName(frames[iTop])
+	topFunc = FuncName(frames[iTop])
 	return
 }
 
@@ -225,7 +225,7 @@
 	}
 	iVulnStart += iTop + 1 // adjust for slice in call to highest.
 
-	vulnStartFunc = result.FuncName(frames[iVulnStart])
+	vulnStartFunc = FuncName(frames[iVulnStart])
 	if !isAnonymousFunction(vulnStartFunc) {
 		vulnFunc = vulnStartFunc
 		return
@@ -241,7 +241,7 @@
 		return
 	}
 
-	vulnFunc = result.FuncName(frames[iVuln+iVulnStart])
+	vulnFunc = FuncName(frames[iVuln+iVulnStart])
 	return
 }
 
diff --git a/internal/govulncheck/result.go b/internal/govulncheck/result.go
index 5a33410..f44bed7 100644
--- a/internal/govulncheck/result.go
+++ b/internal/govulncheck/result.go
@@ -6,8 +6,12 @@
 package govulncheck
 
 import (
+	"fmt"
+	"strings"
+
 	"golang.org/x/tools/go/packages"
 	"golang.org/x/vuln/client"
+	"golang.org/x/vuln/internal/result"
 )
 
 // LoadMode is the level of information needed for each package
@@ -28,3 +32,37 @@
 	// By default, GoVersion is the go command version found from the PATH.
 	GoVersion string
 }
+
+// IsCalled reports whether the vulnerability is called, therefore
+// affecting the target source code or binary.
+func IsCalled(v *result.Vuln) bool {
+	for _, m := range v.Modules {
+		for _, p := range m.Packages {
+			if len(p.CallStacks) > 0 {
+				return true
+			}
+		}
+	}
+	return false
+}
+
+// FuncName returns the full qualified function name from sf,
+// adjusted to remove pointer annotations.
+func FuncName(sf *result.StackFrame) string {
+	var n string
+	if sf.RecvType == "" {
+		n = fmt.Sprintf("%s.%s", sf.PkgPath, sf.FuncName)
+	} else {
+		n = fmt.Sprintf("%s.%s", sf.RecvType, sf.FuncName)
+	}
+	return strings.TrimPrefix(n, "*")
+}
+
+// Pos returns the position of the call in sf as string.
+// If position is not available, return "".
+func Pos(sf *result.StackFrame) string {
+	if sf.Position.IsValid() {
+		return sf.Position.String()
+	}
+	return ""
+}
diff --git a/internal/govulncheck/result_test.go b/internal/govulncheck/result_test.go
index 302043b..2bee377 100644
--- a/internal/govulncheck/result_test.go
+++ b/internal/govulncheck/result_test.go
@@ -36,10 +36,10 @@
 			"",
 		},
 	} {
-		if got := result.FuncName(test.sf); got != test.wantFunc {
+		if got := FuncName(test.sf); got != test.wantFunc {
 			t.Errorf("want %v func name; got %v", test.wantFunc, got)
 		}
-		if got := result.Pos(test.sf); got != test.wantPos {
+		if got := Pos(test.sf); got != test.wantPos {
 			t.Errorf("want %v call position; got %v", test.wantPos, got)
 		}
 	}
@@ -79,7 +79,7 @@
 		{"not called - single module", vuln([2]string{"golang.org/p1", ""}), false},
 		{"not called - multi modules", vuln([2]string{"golang.org/p1", ""}, [2]string{"golang.org/p2", ""}), false},
 	} {
-		if result.IsCalled(test.v) != test.want {
+		if IsCalled(test.v) != test.want {
 			t.Errorf("want called=%t for %v; got the opposite", test.want, test.desc)
 		}
 	}
diff --git a/internal/govulncheck/text.go b/internal/govulncheck/text.go
index ebda9df..d21da4f 100644
--- a/internal/govulncheck/text.go
+++ b/internal/govulncheck/text.go
@@ -117,7 +117,7 @@
 	// TODO(https://go.dev/issue/58945): add a test for this
 	if source {
 		for _, v := range r.Vulns {
-			if result.IsCalled(v) {
+			if IsCalled(v) {
 				return ErrVulnerabilitiesFound
 			}
 		}
@@ -140,7 +140,7 @@
 	var unaffected []tmplVulnInfo
 	var affected []tmplVulnInfo
 	for _, v := range r.Vulns {
-		if !source || result.IsCalled(v) {
+		if !source || IsCalled(v) {
 			affected = append(affected, createTmplVulnInfo(v, verbose, source))
 		} else {
 			// save arbitrary module info for informational message
@@ -276,8 +276,8 @@
 	for _, cs := range css {
 		b.WriteString(fmt.Sprintf("#%d: for function %s\n", i, cs.Symbol))
 		for _, e := range cs.Frames {
-			b.WriteString(fmt.Sprintf("  %s\n", result.FuncName(e)))
-			if pos := internal.AbsRelShorter(result.Pos(e)); pos != "" {
+			b.WriteString(fmt.Sprintf("  %s\n", FuncName(e)))
+			if pos := internal.AbsRelShorter(Pos(e)); pos != "" {
 				b.WriteString(fmt.Sprintf("      %s\n", pos))
 			}
 		}
diff --git a/internal/result/result.go b/internal/result/result.go
index 83e3b38..bc1282e 100644
--- a/internal/result/result.go
+++ b/internal/result/result.go
@@ -6,9 +6,7 @@
 package result
 
 import (
-	"fmt"
 	"go/token"
-	"strings"
 
 	"golang.org/x/vuln/osv"
 )
@@ -34,19 +32,6 @@
 	Modules []*Module
 }
 
-// IsCalled reports whether the vulnerability is called, therefore
-// affecting the target source code or binary.
-func IsCalled(v *Vuln) bool {
-	for _, m := range v.Modules {
-		for _, p := range m.Packages {
-			if len(p.CallStacks) > 0 {
-				return true
-			}
-		}
-	}
-	return false
-}
-
 // Module represents a specific vulnerability relevant to a single module.
 type Module struct {
 	// Path is the module path of the module containing the vulnerability.
@@ -132,24 +117,3 @@
 	// A Position is valid if the line number is > 0.
 	Position token.Position
 }
-
-// FuncName returns the full qualified function name from sf,
-// adjusted to remove pointer annotations.
-func FuncName(sf *StackFrame) string {
-	var n string
-	if sf.RecvType == "" {
-		n = fmt.Sprintf("%s.%s", sf.PkgPath, sf.FuncName)
-	} else {
-		n = fmt.Sprintf("%s.%s", sf.RecvType, sf.FuncName)
-	}
-	return strings.TrimPrefix(n, "*")
-}
-
-// Pos returns the position of the call in sf as string.
-// If position is not available, return "".
-func Pos(sf *StackFrame) string {
-	if sf.Position.IsValid() {
-		return sf.Position.String()
-	}
-	return ""
-}