diff options
Diffstat (limited to 'src/pkg/go/scanner/scanner_test.go')
-rw-r--r-- | src/pkg/go/scanner/scanner_test.go | 155 |
1 files changed, 89 insertions, 66 deletions
diff --git a/src/pkg/go/scanner/scanner_test.go b/src/pkg/go/scanner/scanner_test.go index eb9e1cb81..06223e23b 100644 --- a/src/pkg/go/scanner/scanner_test.go +++ b/src/pkg/go/scanner/scanner_test.go @@ -83,6 +83,8 @@ var tokens = [...]elt{ "`", literal, }, + {token.STRING, "`\r`", literal}, + {token.STRING, "`foo\r\nbar`", literal}, // Operators and delimiters {token.ADD, "+", operator}, @@ -175,13 +177,14 @@ var tokens = [...]elt{ const whitespace = " \t \n\n\n" // to separate tokens -type testErrorHandler struct { - t *testing.T -} - -func (h *testErrorHandler) Error(pos token.Position, msg string) { - h.t.Errorf("Error() called (msg = %s)", msg) -} +var source = func() []byte { + var src []byte + for _, t := range tokens { + src = append(src, t.lit...) + src = append(src, whitespace...) + } + return src +}() func newlineCount(s string) int { n := 0 @@ -212,20 +215,31 @@ func checkPos(t *testing.T, lit string, p token.Pos, expected token.Position) { // Verify that calling Scan() provides the correct results. func TestScan(t *testing.T) { // make source - var src string - for _, e := range tokens { - src += e.lit + whitespace - } - src_linecount := newlineCount(src) + src_linecount := newlineCount(string(source)) whitespace_linecount := newlineCount(whitespace) + // error handler + eh := func(_ token.Position, msg string) { + t.Errorf("error handler called (msg = %s)", msg) + } + // verify scan var s Scanner - s.Init(fset.AddFile("", fset.Base(), len(src)), []byte(src), &testErrorHandler{t}, ScanComments) + s.Init(fset.AddFile("", fset.Base(), len(source)), source, eh, ScanComments|dontInsertSemis) index := 0 - epos := token.Position{"", 0, 1, 1} // expected position + // epos is the expected position + epos := token.Position{ + Filename: "", + Offset: 0, + Line: 1, + Column: 1, + } for { pos, tok, lit := s.Scan() + if lit == "" { + // no literal value for non-literal tokens + lit = tok.String() + } e := elt{token.EOF, "", special} if index < len(tokens) { e = tokens[index] @@ -237,10 +251,18 @@ func TestScan(t *testing.T) { } checkPos(t, lit, pos, epos) if tok != e.tok { - t.Errorf("bad token for %q: got %s, expected %s", lit, tok.String(), e.tok.String()) + t.Errorf("bad token for %q: got %s, expected %s", lit, tok, e.tok) } - if e.tok.IsLiteral() && lit != e.lit { - t.Errorf("bad literal for %q: got %q, expected %q", lit, lit, e.lit) + if e.tok.IsLiteral() { + // no CRs in raw string literals + elit := e.lit + if elit[0] == '`' { + elit = string(stripCR([]byte(elit))) + epos.Offset += len(e.lit) - len(lit) // correct position + } + if lit != elit { + t.Errorf("bad literal for %q: got %q, expected %q", lit, lit, elit) + } } if tokenclass(tok) != e.class { t.Errorf("bad class for %q: got %d, expected %d", lit, tokenclass(tok), e.class) @@ -262,7 +284,7 @@ func TestScan(t *testing.T) { } } -func checkSemi(t *testing.T, line string, mode uint) { +func checkSemi(t *testing.T, line string, mode Mode) { var S Scanner file := fset.AddFile("TestSemis", fset.Base(), len(line)) S.Init(file, []byte(line), nil, mode) @@ -286,7 +308,7 @@ func checkSemi(t *testing.T, line string, mode uint) { } checkPos(t, line, pos, semiPos) } else { - t.Errorf("bad token for %q: got %s, expected ;", line, tok.String()) + t.Errorf("bad token for %q: got %s, expected ;", line, tok) } } else if tok == token.SEMICOLON { t.Errorf("bad token for %q: got ;, expected no ;", line) @@ -420,14 +442,14 @@ var lines = []string{ func TestSemis(t *testing.T) { for _, line := range lines { - checkSemi(t, line, AllowIllegalChars|InsertSemis) - checkSemi(t, line, AllowIllegalChars|InsertSemis|ScanComments) + checkSemi(t, line, 0) + checkSemi(t, line, ScanComments) // if the input ended in newlines, the input must tokenize the // same with or without those newlines for i := len(line) - 1; i >= 0 && line[i] == '\n'; i-- { - checkSemi(t, line[0:i], AllowIllegalChars|InsertSemis) - checkSemi(t, line[0:i], AllowIllegalChars|InsertSemis|ScanComments) + checkSemi(t, line[0:i], 0) + checkSemi(t, line[0:i], ScanComments) } } } @@ -482,11 +504,16 @@ func TestLineComments(t *testing.T) { // verify scan var S Scanner file := fset.AddFile(filepath.Join("dir", "TestLineComments"), fset.Base(), len(src)) - S.Init(file, []byte(src), nil, 0) + S.Init(file, []byte(src), nil, dontInsertSemis) for _, s := range segs { p, _, lit := S.Scan() pos := file.Position(p) - checkPos(t, lit, p, token.Position{s.filename, pos.Offset, s.line, pos.Column}) + checkPos(t, lit, p, token.Position{ + Filename: s.filename, + Offset: pos.Offset, + Line: s.line, + Column: pos.Column, + }) } if S.ErrorCount != 0 { @@ -501,7 +528,7 @@ func TestInit(t *testing.T) { // 1st init src1 := "if true { }" f1 := fset.AddFile("src1", fset.Base(), len(src1)) - s.Init(f1, []byte(src1), nil, 0) + s.Init(f1, []byte(src1), nil, dontInsertSemis) if f1.Size() != len(src1) { t.Errorf("bad file size: got %d, expected %d", f1.Size(), len(src1)) } @@ -509,40 +536,19 @@ func TestInit(t *testing.T) { s.Scan() // true _, tok, _ := s.Scan() // { if tok != token.LBRACE { - t.Errorf("bad token: got %s, expected %s", tok.String(), token.LBRACE) + t.Errorf("bad token: got %s, expected %s", tok, token.LBRACE) } // 2nd init src2 := "go true { ]" f2 := fset.AddFile("src2", fset.Base(), len(src2)) - s.Init(f2, []byte(src2), nil, 0) + s.Init(f2, []byte(src2), nil, dontInsertSemis) if f2.Size() != len(src2) { t.Errorf("bad file size: got %d, expected %d", f2.Size(), len(src2)) } _, tok, _ = s.Scan() // go if tok != token.GO { - t.Errorf("bad token: got %s, expected %s", tok.String(), token.GO) - } - - if s.ErrorCount != 0 { - t.Errorf("found %d errors", s.ErrorCount) - } -} - -func TestIllegalChars(t *testing.T) { - var s Scanner - - const src = "*?*$*@*" - file := fset.AddFile("", fset.Base(), len(src)) - s.Init(file, []byte(src), &testErrorHandler{t}, AllowIllegalChars) - for offs, ch := range src { - pos, tok, lit := s.Scan() - if poffs := file.Offset(pos); poffs != offs { - t.Errorf("bad position for %s: got %d, expected %d", lit, poffs, offs) - } - if tok == token.ILLEGAL && lit != string(ch) { - t.Errorf("bad token: got %s, expected %s", lit, string(ch)) - } + t.Errorf("bad token: got %s, expected %s", tok, token.GO) } if s.ErrorCount != 0 { @@ -560,36 +566,37 @@ func TestStdErrorHander(t *testing.T) { "//line File1:1\n" + "@ @ @" // original file, line 1 again - v := new(ErrorVector) + var list ErrorList + eh := func(pos token.Position, msg string) { list.Add(pos, msg) } + var s Scanner - s.Init(fset.AddFile("File1", fset.Base(), len(src)), []byte(src), v, 0) + s.Init(fset.AddFile("File1", fset.Base(), len(src)), []byte(src), eh, dontInsertSemis) for { if _, tok, _ := s.Scan(); tok == token.EOF { break } } - list := v.GetErrorList(Raw) + if len(list) != s.ErrorCount { + t.Errorf("found %d errors, expected %d", len(list), s.ErrorCount) + } + if len(list) != 9 { t.Errorf("found %d raw errors, expected 9", len(list)) PrintError(os.Stderr, list) } - list = v.GetErrorList(Sorted) + list.Sort() if len(list) != 9 { t.Errorf("found %d sorted errors, expected 9", len(list)) PrintError(os.Stderr, list) } - list = v.GetErrorList(NoMultiples) + list.RemoveMultiples() if len(list) != 4 { t.Errorf("found %d one-per-line errors, expected 4", len(list)) PrintError(os.Stderr, list) } - - if v.ErrorCount() != s.ErrorCount { - t.Errorf("found %d errors, expected %d", v.ErrorCount(), s.ErrorCount) - } } type errorCollector struct { @@ -598,16 +605,15 @@ type errorCollector struct { pos token.Position // last error position encountered } -func (h *errorCollector) Error(pos token.Position, msg string) { - h.cnt++ - h.msg = msg - h.pos = pos -} - func checkError(t *testing.T, src string, tok token.Token, pos int, err string) { var s Scanner var h errorCollector - s.Init(fset.AddFile("", fset.Base(), len(src)), []byte(src), &h, ScanComments) + eh := func(pos token.Position, msg string) { + h.cnt++ + h.msg = msg + h.pos = pos + } + s.Init(fset.AddFile("", fset.Base(), len(src)), []byte(src), eh, ScanComments|dontInsertSemis) _, tok0, _ := s.Scan() _, tok1, _ := s.Scan() if tok0 != tok { @@ -670,3 +676,20 @@ func TestScanErrors(t *testing.T) { checkError(t, e.src, e.tok, e.pos, e.err) } } + +func BenchmarkScan(b *testing.B) { + b.StopTimer() + fset := token.NewFileSet() + file := fset.AddFile("", fset.Base(), len(source)) + var s Scanner + b.StartTimer() + for i := b.N - 1; i >= 0; i-- { + s.Init(file, source, nil, ScanComments) + for { + _, tok, _ := s.Scan() + if tok == token.EOF { + break + } + } + } +} |