cmd/gorename: a precise, type-aware renaming tool for Go identifiers.
See the usage message in main.go for orientation.
To the best of my knowledge, the tool implements all required
soundness checks, except:
- the dynamic behaviour of reflection is obviously undecidable.
- it rejects method renamings that change the "implements" relation.
It should probably be more aggressive.
- actually it only checks the part of the "implements" relation
needed for compilation. Understanding the dynamic behaviour
of interfaces is obviously undecidable.
- a couple of minor gaps are indicated by TODO comments.
Also:
- Emacs integration.
- tests of all safety checks and (some) successful rewrites.
https://codereview.appspot.com/139150044/diff/120001/cmd/gorename/main.go File cmd/gorename/main.go (right): https://codereview.appspot.com/139150044/diff/120001/cmd/gorename/main.go#newcode93 cmd/gorename/main.go:93: - support renaming the package clause (no object) On ...
9 years, 8 months ago
(2014-09-22 14:46:38 UTC)
#6
Thanks, all done. I've added tests of successful rewrites. They found a bug, now fixed, ...
9 years, 8 months ago
(2014-09-22 15:14:28 UTC)
#7
Thanks, all done.
I've added tests of successful rewrites.
They found a bug, now fixed, when renaming an anonymous field (the corresponding
type must be renamed too).
(I'd implemented only the reverse check before).
https://codereview.appspot.com/139150044/diff/120001/cmd/gorename/main.go
File cmd/gorename/main.go (right):
https://codereview.appspot.com/139150044/diff/120001/cmd/gorename/main.go#new...
cmd/gorename/main.go:93: - support renaming the package clause (no object)
On 2014/09/22 14:46:37, Sameer Ajmani wrote:
> On 2014/09/19 21:31:50, adonovan wrote:
> > On 2014/09/19 21:03:35, Sameer Ajmani wrote:
> > > YES!
> >
> > It's not hard, but it feels like an almost an entirely different tool: its
> -from
> > and -to are import paths (not identifiers), it must move files and
> directories,
> > and must update SCM state. Only the logic to check for name conflicts is
> > similar.
> >
> > I wonder if it would be best as a "gomvpkg" tool.
>
> I agree this sounds like a different tool. Not sure about the name. One
could
> imagine other "package level" operations like merge & split that would overlap
> with move, so perhaps there's a gopkg tool here.
Acknowledged.
https://codereview.appspot.com/139150044/diff/120001/refactor/rename/check.go
File refactor/rename/check.go (right):
https://codereview.appspot.com/139150044/diff/120001/refactor/rename/check.go...
refactor/rename/check.go:258: // requires renaming the field too.
On 2014/09/22 14:46:37, Sameer Ajmani wrote:
> On 2014/09/19 21:31:50, adonovan wrote:
> > On 2014/09/19 21:03:36, Sameer Ajmani wrote:
> > > Can you provide an example for this case?
> >
> > type T int // if we rename this to U..
> > var s struct {T}
> > print(s.T) // ...this must change too
>
> Thanks. Perhaps include this example with this comment in the code.
Done.
https://codereview.appspot.com/139150044/diff/140001/refactor/rename/spec.go
File refactor/rename/spec.go (right):
https://codereview.appspot.com/139150044/diff/140001/refactor/rename/spec.go#...
refactor/rename/spec.go:31: // If the query had a ::from component, this is
that;
On 2014/09/22 14:46:38, Sameer Ajmani wrote:
> what query?
See file documentation; the -from flag is a kind of query over the identifiers
defined in a file or package; it must return a singleton result.
https://codereview.appspot.com/139150044/diff/140001/refactor/rename/spec.go#...
refactor/rename/spec.go:37: // -- The remaining fields are private to this file.
All are optional. --
On 2014/09/22 14:46:37, Sameer Ajmani wrote:
> Are the preceding fields required?
They are both defined; pkg may be "" but fromName may not.
https://codereview.appspot.com/139150044/diff/140001/refactor/rename/spec.go#...
refactor/rename/spec.go:44: pkgmember string
On 2014/09/22 14:46:37, Sameer Ajmani wrote:
> pkgMember
Done.
https://codereview.appspot.com/139150044/diff/140001/refactor/rename/spec.go#...
refactor/rename/spec.go:47: typemember string
On 2014/09/22 14:46:38, Sameer Ajmani wrote:
> typeMember
Done.
https://codereview.appspot.com/139150044/diff/140001/refactor/rename/spec.go#...
refactor/rename/spec.go:58: const FromFlagUsage = `
On 2014/09/22 14:46:37, Sameer Ajmani wrote:
> Aha, the spec makes a lot more sense with this usage message as explanation
:-)
> Add a comment to the spec doc comment:
> // A spec specifies an entity to rename.
> // It is created from a query; see FromFlagUsage for the allowed query
forms.
Done.
https://codereview.appspot.com/139150044/diff/140001/refactor/rename/spec.go#...
refactor/rename/spec.go:64: (encoding/json.Decoder).Decode::x local object x
within a method
On 2014/09/22 14:46:37, Sameer Ajmani wrote:
> "anywhere within a method", ot mirror "anywhere in package", below?
Done.
> Specifically, does this rename x inside a function literal in the method?
> func (*Decoder) Decode() {
> ...
> f := func() {
> var x int // will this be renamed?
> }
> }
If that is the sole matching x, then yes.
The foo::x syntax means "a definition of x syntactically within the AST of foo:,
where foo is a var, func, file or package.
https://codereview.appspot.com/139150044/diff/140001/refactor/rename/spec.go#...
refactor/rename/spec.go:66: encoding/json::x object x
anywhere in package
On 2014/09/22 14:46:38, Sameer Ajmani wrote:
> Perhaps you should use encoding/json::HTMLEscape here to contrast with
> encoding/json.HTMLEscape
But it's unlikely you would ever specify HTMLEscape in this way, since you know
it's a package-level entity. ::x is really intended to make it possible to
specify local names that don't have good unambiguous name.
https://codereview.appspot.com/139150044/diff/140001/refactor/rename/spec.go#...
refactor/rename/spec.go:69: For methods attached to a pointer type, the '*' must
not be specified.
On 2014/09/22 14:46:37, Sameer Ajmani wrote:
> "must not" seems like an odd constraint here. When a method on a pointer is
> referred to in runtime.Stack output, it includes the *. Why not here?
It should probably be allowed but (for convenience) not required. Added a TODO
to fix that.
https://codereview.appspot.com/139150044/diff/140001/refactor/rename/spec.go#...
refactor/rename/spec.go:84: fallthrough
On 2014/09/22 14:46:37, Sameer Ajmani wrote:
> This logic seems unnecessarily clever.
Rephrased.
https://codereview.appspot.com/139150044/diff/180001/refactor/rename/rename.el File refactor/rename/rename.el (right): https://codereview.appspot.com/139150044/diff/180001/refactor/rename/rename.el#newcode95 refactor/rename/rename.el:95: (replace-regexp-in-string "[\t\n ]*$" This regex replaces all newlines, not ...
9 years, 8 months ago
(2014-09-22 18:31:39 UTC)
#10
https://codereview.appspot.com/139150044/diff/180001/refactor/rename/rename.el
File refactor/rename/rename.el (right):
https://codereview.appspot.com/139150044/diff/180001/refactor/rename/rename.e...
refactor/rename/rename.el:95: (replace-regexp-in-string "[\t\n ]*$"
This regex replaces all newlines, not just the last one, as $ matches end of
line, not end of string. you want \\' instead of $
https://codereview.appspot.com/139150044/diff/180001/refactor/rename/rename.e...
refactor/rename/rename.el:101: (defun go--hide-filename-links ()
I'm not sure this substitution is all that helpful for gorename. For the oracle
it makes sense, because it can possibly output dozens of lines, during normal
operation, which are only interesting as navigational targets. gorename,
however, will only display a couple of lines, and only in the case of an error.
This substitution makes it harder to see what is going on, especially as it
requires additional interaction to get to the file name/line number. Since we're
actually dealing with error output here, being able to read the full error,
including file name etc, might be more helpful than reduced clutter.
https://codereview.appspot.com/139150044/diff/180001/refactor/rename/rename.el File refactor/rename/rename.el (right): https://codereview.appspot.com/139150044/diff/180001/refactor/rename/rename.el#newcode43 refactor/rename/rename.el:43: (let* ((filename (file-truename buffer-file-name)) Using file-truename here means that ...
9 years, 8 months ago
(2014-09-22 18:58:13 UTC)
#11
https://codereview.appspot.com/139150044/diff/180001/refactor/rename/rename.el
File refactor/rename/rename.el (right):
https://codereview.appspot.com/139150044/diff/180001/refactor/rename/rename.e...
refactor/rename/rename.el:43: (let* ((filename (file-truename buffer-file-name))
Using file-truename here means that the following setup breaks:
GOPATH=~/foo
~/foo is a symlink to ~/bar
Opening ~/foo/baz.go will make gorename.el look at ~/bar/baz.go, and then it
won't be able to guess the package from the file name, as ~/bar isn't in GOPATH
– Symlinks are a fun thing, considering that when you worked on oracle.el, you
actually needed file-truename to make symlinks work, now it's the other way
around.
Are there any cases that would break if *not* using file-truename? Maybe I
should adjust my setup and stop using symlinks like that.
Thanks for the review. https://codereview.appspot.com/139150044/diff/180001/refactor/rename/rename.el File refactor/rename/rename.el (right): https://codereview.appspot.com/139150044/diff/180001/refactor/rename/rename.el#newcode23 refactor/rename/rename.el:23: (defcustom go-rename-command (concat (car (go-root-and-paths)) ...
9 years, 8 months ago
(2014-09-22 20:12:17 UTC)
#12
Thanks for the review.
https://codereview.appspot.com/139150044/diff/180001/refactor/rename/rename.el
File refactor/rename/rename.el (right):
https://codereview.appspot.com/139150044/diff/180001/refactor/rename/rename.e...
refactor/rename/rename.el:23: (defcustom go-rename-command (concat (car
(go-root-and-paths)) "/bin/gorename")
On 2014/09/22 17:57:04, Dominik Honnef wrote:
> Is there any harm in letting PATH deal with this and just invoke "gorename"?
The
> name seems sufficiently unique to me. Assuming GOROOT will probably mean that
> almost everyone will have to change this setting.
I copied this from oracle.el, but you're probably right.
Done.
https://codereview.appspot.com/139150044/diff/180001/refactor/rename/rename.e...
refactor/rename/rename.el:38: (error "Please save the current buffer before
invoking go-rename"))
On 2014/09/22 17:57:04, Dominik Honnef wrote:
> I'm still hoping that one day your tools will support reading the target file
> from stdin ;)
Yeah, me too. :)
https://codereview.appspot.com/139150044/diff/180001/refactor/rename/rename.e...
refactor/rename/rename.el:43: (let* ((filename (file-truename buffer-file-name))
On 2014/09/22 18:58:12, Dominik Honnef wrote:
> Using file-truename here means that the following setup breaks:
>
> GOPATH=~/foo
> ~/foo is a symlink to ~/bar
>
> Opening ~/foo/baz.go will make gorename.el look at ~/bar/baz.go, and then it
> won't be able to guess the package from the file name, as ~/bar isn't in
GOPATH
> – Symlinks are a fun thing, considering that when you worked on oracle.el, you
> actually needed file-truename to make symlinks work, now it's the other way
> around.
>
> Are there any cases that would break if *not* using file-truename? Maybe I
> should adjust my setup and stop using symlinks like that.
I've changed it to not use truename here; I suppose we should match the buffer's
apparent filename and the textual directory in $GOPATH, and not try to be
clever.
(I'm struggling to remember why the oracle behaviour is different. The
operations they perform internally are very similar.)
https://codereview.appspot.com/139150044/diff/180001/refactor/rename/rename.e...
refactor/rename/rename.el:46: (1- (position-bytes (point)))))
On 2014/09/22 17:57:04, Dominik Honnef wrote:
> Use go--position-bytes for (some) compatibility with XEmacs
More oracle copypasta. Will fix there too.
https://codereview.appspot.com/139150044/diff/180001/refactor/rename/rename.e...
refactor/rename/rename.el:57: (message nil) ; clears/shrinks minibuffer
On 2014/09/22 17:57:04, Dominik Honnef wrote:
> Do we need to clear if we're printing another message right after?
No. Deleted. (Ditto oracle.el.)
https://codereview.appspot.com/139150044/diff/180001/refactor/rename/rename.e...
refactor/rename/rename.el:101: (defun go--hide-filename-links ()
On 2014/09/22 18:31:39, Dominik Honnef wrote:
> I'm not sure this substitution is all that helpful for gorename. For the
oracle
> it makes sense, because it can possibly output dozens of lines, during normal
> operation, which are only interesting as navigational targets. gorename,
> however, will only display a couple of lines, and only in the case of an
error.
>
> This substitution makes it harder to see what is going on, especially as it
> requires additional interaction to get to the file name/line number. Since
we're
> actually dealing with error output here, being able to read the full error,
> including file name etc, might be more helpful than reduced clutter.
Good point. Deleted.
*** Submitted as https://code.google.com/p/go/source/detail?r=511801758bb9&repo=tools *** cmd/gorename: a precise, type-aware renaming tool for Go identifiers. See ...
9 years, 8 months ago
(2014-09-23 14:23:08 UTC)
#16
*** Submitted as
https://code.google.com/p/go/source/detail?r=511801758bb9&repo=tools ***
cmd/gorename: a precise, type-aware renaming tool for Go identifiers.
See the usage message in main.go for orientation.
To the best of my knowledge, the tool implements all required
soundness checks, except:
- the dynamic behaviour of reflection is obviously undecidable.
- it rejects method renamings that change the "implements" relation.
It should probably be more aggressive.
- actually it only checks the part of the "implements" relation
needed for compilation. Understanding the dynamic behaviour
of interfaces is obviously undecidable.
- a couple of minor gaps are indicated by TODO comments.
Also:
- Emacs integration.
- tests of all safety checks and (some) successful rewrites.
LGTM=dominik.honnef, sameer
R=gri, sameer, dominik.honnef
CC=golang-codereviews
https://codereview.appspot.com/139150044
'rename' is already present in /usr/bin on the many POSIX systems as a non-standard script ...
9 years, 8 months ago
(2014-09-23 15:28:58 UTC)
#18
'rename' is already present in /usr/bin on the many POSIX systems as a
non-standard script for renaming files according to a pattern. I think it
comes from the Perl distribution.
Plus, this tool gores the names of entities in your Go program. :)
On 23 September 2014 10:41, <r@golang.org> wrote:
> "gorename" reads to me like "gore name". why not just call it rename?
>
> https://codereview.appspot.com/139150044/
>
adonovan wrote: > 'rename' is already present in /usr/bin on the many POSIX systems as ...
9 years, 7 months ago
(2014-09-24 08:12:10 UTC)
#19
Message was sent while issue was closed.
adonovan wrote:
> 'rename' is already present in /usr/bin on the many POSIX systems as a
> non-standard script for renaming files according to a pattern.
(Yes, it's very useful; rename 's/(\d+)-(\d+)/$2-$1/' *.foo)
I too read "gore". How about renamego, since that's what it does?
Re-order the examples so the one I'm likely to need is first, not the "for
use by editors" one.
Why are -from and -to needed? I don't have to "mv -from foo -to bar".
Can't it take positional parameters instead for the common case, with a
flag without argument to say the "from" is a byte location?
Issue 139150044: code review 139150044: cmd/gorename: a precise, type-aware renaming tool for G...
(Closed)
Created 9 years, 8 months ago by adonovan
Modified 9 years, 7 months ago
Reviewers: r, Ralph Corderoy
Base URL:
Comments: 90