x/tools/cmd/gorename: allow renaming to builtins

cu6pst1q  于 8个月前  发布在  Go
关注(0)|答案(4)|浏览(272)

你做了什么?
在尝试将一个变量(func等)重命名为real时,gorename工具崩溃了。
假设你有这样一个main.go:

  1. package main
  2. import "fmt"
  3. func main() {
  4. world := "Hello world!"
  5. fmt.Println(world)
  6. }

然后运行gorename -from 'main.go::world' -to real

你期望看到什么?

预期输出:
Renamed 2 occurrences in 1 file in 1 package.
以及包含

  1. package main
  2. import "fmt"
  3. func main() {
  4. real := "Hello world!"
  5. fmt.Println(real)
  6. }

main.go文件。

你看到了什么?
  1. panic: runtime error: invalid memory address or nil pointer dereference
  2. [signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x5eef75]
  3. goroutine 1 [running]:
  4. go/types.(*Package).Scope(...)
  5. /usr/local/go/src/go/types/package.go:41
  6. golang.org/x/tools/refactor/rename.lexicalLookup(0xc4222d93b0, 0x7ffe2fd24c80, 0x4, 0x6a, 0xc42000f6d0, 0x79aea0, 0xc4222d92c0)
  7. /home/rndz/golang/src/golang.org/x/tools/refactor/rename/check.go:291 +0x95
  8. golang.org/x/tools/refactor/rename.(*renamer).checkInLexicalScope.func2(0xc42000a840, 0xc4222d93b0, 0x6)
  9. /home/rndz/golang/src/golang.org/x/tools/refactor/rename/check.go:250 +0xb7
  10. golang.org/x/tools/refactor/rename.forEachLexicalRef.func1(0x7977e0, 0xc42000a840, 0x639a00)
  11. /home/rndz/golang/src/golang.org/x/tools/refactor/rename/check.go:332 +0x56c
  12. go/ast.inspector.Visit(0xc42247a000, 0x7977e0, 0xc42000a840, 0x0, 0x0)
  13. /usr/local/go/src/go/ast/walk.go:373 +0x3a
  14. go/ast.Walk(0x7969e0, 0xc42247a000, 0x7977e0, 0xc42000a840)
  15. /usr/local/go/src/go/ast/walk.go:52 +0x66
  16. go/ast.Walk(0x7969e0, 0xc42247a000, 0x7972a0, 0xc42004e700)
  17. /usr/local/go/src/go/ast/walk.go:136 +0x1041
  18. go/ast.Walk(0x7969e0, 0xc42247a000, 0x797560, 0xc420044720)
  19. /usr/local/go/src/go/ast/walk.go:196 +0x1b1c
  20. go/ast.walkStmtList(0x7969e0, 0xc42247a000, 0xc420044730, 0x1, 0x1)
  21. /usr/local/go/src/go/ast/walk.go:32 +0x81
  22. go/ast.Walk(0x7969e0, 0xc42247a000, 0x797220, 0xc42005f350)
  23. /usr/local/go/src/go/ast/walk.go:224 +0x1b71
  24. go/ast.Walk(0x7969e0, 0xc42247a000, 0x7976a0, 0xc42005f380)
  25. /usr/local/go/src/go/ast/walk.go:344 +0xd83
  26. go/ast.walkDeclList(0x7969e0, 0xc42247a000, 0xc42004e740, 0x3, 0x4)
  27. /usr/local/go/src/go/ast/walk.go:38 +0x81
  28. go/ast.Walk(0x7969e0, 0xc42247a000, 0x797620, 0xc42007c200)
  29. /usr/local/go/src/go/ast/walk.go:353 +0x266f
  30. go/ast.Inspect(0x797620, 0xc42007c200, 0xc42247a000)
  31. /usr/local/go/src/go/ast/walk.go:385 +0x4b
  32. golang.org/x/tools/refactor/rename.forEachLexicalRef(0xc4200b00b0, 0x79aea0, 0xc4222d92c0, 0xc4222e9fa0, 0xc42000e301)
  33. /home/rndz/golang/src/golang.org/x/tools/refactor/rename/check.go:365 +0x18f
  34. golang.org/x/tools/refactor/rename.(*renamer).checkInLexicalScope(0xc42017ea10, 0x79aea0, 0xc4222d92c0, 0xc4200b00b0)
  35. /home/rndz/golang/src/golang.org/x/tools/refactor/rename/check.go:244 +0xd3
  36. golang.org/x/tools/refactor/rename.(*renamer).checkInPackageBlock(0xc42017ea10, 0x79aea0, 0xc4222d92c0)
  37. /home/rndz/golang/src/golang.org/x/tools/refactor/rename/check.go:143 +0x5b3
  38. golang.org/x/tools/refactor/rename.(*renamer).check(0xc42017ea10, 0x79aea0, 0xc4222d92c0)
  39. /home/rndz/golang/src/golang.org/x/tools/refactor/rename/check.go:38 +0x3c3
  40. golang.org/x/tools/refactor/rename.Main(0x7b1b20, 0x0, 0x0, 0x7ffe2fd24c6e, 0xd, 0x7ffe2fd24c80, 0x4, 0x0, 0x0)
  41. /home/rndz/golang/src/golang.org/x/tools/refactor/rename/rename.go:347 +0x883
  42. main.main()
  43. /home/rndz/golang/src/golang.org/x/tools/cmd/gorename/main.go:49 +0x157
系统详细信息
  1. go version go1.9.2 linux/amd64
  2. GOARCH="amd64"
  3. GOBIN=""
  4. GOEXE=""
  5. GOHOSTARCH="amd64"
  6. GOHOSTOS="linux"
  7. GOOS="linux"
  8. GOPATH="/home/rndz/golang"
  9. GORACE=""
  10. GOROOT="/usr/local/go"
  11. GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
  12. GCCGO="gccgo"
  13. CC="gcc"
  14. GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build855039640=/tmp/go-build -gno-record-gcc-switches"
  15. CXX="g++"
  16. CGO_ENABLED="1"
  17. CGO_CFLAGS="-g -O2"
  18. CGO_CPPFLAGS=""
  19. CGO_CXXFLAGS="-g -O2"
  20. CGO_FFLAGS="-g -O2"
  21. CGO_LDFLAGS="-g -O2"
  22. PKG_CONFIG="pkg-config"
  23. GOROOT/bin/go version: go version go1.9.2 linux/amd64
  24. GOROOT/bin/go tool compile -V: compile version go1.9.2
  25. uname -sr: Linux 3.16.0-4-amd64
  26. Distributor ID: Debian
  27. Description: Debian GNU/Linux 8.9 (jessie)
  28. Release: 8.9
  29. Codename: jessie
  30. /lib/x86_64-linux-gnu/libc.so.6: GNU C Library (Debian GLIBC 2.19-18+deb8u10) stable release version 2.19, by Roland McGrath et al.
mkshixfv

mkshixfv1#

崩溃似乎也发生在新名称是内置名称时,例如gorename -from 'main.go::world' -to len

rn0zuynd

rn0zuynd2#

崩溃似乎也发生在新名称是内置名称的时候。
实际上,real 是一个内置名称。
与重命名到导致崩溃的内置名称相比,重命名到关键字被优雅地处理:

  1. $ gorename -from 'main.go:: world' -to else
  2. gorename: -to "else": not a valid identifier

参见 isValidIdentifier -> token.Lookup
/cc @alandonovan

6g8kf2rb

6g8kf2rb3#

我们可以通过将重命名操作与关键字处理方式相同来改进gorename。它应该返回以下错误:gorename: -to "len": not a valid identifier

mefy6pfw

mefy6pfw4#

重命名内置名称不应特别处理。有很多场合需要重用预先声明的名称,例如名为print或real的函数,或名为int或string的方法。
当然,工具不应该崩溃。

相关问题