]> Cypherpunks repositories - gostls13.git/commitdiff
go/token: add example for retrieving Position from Pos
authorjimmyfrasche <soapboxcicero@gmail.com>
Mon, 12 Mar 2018 00:15:44 +0000 (17:15 -0700)
committerRobert Griesemer <gri@golang.org>
Tue, 13 Mar 2018 03:02:15 +0000 (03:02 +0000)
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 <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/go/token/example_test.go [new file with mode: 0644]

diff --git a/src/go/token/example_test.go b/src/go/token/example_test.go
new file mode 100644 (file)
index 0000000..0011703
--- /dev/null
@@ -0,0 +1,77 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package token_test
+
+import (
+       "fmt"
+       "go/ast"
+       "go/parser"
+       "go/token"
+)
+
+func Example_retrievePositionInfo() {
+       fset := token.NewFileSet()
+
+       const src = `package main
+
+import "fmt"
+
+import "go/token"
+
+//line :1:5
+type p = token.Pos
+
+const bad = token.NoPos
+
+//line fake.go:42:11
+func ok(pos p) bool {
+       return pos != bad
+}
+
+/*line :7:9*/func main() {
+       fmt.Println(ok(bad) == bad.IsValid())
+}
+`
+
+       f, err := parser.ParseFile(fset, "main.go", src, 0)
+       if err != nil {
+               fmt.Println(err)
+               return
+       }
+
+       // Print the location and kind of each declaration in f.
+       for _, decl := range f.Decls {
+               // Get the filename, line, and column back via the file set.
+               // We get both the relative and absolute position.
+               // The relative position is relative to the last line directive.
+               // The absolute position is the exact position in the source.
+               pos := decl.Pos()
+               relPosition := fset.Position(pos)
+               absPosition := fset.PositionFor(pos, false)
+
+               // Either a FuncDecl or GenDecl, since we exit on error.
+               kind := "func"
+               if gen, ok := decl.(*ast.GenDecl); ok {
+                       kind = gen.Tok.String()
+               }
+
+               // If the relative and absolute positions differ, show both.
+               fmtPosition := relPosition.String()
+               if relPosition != absPosition {
+                       fmtPosition += "[" + absPosition.String() + "]"
+               }
+
+               fmt.Printf("%s: %s\n", fmtPosition, kind)
+       }
+
+       //Output:
+       //
+       // main.go:3:1: import
+       // main.go:5:1: import
+       // main.go:1:5[main.go:8:1]: type
+       // main.go:3:1[main.go:10:1]: const
+       // fake.go:42:11[main.go:13:1]: func
+       // fake.go:7:9[main.go:17:14]: func
+}