Skip to content

Fix renaming in DrRacket #415

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 8, 2020
Merged

Fix renaming in DrRacket #415

merged 3 commits into from
Sep 8, 2020

Conversation

sorawee
Copy link
Contributor

@sorawee sorawee commented Sep 6, 2020

Renaming in DrRacket is currently broken in two ways.

  1. Consider the program:

    #lang racket
    (require racket/list)
    

    Right clicking require will offer users to rename the racket
    identifier which doesn't make much sense. Users right click require
    because they want to rename that particular identifier, not others.

2. To continue from the above example, renaming `racket` to `racket/base` will cause all identifiers imported from `racket` to be renamed to `racket/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.

sorawee added a commit to sorawee/racket-mode that referenced this pull request Sep 6, 2020
It is possible to have an arrow between two identifiers that are not
textually equivalent (definitely possible in DrRacket, and theoretically
possible in Racket Mode).

In the above event, renaming one identifier should not change the other.

See also racket/drracket#415 for a similar fix in DrRacket, and
racket/racket#3391 which would start to make Racket Mode behave
incorrectly. In particular, with the above PR, renaming
the identifier `a` in the following program should not rename
`all-defined-out` as well.

    #lang racket
    (provide (all-defined-out))
    (define a 1)
@rfindler
Copy link
Member

rfindler commented Sep 7, 2020

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?).

@sorawee
Copy link
Contributor Author

sorawee commented Sep 7, 2020

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.

@sorawee
Copy link
Contributor Author

sorawee commented Sep 7, 2020

@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?

@rfindler
Copy link
Member

rfindler commented Sep 7, 2020

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.

@sorawee
Copy link
Contributor Author

sorawee commented Sep 7, 2020

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?

Consider the program:

       #lang racket
       (require racket/list)

Right clicking `require` will offer users to rename the `racket`
identifier which doesn't make much sense. Users right click `require`
because they want to rename that particular identifier, not others.

This PR fixes the issues.
@sorawee
Copy link
Contributor Author

sorawee commented Sep 7, 2020

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!

@rfindler rfindler merged commit 583be06 into racket:master Sep 8, 2020
@sorawee sorawee deleted the fix-renaming branch September 8, 2020 00:11
sorawee referenced this pull request Feb 6, 2023
check that the symbolic name of a binder and its reference are the
same

Also, it appears that something changed along the way such that we no
longer need the special case that solved issue #110 anymore
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants