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