Skip to content

Commit 867d07f

Browse files
jimmyfraschegriesemer
authored andcommitted
go/token: add example for retrieving Position from Pos
There are few uses for the majority of the API in go/token for the average user. The exception to this is getting the filename, line, and column information from a token.Pos (reported and absolute. This is straightforward but figuring out how to do it requires combing through a lot of documentation. This example makes it more easily discoverable. Updates #24352. Change-Id: I0a45da6173b3dabebf42484bbbed30d9e5e20e01 Reviewed-on: https://go-review.googlesource.com/100058 Reviewed-by: Robert Griesemer <[email protected]> Run-TryBot: Robert Griesemer <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 2086f35 commit 867d07f

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

src/go/token/example_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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+
package token_test
6+
7+
import (
8+
"fmt"
9+
"go/ast"
10+
"go/parser"
11+
"go/token"
12+
)
13+
14+
func Example_retrievePositionInfo() {
15+
fset := token.NewFileSet()
16+
17+
const src = `package main
18+
19+
import "fmt"
20+
21+
import "go/token"
22+
23+
//line :1:5
24+
type p = token.Pos
25+
26+
const bad = token.NoPos
27+
28+
//line fake.go:42:11
29+
func 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+
}

0 commit comments

Comments
 (0)