Source file
misc/cgo/errors/argposition_test.go
1
2
3
4
5
6
7 package errorstest
8
9 import (
10 "bytes"
11 "fmt"
12 "go/ast"
13 "go/parser"
14 "go/token"
15 "io/ioutil"
16 "os"
17 "os/exec"
18 "path/filepath"
19 "strings"
20 "testing"
21 )
22
23 type ShortPosition struct {
24 Line int
25 Column int
26 Visited bool
27 }
28
29 type IdentPositionInfo map[string][]ShortPosition
30
31 type Visitor struct {
32 identPosInfo IdentPositionInfo
33 fset *token.FileSet
34 t *testing.T
35 }
36
37 func (v *Visitor) Visit(node ast.Node) ast.Visitor {
38 if ident, ok := node.(*ast.Ident); ok {
39 if expectedPositions, ok := v.identPosInfo[ident.Name]; ok {
40 gotMatch := false
41 var errorMessage strings.Builder
42 for caseIndex, expectedPos := range expectedPositions {
43 actualPosition := v.fset.PositionFor(ident.Pos(), true)
44 errorOccured := false
45 if expectedPos.Line != actualPosition.Line {
46 fmt.Fprintf(&errorMessage, "wrong line number for ident %s: expected: %d got: %d\n", ident.Name, expectedPos.Line, actualPosition.Line)
47 errorOccured = true
48 }
49 if expectedPos.Column != actualPosition.Column {
50 fmt.Fprintf(&errorMessage, "wrong column number for ident %s: expected: %d got: %d\n", ident.Name, expectedPos.Column, actualPosition.Column)
51 errorOccured = true
52 }
53 if errorOccured {
54 continue
55 }
56 gotMatch = true
57 expectedPositions[caseIndex].Visited = true
58 }
59
60 if !gotMatch {
61 v.t.Errorf(errorMessage.String())
62 }
63 }
64 }
65 return v
66 }
67
68 func TestArgumentsPositions(t *testing.T) {
69 testdata, err := filepath.Abs("testdata")
70 if err != nil {
71 t.Fatal(err)
72 }
73
74 tmpPath := t.TempDir()
75
76 dir := filepath.Join(tmpPath, "src", "testpositions")
77 if err := os.MkdirAll(dir, 0755); err != nil {
78 t.Fatal(err)
79 }
80
81 cmd := exec.Command("go", "tool", "cgo",
82 "-srcdir", testdata,
83 "-objdir", dir,
84 "issue42580.go")
85 cmd.Stderr = new(bytes.Buffer)
86
87 err = cmd.Run()
88 if err != nil {
89 t.Fatalf("%s: %v\n%s", cmd, err, cmd.Stderr)
90 }
91 mainProcessed, err := ioutil.ReadFile(filepath.Join(dir, "issue42580.cgo1.go"))
92 if err != nil {
93 t.Fatal(err)
94 }
95 fset := token.NewFileSet()
96 f, err := parser.ParseFile(fset, "", mainProcessed, parser.AllErrors)
97 if err != nil {
98 fmt.Println(err)
99 return
100 }
101
102 expectation := IdentPositionInfo{
103 "checkedPointer": []ShortPosition{
104 ShortPosition{
105 Line: 32,
106 Column: 56,
107 },
108 },
109 "singleInnerPointerChecked": []ShortPosition{
110 ShortPosition{
111 Line: 37,
112 Column: 91,
113 },
114 },
115 "doublePointerChecked": []ShortPosition{
116 ShortPosition{
117 Line: 42,
118 Column: 91,
119 },
120 },
121 }
122 for _, decl := range f.Decls {
123 if fdecl, ok := decl.(*ast.FuncDecl); ok {
124 ast.Walk(&Visitor{expectation, fset, t}, fdecl.Body)
125 }
126 }
127 for ident, positions := range expectation {
128 for _, position := range positions {
129 if !position.Visited {
130 t.Errorf("Position %d:%d missed for %s ident", position.Line, position.Column, ident)
131 }
132 }
133 }
134 }
135
View as plain text