Skip to content

Instantly share code, notes, and snippets.

@tenntenn
Last active January 5, 2017 05:19
Show Gist options
  • Save tenntenn/97320cdb91346d0abd0e68261de7aa97 to your computer and use it in GitHub Desktop.
Save tenntenn/97320cdb91346d0abd0e68261de7aa97 to your computer and use it in GitHub Desktop.
go/typesパッケージを使い変数名をリネームしてみる #golang ref: http://qiita.com/tenntenn/items/beea3bd019ba92b4d62a
$ golang.org/x/tools/cmd/gorename
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "sample.go", src, 0)
if err != nil {
log.Fatalln("Error:", err)
}
package main
var msg = "hoge"
func main() {
msg := "Hello,"
msg += " World"
println(msg)
}
package main
func main() {
msg := "Hello,"
msg += " World"
println(msg)
}
// 47バイト目 = msg
const p = 47
var pos token.Pos
fset.Iterate(func(f *token.File) bool {
if f.Name() == "sample.go" {
pos = f.Pos(p)
return false
}
return true
})
var ident *ast.Ident
ast.Inspect(f, func(n ast.Node) bool {
if n == nil || pos < n.Pos() || pos > n.End() {
return true
}
if n, ok := n.(*ast.Ident); ok {
ident = n
return false
}
return true
})
conf := &types.Config{
Importer: importer.Default(),
}
info := &types.Info{
Defs: map[*ast.Ident]types.Object{},
Uses: map[*ast.Ident]types.Object{},
}
_, err = conf.Check("main", fset, []*ast.File{f}, info)
if err != nil {
log.Fatalln("Error:", err)
}
type Object interface {
Parent() *Scope // scope in which this object is declared
Pos() token.Pos // position of object identifier in declaration
Pkg() *Package // nil for objects in the Universe scope and labels
Name() string // package local object name
Type() Type // object type
Exported() bool // reports whether the name starts with a capital letter
Id() string // object id (see Id below)
// String returns a human-readable string of the object.
String() string
// contains filtered or unexported methods
}
from := ident.Name
const to = "message"
fmt.Println(ident, "->", to)
obj := info.Defs[ident]
if obj == nil {
obj = info.Uses[ident]
}
// Defs
fmt.Println("== Defs ==")
for i, o := range info.Defs {
if i.Name == from && o.Parent() == obj.Parent() {
fmt.Println(fset.Position(i.Pos()))
i.Name = to
}
}
// Uses
fmt.Println("== Uses ==")
for i, o := range info.Uses {
if i.Name == from && o.Parent() == obj.Parent() {
fmt.Println(fset.Position(i.Pos()))
i.Name = to
}
}
package main
import (
"fmt"
"go/ast"
"go/format"
"go/importer"
"go/parser"
"go/token"
"go/types"
"log"
"os"
)
// sample.go
const src = `package main
func main() {
msg := "Hello,"
msg += " World"
println(msg)
}`
func main() {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "sample.go", src, 0)
if err != nil {
log.Fatalln("Error:", err)
}
conf := &types.Config{
Importer: importer.Default(),
}
info := &types.Info{
Defs: map[*ast.Ident]types.Object{},
Uses: map[*ast.Ident]types.Object{},
}
_, err = conf.Check("main", fset, []*ast.File{f}, info)
if err != nil {
log.Fatalln("Error:", err)
}
// 47バイト目 = msg
const p = 47
var pos token.Pos
fset.Iterate(func(f *token.File) bool {
if f.Name() == "sample.go" {
pos = f.Pos(p)
return false
}
return true
})
var ident *ast.Ident
ast.Inspect(f, func(n ast.Node) bool {
if n == nil || pos < n.Pos() || pos > n.End() {
return true
}
if n, ok := n.(*ast.Ident); ok {
ident = n
return false
}
return true
})
from := ident.Name
const to = "message"
fmt.Println(ident, "->", to)
obj := info.Defs[ident]
if obj == nil {
obj = info.Uses[ident]
}
// Defs
fmt.Println("== Defs ==")
for i, o := range info.Defs {
if i.Name == from && o.Parent() == obj.Parent() {
fmt.Println(fset.Position(i.Pos()))
i.Name = to
}
}
// Uses
fmt.Println("== Uses ==")
for i, o := range info.Uses {
if i.Name == from && o.Parent() == obj.Parent() {
fmt.Println(fset.Position(i.Pos()))
i.Name = to
}
}
fmt.Println()
fmt.Println("==== Before ====")
fmt.Println(src)
fmt.Println()
fmt.Println("==== After ====")
format.Node(os.Stdout, fset, f)
}
msg -> message
== Defs ==
sample.go:6:2
== Uses ==
sample.go:7:2
sample.go:8:10
==== Before ====
package main
var msg = "hoge"
func main() {
msg := "Hello,"
msg += " World"
println(msg)
}
==== After ====
package main
var msg = "hoge"
func main() {
message := "Hello,"
message += " World"
println(message)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment