github.com/golang/gofrontend@v0.0.0-20240429183944-60f985a78526/libgo/misc/cgo/errors/argposition_test.go (about) 1 // Copyright 2021 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Issue 42580: cmd/cgo: shifting identifier position in ast 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 }