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

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

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

package main

import "fmt"

func main() {
	world := "Hello world!"
	fmt.Println(world)
}

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

你期望看到什么?

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

package main

import "fmt"

func main() {
	real := "Hello world!"
	fmt.Println(real)
}

main.go文件。

你看到了什么?
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x5eef75]

goroutine 1 [running]:
go/types.(*Package).Scope(...)
        /usr/local/go/src/go/types/package.go:41
golang.org/x/tools/refactor/rename.lexicalLookup(0xc4222d93b0, 0x7ffe2fd24c80, 0x4, 0x6a, 0xc42000f6d0, 0x79aea0, 0xc4222d92c0)
        /home/rndz/golang/src/golang.org/x/tools/refactor/rename/check.go:291 +0x95
golang.org/x/tools/refactor/rename.(*renamer).checkInLexicalScope.func2(0xc42000a840, 0xc4222d93b0, 0x6)
        /home/rndz/golang/src/golang.org/x/tools/refactor/rename/check.go:250 +0xb7
golang.org/x/tools/refactor/rename.forEachLexicalRef.func1(0x7977e0, 0xc42000a840, 0x639a00)
        /home/rndz/golang/src/golang.org/x/tools/refactor/rename/check.go:332 +0x56c
go/ast.inspector.Visit(0xc42247a000, 0x7977e0, 0xc42000a840, 0x0, 0x0)
        /usr/local/go/src/go/ast/walk.go:373 +0x3a
go/ast.Walk(0x7969e0, 0xc42247a000, 0x7977e0, 0xc42000a840)
        /usr/local/go/src/go/ast/walk.go:52 +0x66
go/ast.Walk(0x7969e0, 0xc42247a000, 0x7972a0, 0xc42004e700)
        /usr/local/go/src/go/ast/walk.go:136 +0x1041
go/ast.Walk(0x7969e0, 0xc42247a000, 0x797560, 0xc420044720)
        /usr/local/go/src/go/ast/walk.go:196 +0x1b1c
go/ast.walkStmtList(0x7969e0, 0xc42247a000, 0xc420044730, 0x1, 0x1)
        /usr/local/go/src/go/ast/walk.go:32 +0x81
go/ast.Walk(0x7969e0, 0xc42247a000, 0x797220, 0xc42005f350)
        /usr/local/go/src/go/ast/walk.go:224 +0x1b71
go/ast.Walk(0x7969e0, 0xc42247a000, 0x7976a0, 0xc42005f380)
        /usr/local/go/src/go/ast/walk.go:344 +0xd83
go/ast.walkDeclList(0x7969e0, 0xc42247a000, 0xc42004e740, 0x3, 0x4)
        /usr/local/go/src/go/ast/walk.go:38 +0x81
go/ast.Walk(0x7969e0, 0xc42247a000, 0x797620, 0xc42007c200)
        /usr/local/go/src/go/ast/walk.go:353 +0x266f
go/ast.Inspect(0x797620, 0xc42007c200, 0xc42247a000)
        /usr/local/go/src/go/ast/walk.go:385 +0x4b
golang.org/x/tools/refactor/rename.forEachLexicalRef(0xc4200b00b0, 0x79aea0, 0xc4222d92c0, 0xc4222e9fa0, 0xc42000e301)
        /home/rndz/golang/src/golang.org/x/tools/refactor/rename/check.go:365 +0x18f
golang.org/x/tools/refactor/rename.(*renamer).checkInLexicalScope(0xc42017ea10, 0x79aea0, 0xc4222d92c0, 0xc4200b00b0)
        /home/rndz/golang/src/golang.org/x/tools/refactor/rename/check.go:244 +0xd3
golang.org/x/tools/refactor/rename.(*renamer).checkInPackageBlock(0xc42017ea10, 0x79aea0, 0xc4222d92c0)
        /home/rndz/golang/src/golang.org/x/tools/refactor/rename/check.go:143 +0x5b3
golang.org/x/tools/refactor/rename.(*renamer).check(0xc42017ea10, 0x79aea0, 0xc4222d92c0)
        /home/rndz/golang/src/golang.org/x/tools/refactor/rename/check.go:38 +0x3c3
golang.org/x/tools/refactor/rename.Main(0x7b1b20, 0x0, 0x0, 0x7ffe2fd24c6e, 0xd, 0x7ffe2fd24c80, 0x4, 0x0, 0x0)
        /home/rndz/golang/src/golang.org/x/tools/refactor/rename/rename.go:347 +0x883
main.main()
        /home/rndz/golang/src/golang.org/x/tools/cmd/gorename/main.go:49 +0x157
系统详细信息
go version go1.9.2 linux/amd64
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/rndz/golang"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build855039640=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOROOT/bin/go version: go version go1.9.2 linux/amd64
GOROOT/bin/go tool compile -V: compile version go1.9.2
uname -sr: Linux 3.16.0-4-amd64
Distributor ID:	Debian
Description:	Debian GNU/Linux 8.9 (jessie)
Release:	8.9
Codename:	jessie
/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 是一个内置名称。
与重命名到导致崩溃的内置名称相比,重命名到关键字被优雅地处理:

$ gorename -from 'main.go:: world' -to else
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的方法。
当然,工具不应该崩溃。

相关问题