cmd/guru: make fastQueryPos indirect through the -modified map

This fixes a bug in which guru reports a "query position beyond end of
file" error when making a query from an unsaved editor buffer at an
offset greater than the length of the file on disk.

Change-Id: I908c024d8dd14baa657b4227e3231fa760443732
Reviewed-on: https://go-review.googlesource.com/20167
Reviewed-by: Daniel Morsing <daniel.morsing@gmail.com>
This commit is contained in:
Alan Donovan 2016-03-03 13:42:12 -05:00
parent 2f1d035a8a
commit 6c84e9e3e0
4 changed files with 10 additions and 5 deletions

View File

@ -20,7 +20,7 @@ func definition(q *Query) error {
// (Extending this approach to all the files of the package,
// resolved using ast.NewPackage, was not worth the effort.)
{
qpos, err := fastQueryPos(q.Pos)
qpos, err := fastQueryPos(q.Build, q.Pos)
if err != nil {
return err
}

View File

@ -179,7 +179,7 @@ func setupPTA(prog *ssa.Program, lprog *loader.Program, ptaLog io.Writer, reflec
// query position and tells conf to import it.
// It returns the package's path.
func importQueryPackage(pos string, conf *loader.Config) (string, error) {
fqpos, err := fastQueryPos(pos)
fqpos, err := fastQueryPos(conf.Build, pos)
if err != nil {
return "", err // bad query
}

View File

@ -8,6 +8,7 @@ package main
import (
"fmt"
"go/build"
"go/parser"
"go/token"
"os"
@ -16,6 +17,7 @@ import (
"strings"
"golang.org/x/tools/go/ast/astutil"
"golang.org/x/tools/go/buildutil"
)
// parseOctothorpDecimal returns the numeric value if s matches "#%d",
@ -106,14 +108,17 @@ func sameFile(x, y string) bool {
// fastQueryPos parses the position string and returns a queryPos.
// It parses only a single file and does not run the type checker.
func fastQueryPos(pos string) (*queryPos, error) {
func fastQueryPos(ctxt *build.Context, pos string) (*queryPos, error) {
filename, startOffset, endOffset, err := parsePos(pos)
if err != nil {
return nil, err
}
// Parse the file, opening it the file via the build.Context
// so that we observe the effects of the -modified flag.
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, filename, nil, 0)
cwd, _ := os.Getwd()
f, err := buildutil.ParseFile(fset, ctxt, nil, cwd, filename, parser.Mode(0))
// ParseFile usually returns a partial file along with an error.
// Only fail if there is no file.
if f == nil {

View File

@ -25,7 +25,7 @@ import (
// the selected location.
//
func what(q *Query) error {
qpos, err := fastQueryPos(q.Pos)
qpos, err := fastQueryPos(q.Build, q.Pos)
if err != nil {
return err
}