Commit e538770d authored by Robert Griesemer's avatar Robert Griesemer

go/parser: Use test-specific filesets to avoid races.

Only affects test code.

Fixes #9025.
Fixes #9130.

LGTM=r, adonovan
R=adonovan, r
CC=golang-codereviews
https://golang.org/cl/180920043
parent 2b3f3790
...@@ -34,11 +34,9 @@ import ( ...@@ -34,11 +34,9 @@ import (
const testdata = "testdata" const testdata = "testdata"
var fsetErrs = token.NewFileSet()
// getFile assumes that each filename occurs at most once // getFile assumes that each filename occurs at most once
func getFile(filename string) (file *token.File) { func getFile(fset *token.FileSet, filename string) (file *token.File) {
fsetErrs.Iterate(func(f *token.File) bool { fset.Iterate(func(f *token.File) bool {
if f.Name() == filename { if f.Name() == filename {
if file != nil { if file != nil {
panic(filename + " used multiple times") panic(filename + " used multiple times")
...@@ -50,8 +48,8 @@ func getFile(filename string) (file *token.File) { ...@@ -50,8 +48,8 @@ func getFile(filename string) (file *token.File) {
return file return file
} }
func getPos(filename string, offset int) token.Pos { func getPos(fset *token.FileSet, filename string, offset int) token.Pos {
if f := getFile(filename); f != nil { if f := getFile(fset, filename); f != nil {
return f.Pos(offset) return f.Pos(offset)
} }
return token.NoPos return token.NoPos
...@@ -68,14 +66,14 @@ var errRx = regexp.MustCompile(`^/\* *ERROR *(HERE)? *"([^"]*)" *\*/$`) ...@@ -68,14 +66,14 @@ var errRx = regexp.MustCompile(`^/\* *ERROR *(HERE)? *"([^"]*)" *\*/$`)
// expectedErrors collects the regular expressions of ERROR comments found // expectedErrors collects the regular expressions of ERROR comments found
// in files and returns them as a map of error positions to error messages. // in files and returns them as a map of error positions to error messages.
// //
func expectedErrors(t *testing.T, filename string, src []byte) map[token.Pos]string { func expectedErrors(t *testing.T, fset *token.FileSet, filename string, src []byte) map[token.Pos]string {
errors := make(map[token.Pos]string) errors := make(map[token.Pos]string)
var s scanner.Scanner var s scanner.Scanner
// file was parsed already - do not add it again to the file // file was parsed already - do not add it again to the file
// set otherwise the position information returned here will // set otherwise the position information returned here will
// not match the position information collected by the parser // not match the position information collected by the parser
s.Init(getFile(filename), src, nil, scanner.ScanComments) s.Init(getFile(fset, filename), src, nil, scanner.ScanComments)
var prev token.Pos // position of last non-comment, non-semicolon token var prev token.Pos // position of last non-comment, non-semicolon token
var here token.Pos // position immediately after the token at position prev var here token.Pos // position immediately after the token at position prev
...@@ -109,11 +107,11 @@ func expectedErrors(t *testing.T, filename string, src []byte) map[token.Pos]str ...@@ -109,11 +107,11 @@ func expectedErrors(t *testing.T, filename string, src []byte) map[token.Pos]str
// compareErrors compares the map of expected error messages with the list // compareErrors compares the map of expected error messages with the list
// of found errors and reports discrepancies. // of found errors and reports discrepancies.
// //
func compareErrors(t *testing.T, expected map[token.Pos]string, found scanner.ErrorList) { func compareErrors(t *testing.T, fset *token.FileSet, expected map[token.Pos]string, found scanner.ErrorList) {
for _, error := range found { for _, error := range found {
// error.Pos is a token.Position, but we want // error.Pos is a token.Position, but we want
// a token.Pos so we can do a map lookup // a token.Pos so we can do a map lookup
pos := getPos(error.Pos.Filename, error.Pos.Offset) pos := getPos(fset, error.Pos.Filename, error.Pos.Offset)
if msg, found := expected[pos]; found { if msg, found := expected[pos]; found {
// we expect a message at pos; check if it matches // we expect a message at pos; check if it matches
rx, err := regexp.Compile(msg) rx, err := regexp.Compile(msg)
...@@ -140,7 +138,7 @@ func compareErrors(t *testing.T, expected map[token.Pos]string, found scanner.Er ...@@ -140,7 +138,7 @@ func compareErrors(t *testing.T, expected map[token.Pos]string, found scanner.Er
if len(expected) > 0 { if len(expected) > 0 {
t.Errorf("%d errors not reported:", len(expected)) t.Errorf("%d errors not reported:", len(expected))
for pos, msg := range expected { for pos, msg := range expected {
t.Errorf("%s: %s\n", fsetErrs.Position(pos), msg) t.Errorf("%s: %s\n", fset.Position(pos), msg)
} }
} }
} }
...@@ -152,7 +150,8 @@ func checkErrors(t *testing.T, filename string, input interface{}) { ...@@ -152,7 +150,8 @@ func checkErrors(t *testing.T, filename string, input interface{}) {
return return
} }
_, err = ParseFile(fsetErrs, filename, src, DeclarationErrors|AllErrors) fset := token.NewFileSet()
_, err = ParseFile(fset, filename, src, DeclarationErrors|AllErrors)
found, ok := err.(scanner.ErrorList) found, ok := err.(scanner.ErrorList)
if err != nil && !ok { if err != nil && !ok {
t.Error(err) t.Error(err)
...@@ -162,10 +161,10 @@ func checkErrors(t *testing.T, filename string, input interface{}) { ...@@ -162,10 +161,10 @@ func checkErrors(t *testing.T, filename string, input interface{}) {
// we are expecting the following errors // we are expecting the following errors
// (collect these after parsing a file so that it is found in the file set) // (collect these after parsing a file so that it is found in the file set)
expected := expectedErrors(t, filename, src) expected := expectedErrors(t, fset, filename, src)
// verify errors returned by the parser // verify errors returned by the parser
compareErrors(t, expected, found) compareErrors(t, fset, expected, found)
} }
func TestErrors(t *testing.T) { func TestErrors(t *testing.T) {
......
...@@ -14,8 +14,6 @@ import ( ...@@ -14,8 +14,6 @@ import (
"testing" "testing"
) )
var fset = token.NewFileSet()
var validFiles = []string{ var validFiles = []string{
"parser.go", "parser.go",
"parser_test.go", "parser_test.go",
...@@ -25,7 +23,7 @@ var validFiles = []string{ ...@@ -25,7 +23,7 @@ var validFiles = []string{
func TestParse(t *testing.T) { func TestParse(t *testing.T) {
for _, filename := range validFiles { for _, filename := range validFiles {
_, err := ParseFile(fset, filename, nil, DeclarationErrors) _, err := ParseFile(token.NewFileSet(), filename, nil, DeclarationErrors)
if err != nil { if err != nil {
t.Fatalf("ParseFile(%s): %v", filename, err) t.Fatalf("ParseFile(%s): %v", filename, err)
} }
...@@ -46,7 +44,7 @@ func dirFilter(f os.FileInfo) bool { return nameFilter(f.Name()) } ...@@ -46,7 +44,7 @@ func dirFilter(f os.FileInfo) bool { return nameFilter(f.Name()) }
func TestParseDir(t *testing.T) { func TestParseDir(t *testing.T) {
path := "." path := "."
pkgs, err := ParseDir(fset, path, dirFilter, 0) pkgs, err := ParseDir(token.NewFileSet(), path, dirFilter, 0)
if err != nil { if err != nil {
t.Fatalf("ParseDir(%s): %v", path, err) t.Fatalf("ParseDir(%s): %v", path, err)
} }
...@@ -131,7 +129,7 @@ func TestParseExpr(t *testing.T) { ...@@ -131,7 +129,7 @@ func TestParseExpr(t *testing.T) {
} }
func TestColonEqualsScope(t *testing.T) { func TestColonEqualsScope(t *testing.T) {
f, err := ParseFile(fset, "", `package p; func f() { x, y, z := x, y, z }`, 0) f, err := ParseFile(token.NewFileSet(), "", `package p; func f() { x, y, z := x, y, z }`, 0)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -153,7 +151,7 @@ func TestColonEqualsScope(t *testing.T) { ...@@ -153,7 +151,7 @@ func TestColonEqualsScope(t *testing.T) {
} }
func TestVarScope(t *testing.T) { func TestVarScope(t *testing.T) {
f, err := ParseFile(fset, "", `package p; func f() { var x, y, z = x, y, z }`, 0) f, err := ParseFile(token.NewFileSet(), "", `package p; func f() { var x, y, z = x, y, z }`, 0)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -183,7 +181,7 @@ var x int ...@@ -183,7 +181,7 @@ var x int
func f() { L: } func f() { L: }
` `
f, err := ParseFile(fset, "", src, 0) f, err := ParseFile(token.NewFileSet(), "", src, 0)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -221,7 +219,7 @@ func f() { L: } ...@@ -221,7 +219,7 @@ func f() { L: }
} }
func TestUnresolved(t *testing.T) { func TestUnresolved(t *testing.T) {
f, err := ParseFile(fset, "", ` f, err := ParseFile(token.NewFileSet(), "", `
package p package p
// //
func f1a(int) func f1a(int)
...@@ -316,7 +314,7 @@ var imports = map[string]bool{ ...@@ -316,7 +314,7 @@ var imports = map[string]bool{
func TestImports(t *testing.T) { func TestImports(t *testing.T) {
for path, isValid := range imports { for path, isValid := range imports {
src := fmt.Sprintf("package p; import %s", path) src := fmt.Sprintf("package p; import %s", path)
_, err := ParseFile(fset, "", src, 0) _, err := ParseFile(token.NewFileSet(), "", src, 0)
switch { switch {
case err != nil && isValid: case err != nil && isValid:
t.Errorf("ParseFile(%s): got %v; expected no error", src, err) t.Errorf("ParseFile(%s): got %v; expected no error", src, err)
...@@ -327,7 +325,7 @@ func TestImports(t *testing.T) { ...@@ -327,7 +325,7 @@ func TestImports(t *testing.T) {
} }
func TestCommentGroups(t *testing.T) { func TestCommentGroups(t *testing.T) {
f, err := ParseFile(fset, "", ` f, err := ParseFile(token.NewFileSet(), "", `
package p /* 1a */ /* 1b */ /* 1c */ // 1d package p /* 1a */ /* 1b */ /* 1c */ // 1d
/* 2a /* 2a
*/ */
...@@ -421,7 +419,7 @@ func checkFieldComments(t *testing.T, file *ast.File, fieldname, lead, line stri ...@@ -421,7 +419,7 @@ func checkFieldComments(t *testing.T, file *ast.File, fieldname, lead, line stri
} }
func TestLeadAndLineComments(t *testing.T) { func TestLeadAndLineComments(t *testing.T) {
f, err := ParseFile(fset, "", ` f, err := ParseFile(token.NewFileSet(), "", `
package p package p
type T struct { type T struct {
/* F1 lead comment */ /* F1 lead comment */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment