Closed sorawee closed 4 years ago
I am not sure about this -- I never thought that we should compare the characters in the original program! It seems like it might be that someone somewhere has a language that this would break if they, for example, equate variables with and without accents of them or ... who knows what else.
Still, for the majority of things (everything I actually know about) this seems like a great idea!
I'm not sure if it is necessary but we could add a backwards compatibility hedge in the form of a property that would say "rename even if the name is different" that could be plumbed through?
And we probably do need some tests (this time I'm just not missing them am I?).
CC: @greghendershott
I am not sure about this -- I never thought that we should compare the characters in the original program! It seems like it might be that someone somewhere has a language that this would break if they, for example, equate variables with and without accents of them or ... who knows what else.
That's a good point. One instance I can see is when read-case-sensitive
is #f
(such as #lang r5rs
). This PR would make it not possible to rename A
in:
#lang r5rs
(define a 1)
A
There are two problems at hand: (1) how can language + macro indicate when it's safe (or unsafe) to rename an identifier? (2) how can Check Syntax provide these information to clients (e.g., DrRacket, Racket Mode) in a backward-compatible manner?
For (2), Racket Mode currently uses syncheck:add-arrow/name-dup/pxpy
to decide whether or not a variable is rename-able. For example, Racket Mode deliberately restricts renaming to local variables (require-arrow
in syncheck:add-arrow/name-dup/pxpy
is #f
). This suggests that the fix is to extend syncheck:add-arrow/name-dup/pxpy
to syncheck:add-arrow/name-dup/pxpy/renamable
. The additional argument renamable?
would indicate if renaming either end should affect the other end. When require-arrow
is not #f
, renamable?
will be #f
.
Racket Mode would implement both syncheck:add-arrow/name-dup/pxpy
and syncheck:add-arrow/name-dup/pxpy/renamable
to support both old and new versions of DrRacket. At runtime, it can first check if syncheck-annotations<%>
has a method syncheck:add-arrow/name-dup/pxpy/renamable
, and if it does, syncheck:add-arrow/name-dup/pxpy
would be disabled. When syncheck:add-arrow/name-dup/pxpy/renamable
is not in the interface, syncheck:add-arrow/name-dup/pxpy/renamable
would simply be unused.
For (1), since currently there's no restriction, it seems to me that to make it backward compatible, it should be an opt-out mechanism. That is, all local connections would make renamable?
#t
by default, but a syntax property inhibit-rename?
setting to #t
of identifiers in either disappeared-binding
or disappeared-use
would make renamable?
#f
.
And we probably do need some tests (this time I'm just not missing them am I?).
Yes, I will add tests.
@rfindler: To prevent the PR from becoming massive, should I make a change to only include the uncontroversial part of the this PR (the first issue in the top post), and separate the rest (the second issue in the top post) as a separate PR?
I'm not sure exactly what you have in mind with the split but I do agree with the general principle that getting uncontroversial improvements in their own PRs and merging them is Very Good.
Well, I just want to make it easy for you to review.
Do you have any comment about my above plan of adding syncheck:add-arrow/name-dup/pxpy/renamable
?
OK, I removed the "compare the characters in the original program" from the PR and added tests. All tests passed, so it's ready for a review (and merge). I will submit a separate, draft PR that implements syncheck:add-arrow/name-dup/pxpy/renamable
soon.
Thanks!
Renaming in DrRacket is currently broken in two ways.
Consider the program:
lang racket
(require racket/list)
Right clicking
require
will offer users to rename theracket
identifier which doesn't make much sense. Users right clickrequire
because they want to rename that particular identifier, not others.To continue from the above example, renaming
racket
toracket/base
will cause all identifiers imported fromracket
to be renamed toracket/base
. That is, it would result in:lang racket/base
(require/base racket/list)
This bug will become even more annoying after racket/racket#3391 is merged, since renaming any defined identifier will cause
all-defined-out
to be renamed as well.This PR fixes both issues. That is, renaming at a position will pick an identifier from that position,
and renaming an identifier will only cause identifiers that are textually equivalent to that identifier to be renamed.