diff --git a/cmd/gorename/main.go b/cmd/gorename/main.go index abf059a1..ea08f881 100644 --- a/cmd/gorename/main.go +++ b/cmd/gorename/main.go @@ -1,6 +1,10 @@ // The gorename command performs precise type-safe renaming of -// identifiers in Go source code. See the -help message or Usage -// constant for details. +// identifiers in Go source code. +// +// Run with -help for usage information, or view the Usage constant in +// package golang.org/x/tools/refactor/rename, which contains most of +// the implementation. +// package main // import "golang.org/x/tools/cmd/gorename" import ( @@ -36,89 +40,6 @@ func init() { } } -const Usage = `gorename: precise type-safe renaming of identifiers in Go source code. - -Usage: - - gorename (-from | -offset :#) -to [-force] - -You must specify the object (named entity) to rename using the -offset -or -from flag. Exactly one must be specified. - -Flags: - --offset specifies the filename and byte offset of an identifier to rename. - This form is intended for use by text editors. - --from specifies the object to rename using a query notation; - This form is intended for interactive use at the command line. -` + rename.FromFlagUsage + ` - --to the new name. - --force causes the renaming to proceed even if conflicts were reported. - The resulting program may be ill-formed, or experience a change - in behaviour. - - WARNING: this flag may even cause the renaming tool to crash. - (In due course this bug will be fixed by moving certain - analyses into the type-checker.) - --dryrun causes the tool to report conflicts but not update any files. - --v enables verbose logging. - -gorename automatically computes the set of packages that might be -affected. For a local renaming, this is just the package specified by --from or -offset, but for a potentially exported name, gorename scans -the workspace ($GOROOT and $GOPATH). - -gorename rejects renamings of concrete methods that would change the -assignability relation between types and interfaces. If the interface -change was intentional, initiate the renaming at the interface method. - -gorename rejects any renaming that would create a conflict at the point -of declaration, or a reference conflict (ambiguity or shadowing), or -anything else that could cause the resulting program not to compile. - - -Examples: - -% gorename -offset file.go:#123 -to foo - - Rename the object whose identifier is at byte offset 123 within file file.go. - -% gorename -from '"bytes".Buffer.Len' -to Size - - Rename the "Len" method of the *bytes.Buffer type to "Size". - ----- TODO ---- - -Correctness: -- handle dot imports correctly -- document limitations (reflection, 'implements' guesswork). -- sketch a proof of exhaustiveness. - -Features: -- support running on packages specified as *.go files on the command line -- support running on programs containing errors (loader.Config.AllowErrors) -- allow users to specify a scope other than "global" (to avoid being - stuck by neglected packages in $GOPATH that don't build). -- support renaming the package clause (no object) -- support renaming an import path (no ident or object) - (requires filesystem + SCM updates). -- detect and reject edits to autogenerated files (cgo, protobufs) - and optionally $GOROOT packages. -- report all conflicts, or at least all qualitatively distinct ones. - Sometimes we stop to avoid redundancy, but - it may give a disproportionate sense of safety in -force mode. -- support renaming all instances of a pattern, e.g. - all receiver vars of a given type, - all local variables of a given type, - all PkgNames for a given package. -- emit JSON output for other editors and tools. -` - func main() { flag.Parse() if len(flag.Args()) > 0 { @@ -127,7 +48,7 @@ func main() { } if *helpFlag || (*offsetFlag == "" && *fromFlag == "" && *toFlag == "") { - fmt.Println(Usage) + fmt.Println(rename.Usage) return } diff --git a/refactor/rename/rename.go b/refactor/rename/rename.go index dabfbee5..e68e5b3a 100644 --- a/refactor/rename/rename.go +++ b/refactor/rename/rename.go @@ -3,8 +3,8 @@ // license that can be found in the LICENSE file. // Package rename contains the implementation of the 'gorename' command -// whose main function is in golang.org/x/tools/refactor/rename. -// See that package for the command documentation. +// whose main function is in golang.org/x/tools/cmd/gorename. +// See the Usage constant for the command documentation. package rename // import "golang.org/x/tools/refactor/rename" import ( @@ -26,6 +26,108 @@ import ( "golang.org/x/tools/refactor/satisfy" ) +const Usage = `gorename: precise type-safe renaming of identifiers in Go source code. + +Usage: + + gorename (-from | -offset :#) -to [-force] + +You must specify the object (named entity) to rename using the -offset +or -from flag. Exactly one must be specified. + +Flags: + +-offset specifies the filename and byte offset of an identifier to rename. + This form is intended for use by text editors. + +-from specifies the object to rename using a query notation; + This form is intended for interactive use at the command line. + A legal -from query has one of the following forms: + + "encoding/json".Decoder.Decode method of package-level named type + (*"encoding/json".Decoder).Decode ditto, alternative syntax + "encoding/json".Decoder.buf field of package-level named struct type + "encoding/json".HTMLEscape package member (const, func, var, type) + "encoding/json".Decoder.Decode::x local object x within a method + "encoding/json".HTMLEscape::x local object x within a function + "encoding/json"::x object x anywhere within a package + json.go::x object x within file json.go + + For methods, the parens and '*' on the receiver type are both + optional. + + Double-quotes may be omitted for single-segment import paths + such as fmt. They may need to be escaped when writing a + shell command. + + It is an error if one of the ::x queries matches multiple + objects. + +-to the new name. + +-force causes the renaming to proceed even if conflicts were reported. + The resulting program may be ill-formed, or experience a change + in behaviour. + + WARNING: this flag may even cause the renaming tool to crash. + (In due course this bug will be fixed by moving certain + analyses into the type-checker.) + +-dryrun causes the tool to report conflicts but not update any files. + +-v enables verbose logging. + +gorename automatically computes the set of packages that might be +affected. For a local renaming, this is just the package specified by +-from or -offset, but for a potentially exported name, gorename scans +the workspace ($GOROOT and $GOPATH). + +gorename rejects renamings of concrete methods that would change the +assignability relation between types and interfaces. If the interface +change was intentional, initiate the renaming at the interface method. + +gorename rejects any renaming that would create a conflict at the point +of declaration, or a reference conflict (ambiguity or shadowing), or +anything else that could cause the resulting program not to compile. + + +Examples: + +% gorename -offset file.go:#123 -to foo + + Rename the object whose identifier is at byte offset 123 within file file.go. + +% gorename -from '"bytes".Buffer.Len' -to Size + + Rename the "Len" method of the *bytes.Buffer type to "Size". + +---- TODO ---- + +Correctness: +- handle dot imports correctly +- document limitations (reflection, 'implements' algorithm). +- sketch a proof of exhaustiveness. + +Features: +- support running on packages specified as *.go files on the command line +- support running on programs containing errors (loader.Config.AllowErrors) +- allow users to specify a scope other than "global" (to avoid being + stuck by neglected packages in $GOPATH that don't build). +- support renaming the package clause (no object) +- support renaming an import path (no ident or object) + (requires filesystem + SCM updates). +- detect and reject edits to autogenerated files (cgo, protobufs) + and optionally $GOROOT packages. +- report all conflicts, or at least all qualitatively distinct ones. + Sometimes we stop to avoid redundancy, but + it may give a disproportionate sense of safety in -force mode. +- support renaming all instances of a pattern, e.g. + all receiver vars of a given type, + all local variables of a given type, + all PkgNames for a given package. +- emit JSON output for other editors and tools. +` + var ( // Force enables patching of the source files even if conflicts were reported. // The resulting program may be ill-formed. diff --git a/refactor/rename/spec.go b/refactor/rename/spec.go index d39e0673..3c736535 100644 --- a/refactor/rename/spec.go +++ b/refactor/rename/spec.go @@ -6,7 +6,7 @@ package rename // This file contains logic related to specifying a renaming: parsing of // the flags as a form of query, and finding the object(s) it denotes. -// See FromFlagUsage for details. +// See Usage for flag details. import ( "bytes" @@ -27,8 +27,8 @@ import ( // A spec specifies an entity to rename. // -// It is populated from an -offset flag or -from query; see -// FromFlagUsage for the allowed -from query forms. +// It is populated from an -offset flag or -from query; +// see Usage for the allowed -from query forms. // type spec struct { // pkg is the package containing the position @@ -65,28 +65,8 @@ type spec struct { offset int } -const FromFlagUsage = ` -A legal -from query has one of the following forms: - - "encoding/json".Decoder.Decode method of package-level named type - (*"encoding/json".Decoder).Decode ditto, alternative syntax - "encoding/json".Decoder.buf field of package-level named struct type - "encoding/json".HTMLEscape package member (const, func, var, type) - "encoding/json".Decoder.Decode::x local object x within a method - "encoding/json".HTMLEscape::x local object x within a function - "encoding/json"::x object x anywhere within a package - json.go::x object x within file json.go - - For methods, the parens and '*' on the receiver type are both optional. - - Double-quotes may be omitted for single-segment import paths such as - fmt. They may need to be escaped when writing a shell command. - - It is an error if one of the ::x queries matches multiple objects. -` - // parseFromFlag interprets the "-from" flag value as a renaming specification. -// See FromFlagUsage for valid formats. +// See Usage in rename.go for valid formats. func parseFromFlag(ctxt *build.Context, fromFlag string) (*spec, error) { var spec spec var main string // sans "::x" suffix