// doQuery poses query q to the guru and writes its response and // error (if any) to out. func doQuery(out io.Writer, q *query, useJson bool) { fmt.Fprintf(out, "-------- @%s %s --------\n", q.verb, q.id) var buildContext = build.Default buildContext.GOPATH = "testdata" query := guru.Query{ Mode: q.verb, Pos: q.queryPos, Build: &buildContext, Scope: []string{q.filename}, Reflection: true, } if err := guru.Run(&query); err != nil { fmt.Fprintf(out, "\nError: %s\n", err) return } if useJson { // JSON output b, err := json.MarshalIndent(query.Serial(), "", "\t") if err != nil { fmt.Fprintf(out, "JSON error: %s\n", err.Error()) return } out.Write(b) fmt.Fprintln(out) } else { // "plain" (compiler diagnostic format) output WriteResult(out, &query) } }
// doQuery poses query q to the guru and writes its response and // error (if any) to out. func doQuery(out io.Writer, q *query, json bool) { fmt.Fprintf(out, "-------- @%s %s --------\n", q.verb, q.id) var buildContext = build.Default buildContext.GOPATH = "testdata" pkg := filepath.Dir(strings.TrimPrefix(q.filename, "testdata/src/")) gopathAbs, _ := filepath.Abs(buildContext.GOPATH) var outputMu sync.Mutex // guards outputs var outputs []string // JSON objects or lines of text outputFn := func(fset *token.FileSet, qr guru.QueryResult) { outputMu.Lock() defer outputMu.Unlock() if json { jsonstr := string(qr.JSON(fset)) // Sanitize any absolute filenames that creep in. jsonstr = strings.Replace(jsonstr, gopathAbs, "$GOPATH", -1) outputs = append(outputs, jsonstr) } else { // suppress position information qr.PrintPlain(func(_ interface{}, format string, args ...interface{}) { outputs = append(outputs, fmt.Sprintf(format, args...)) }) } } query := guru.Query{ Pos: q.queryPos, Build: &buildContext, Scope: []string{pkg}, Reflection: true, Output: outputFn, } if err := guru.Run(q.verb, &query); err != nil { fmt.Fprintf(out, "\nError: %s\n", err) return } // In a "referrers" query, references are sorted within each // package but packages are visited in arbitrary order, // so for determinism we sort them. Line 0 is a caption. if q.verb == "referrers" { sort.Strings(outputs[1:]) } for _, output := range outputs { fmt.Fprintf(out, "%s\n", output) } if !json { io.WriteString(out, "\n") } }
func TestIssue14684(t *testing.T) { var buildContext = build.Default buildContext.GOPATH = "testdata" query := guru.Query{ Pos: "testdata/src/README.txt:#1", Build: &buildContext, } err := guru.Run("freevars", &query) if err == nil { t.Fatal("guru query succeeded unexpectedly") } if got, want := err.Error(), "testdata/src/README.txt is not a Go source file"; got != want { t.Errorf("query error was %q, want %q", got, want) } }