1// Copyright 2018 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 5package token_test 6 7import ( 8 "fmt" 9 "go/ast" 10 "go/parser" 11 "go/token" 12) 13 14func Example_retrievePositionInfo() { 15 fset := token.NewFileSet() 16 17 const src = `package main 18 19import "fmt" 20 21import "go/token" 22 23//line :1:5 24type p = token.Pos 25 26const bad = token.NoPos 27 28//line fake.go:42:11 29func ok(pos p) bool { 30 return pos != bad 31} 32 33/*line :7:9*/func main() { 34 fmt.Println(ok(bad) == bad.IsValid()) 35} 36` 37 38 f, err := parser.ParseFile(fset, "main.go", src, 0) 39 if err != nil { 40 fmt.Println(err) 41 return 42 } 43 44 // Print the location and kind of each declaration in f. 45 for _, decl := range f.Decls { 46 // Get the filename, line, and column back via the file set. 47 // We get both the relative and absolute position. 48 // The relative position is relative to the last line directive. 49 // The absolute position is the exact position in the source. 50 pos := decl.Pos() 51 relPosition := fset.Position(pos) 52 absPosition := fset.PositionFor(pos, false) 53 54 // Either a FuncDecl or GenDecl, since we exit on error. 55 kind := "func" 56 if gen, ok := decl.(*ast.GenDecl); ok { 57 kind = gen.Tok.String() 58 } 59 60 // If the relative and absolute positions differ, show both. 61 fmtPosition := relPosition.String() 62 if relPosition != absPosition { 63 fmtPosition += "[" + absPosition.String() + "]" 64 } 65 66 fmt.Printf("%s: %s\n", fmtPosition, kind) 67 } 68 69 // Output: 70 // 71 // main.go:3:1: import 72 // main.go:5:1: import 73 // main.go:1:5[main.go:8:1]: type 74 // main.go:3:1[main.go:10:1]: const 75 // fake.go:42:11[main.go:13:1]: func 76 // fake.go:7:9[main.go:17:14]: func 77} 78