oracle: support "referrers" query on package declaration
Added test. Change-Id: Id7d061b0f74959166b5631a3fde8da4000ffb8d2 Reviewed-on: https://go-review.googlesource.com/9326 Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
		
							parent
							
								
									fb59b33999
								
							
						
					
					
						commit
						a9f55c4fa4
					
				| 
						 | 
					@ -46,7 +46,9 @@ func definition(q *Query) error {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	obj := qpos.info.ObjectOf(id)
 | 
						obj := qpos.info.ObjectOf(id)
 | 
				
			||||||
	if obj == nil {
 | 
						if obj == nil {
 | 
				
			||||||
		// Happens for y in "switch y := x.(type)", but I think that's all.
 | 
							// Happens for y in "switch y := x.(type)",
 | 
				
			||||||
 | 
							// and the package declaration,
 | 
				
			||||||
 | 
							// but I think that's all.
 | 
				
			||||||
		return fmt.Errorf("no object for identifier")
 | 
							return fmt.Errorf("no object for identifier")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,9 +18,6 @@ import (
 | 
				
			||||||
	"golang.org/x/tools/refactor/importgraph"
 | 
						"golang.org/x/tools/refactor/importgraph"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO(adonovan): use golang.org/x/tools/refactor/importgraph to choose
 | 
					 | 
				
			||||||
// the scope automatically.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Referrers reports all identifiers that resolve to the same object
 | 
					// Referrers reports all identifiers that resolve to the same object
 | 
				
			||||||
// as the queried identifier, within any package in the analysis scope.
 | 
					// as the queried identifier, within any package in the analysis scope.
 | 
				
			||||||
func referrers(q *Query) error {
 | 
					func referrers(q *Query) error {
 | 
				
			||||||
| 
						 | 
					@ -57,20 +54,26 @@ func referrers(q *Query) error {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		obj = qpos.info.ObjectOf(id)
 | 
							obj = qpos.info.ObjectOf(id)
 | 
				
			||||||
		if obj == nil {
 | 
							if obj == nil {
 | 
				
			||||||
			// Happens for y in "switch y := x.(type)", but I think that's all.
 | 
								// Happens for y in "switch y := x.(type)",
 | 
				
			||||||
			return fmt.Errorf("no object for identifier")
 | 
								// the package declaration,
 | 
				
			||||||
 | 
								// and unresolved identifiers.
 | 
				
			||||||
 | 
								if _, ok := qpos.path[1].(*ast.File); ok { // package decl?
 | 
				
			||||||
 | 
									pkg := qpos.info.Pkg
 | 
				
			||||||
 | 
									obj = types.NewPkgName(id.Pos(), pkg, pkg.Name(), pkg)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									return fmt.Errorf("no object for identifier: %T", qpos.path[1])
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if pass2 {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// If the identifier is exported, we must load all packages that
 | 
							// If the identifier is exported, we must load all packages that
 | 
				
			||||||
		// depend transitively upon the package that defines it.
 | 
							// depend transitively upon the package that defines it.
 | 
				
			||||||
		//
 | 
							// Treat PkgNames as exported, even though they're lowercase.
 | 
				
			||||||
		// TODO(adonovan): we should do this for PkgName objects
 | 
							if _, isPkg := obj.(*types.PkgName); !(isPkg || obj.Exported()) {
 | 
				
			||||||
		// too, even though they're lowercase.
 | 
								break // not exported
 | 
				
			||||||
		//
 | 
					 | 
				
			||||||
		// TODO(adonovan): opt: skip this step if obj.Pkg() is a test or
 | 
					 | 
				
			||||||
		// main package.
 | 
					 | 
				
			||||||
		if pass2 || !obj.Exported() {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Scan the workspace and build the import graph.
 | 
							// Scan the workspace and build the import graph.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,10 +22,10 @@
 | 
				
			||||||
			"testdata/src/imports/main.go:22:9",
 | 
								"testdata/src/imports/main.go:22:9",
 | 
				
			||||||
			"testdata/src/referrers-json/main.go:15:8",
 | 
								"testdata/src/referrers-json/main.go:15:8",
 | 
				
			||||||
			"testdata/src/referrers-json/main.go:16:8",
 | 
								"testdata/src/referrers-json/main.go:16:8",
 | 
				
			||||||
			"testdata/src/referrers/ext_test.go:7:17",
 | 
								"testdata/src/referrers/ext_test.go:10:17",
 | 
				
			||||||
			"testdata/src/referrers/int_test.go:7:17",
 | 
								"testdata/src/referrers/int_test.go:7:17",
 | 
				
			||||||
			"testdata/src/referrers/main.go:15:8",
 | 
								"testdata/src/referrers/main.go:17:8",
 | 
				
			||||||
			"testdata/src/referrers/main.go:16:8"
 | 
								"testdata/src/referrers/main.go:18:8"
 | 
				
			||||||
		]
 | 
							]
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,12 @@
 | 
				
			||||||
package main_test
 | 
					package main_test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "lib"
 | 
					import (
 | 
				
			||||||
 | 
						"lib"
 | 
				
			||||||
 | 
						renamed "referrers" // package has name "main", path "referrers", local name "renamed"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func _() {
 | 
					func _() {
 | 
				
			||||||
	// This reference should be found by the ref-method query.
 | 
						// This reference should be found by the ref-method query.
 | 
				
			||||||
	_ = (lib.Type).Method // ref from external test package
 | 
						_ = (lib.Type).Method // ref from external test package
 | 
				
			||||||
 | 
						var _ renamed.T
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
package main
 | 
					package main // @referrers package-decl "main"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests of 'referrers' query.
 | 
					// Tests of 'referrers' query.
 | 
				
			||||||
// See go.tools/oracle/oracle_test.go for explanation.
 | 
					// See go.tools/oracle/oracle_test.go for explanation.
 | 
				
			||||||
| 
						 | 
					@ -6,10 +6,12 @@ package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "lib"
 | 
					import "lib"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type s struct { // @referrers ref-type " s "
 | 
					type s struct { // @referrers type " s "
 | 
				
			||||||
	f int
 | 
						f int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type T int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
	var v lib.Type = lib.Const // @referrers ref-package "lib"
 | 
						var v lib.Type = lib.Const // @referrers ref-package "lib"
 | 
				
			||||||
	_ = v.Method               // @referrers ref-method "Method"
 | 
						_ = v.Method               // @referrers ref-method "Method"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,16 @@
 | 
				
			||||||
-------- @referrers ref-type --------
 | 
					-------- @referrers package-decl --------
 | 
				
			||||||
 | 
					1 references to package main ("referrers")
 | 
				
			||||||
 | 
						var _ renamed.T
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-------- @referrers type --------
 | 
				
			||||||
2 references to type s struct{f int}
 | 
					2 references to type s struct{f int}
 | 
				
			||||||
	_ = s{}.f // @referrers ref-field "f"
 | 
						_ = s{}.f // @referrers ref-field "f"
 | 
				
			||||||
	var s2 s
 | 
						var s2 s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-------- @referrers ref-package --------
 | 
					-------- @referrers ref-package --------
 | 
				
			||||||
2 references to package lib
 | 
					4 references to package lib
 | 
				
			||||||
 | 
						_ = (lib.Type).Method // ref from external test package
 | 
				
			||||||
 | 
						_ = (lib.Type).Method // ref from internal test package
 | 
				
			||||||
	var v lib.Type = lib.Const // @referrers ref-package "lib"
 | 
						var v lib.Type = lib.Const // @referrers ref-package "lib"
 | 
				
			||||||
	var v lib.Type = lib.Const // @referrers ref-package "lib"
 | 
						var v lib.Type = lib.Const // @referrers ref-package "lib"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue