diff --git a/doc.go b/doc.go index 014a906..7d59faf 100644 --- a/doc.go +++ b/doc.go @@ -1,13 +1,16 @@ -package goref +/* + +Package goref provides tools to analyze a set of Go packages, starting +from one or more `main` packages, and produce a graph of relations +between identifiers in these packages. In other words, it indexes your +Go code and tells you where an exported identifier is used. It can +answer questions such as: -// Goref is a package that analyzes a set of Go packages, starting -// from one or more `main` packages, and computes the reverse of the -// cross-package identifier usage graph. In other words, it indexes -// your Go code and tells you where an exported identifier is used. It -// can answer questions such as: -// -// * Where is this type instantiated? -// * Where is this function called? -// * Where are all the references to this identifier? -// * What types implement this interface? -// * What interfaces are implemented by this type? + * Where is this type instantiated? + * Where is this function called? + * Where are all the references to this identifier? + * What types implement this interface? + * What interfaces are implemented by this type? + +*/ +package goref diff --git a/loadpath_test.go b/loadpath_test.go index c210c98..a85d045 100644 --- a/loadpath_test.go +++ b/loadpath_test.go @@ -1,15 +1,22 @@ -package goref +package goref_test import ( + "fmt" "go/ast" "testing" + "github.com/korfuri/goref" "github.com/stretchr/testify/assert" ) func TestCleanImportSpec(t *testing.T) { - assert.Equal(t, "foo/bar/baz", cleanImportSpec(&ast.ImportSpec{Path: &ast.BasicLit{Value: "foo/bar/baz"}})) - assert.Equal(t, "foo/bar/baz", cleanImportSpec(&ast.ImportSpec{Path: &ast.BasicLit{Value: "\"foo/bar/baz\""}})) + assert.Equal(t, "foo/bar/baz", goref.CleanImportSpec(&ast.ImportSpec{Path: &ast.BasicLit{Value: "foo/bar/baz"}})) + assert.Equal(t, "foo/bar/baz", goref.CleanImportSpec(&ast.ImportSpec{Path: &ast.BasicLit{Value: "\"foo/bar/baz\""}})) +} + +func ExampleCleanImportSpec() { + fmt.Println(goref.CleanImportSpec(&ast.ImportSpec{Path: &ast.BasicLit{Value: "\"foo/bar/baz\""}})) + // Output: foo/bar/baz } func TestCandidatePaths(t *testing.T) { @@ -19,5 +26,16 @@ func TestCandidatePaths(t *testing.T) { "vendor/c/d", "c/d", } - assert.Equal(t, r, candidatePaths("c/d", "a/b")) + assert.Equal(t, r, goref.CandidatePaths("c/d", "a/b")) +} + +func ExampleCandidatePaths() { + for _, p := range goref.CandidatePaths("lib/util", "program/bin") { + fmt.Println(p) + } + // Output: + // program/bin/vendor/lib/util + // program/vendor/lib/util + // vendor/lib/util + // lib/util } diff --git a/packagegraph.go b/packagegraph.go index 6fc4831..46ead5e 100644 --- a/packagegraph.go +++ b/packagegraph.go @@ -21,9 +21,9 @@ type PackageGraph struct { Files map[string]*File } -// cleanImportSpec takes an ast.ImportSpec and cleans the Path +// CleanImportSpec takes an ast.ImportSpec and cleans the Path // component by trimming the quotes (") that surround it. -func cleanImportSpec(spec *ast.ImportSpec) string { +func CleanImportSpec(spec *ast.ImportSpec) string { // FIXME we should make sure we understand what can cause Path // to be empty. if spec.Path != nil { @@ -34,7 +34,7 @@ func cleanImportSpec(spec *ast.ImportSpec) string { return "" } -// candidatePaths returns a slice enumerating all the possible import +// CandidatePaths returns a slice enumerating all the possible import // paths for a package. This means inserting the possible "vendor" // directory location from the load path of the importing package. // @@ -50,7 +50,7 @@ func cleanImportSpec(spec *ast.ImportSpec) string { // package path when building the graph. In this sense we follow the // go tool's convention to not try to detect when two packages loaded // through different paths are the same package. -func candidatePaths(loadpath, parent string) []string { +func CandidatePaths(loadpath, parent string) []string { const vendor = "vendor" paths := []string{} for parent != "." && parent != "" { @@ -94,8 +94,8 @@ func (pg *PackageGraph) loadPackage(prog *loader.Program, loadpath string, pi *l for _, imported := range f.Imports { // Find the import's load-path and load that // package into the graph. - ipath := cleanImportSpec(imported) - candidatePaths := candidatePaths(ipath, loadpath) + ipath := CleanImportSpec(imported) + candidatePaths := CandidatePaths(ipath, loadpath) var i *loader.PackageInfo for _, c := range candidatePaths { i = prog.Package(c)