-
Notifications
You must be signed in to change notification settings - Fork 10
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
tidy-requires: module paths w/in require subforms should sort #432
Comments
I agree with this, and others have mentioned the possibility to me too. But I'd also like to keep Resyntax and |
This sounds good in principle. I'd need to reload my brain with details about |
So actually. Having finished my first coffee. I realized that (require a
b
c
(only-in a/extra x)) becomes (require a
(only-in a/extra x)
b
c) Was there maybe some other example where it does not? Maybe I have a bug in some cases. If so, I'll fix. But the intent is definitely to sort by module (within each meta level). TL;DR: I think you could go ahead and change resyntax to sort that way, and if some bug turns up, then it's on me to fix that. |
Ah, I was going off the description here rather than actually installing |
Review didn't support Bogdanp/racket-review@6ce349f#diff-dd9e24dda16c8ecc44babd298601cf79cbe4cd068711b7e6f8b8135691492e2a Running tidy requires on that same file results in: #lang racket/base
(require (prefix-in combined: (combine-in threading))
(combine-in)
racket/string
(prefix-in combined: (combine-in threading racket/base))) |
Although that's intended as user docs, not a full spec, it is ambiguous; I can improve that.
It's not even attempting to handle I started a branch last week to refactor some of this (very old) code of mine, looking at the Among other things, I did add My instinct is to prune empty In any case it begs the question, if we're sorting by module, but EDIT: I saw the empty Generally: It looks like I should re-read the grammar carefully, looking for any more edge cases or bad assumptions. |
Perhaps the three of us ought to standardize on a shared implementation? A minimal-dependency package that we all reuse would get rid of any inconsistency problems. |
IMO, pruning empty
That's what review does, and it expects any nested specs to be sorted by the same rules.
I'm not against this, but my package only lints and doesn't propose changes, so something like this might end up complicating it. The rules themselves are straightforward IMO:
Here's an example of a well-sorted (require (for-syntax racket/base
syntax/parse/pre)
deta
(prefix-in http: net/http-easy)
racket/contract/base
(except-in racket/list group-by)
racket/string
threading
web-server/http
"../a.rkt"
"b.rkt") Running (require (for-syntax racket/base
syntax/parse/pre)
deta
(prefix-in http: net/http-easy)
racket/contract/base
(except-in racket/list
group-by)
racket/string
threading
web-server/http
"../a.rkt"
"b.rkt") The only change is the indentation of |
I'm also not opposed to code sharing. But ATM I'm rewriting some of the old code. So that it still passes the old tests. But also handles some holes like When the dust settles, I can touch base re sharing. Few quick points about that, meanwhile:
|
IMHO what It's probably more important for Also to be clear, I don't even know how many Racket Mode users actively use |
Motivated by jackfirth/resyntax#432, as well as inspired by racket-review's used of syntax classes. Define syntax classes closely following the require grammar. Use them to drive the matching and simplification, producing attribute values that are `sortable` structs, from which we reconstruct the syntax. Because the macro-debugger-lib drop analysis works in terms of <module phase> tuples, the root-module-path syntax class is the locus -- it may produce #f instead of a `sortable` to indicate elision. This can percolate up through other specs, since they all build directly or transitively on root-module-path. Simplify gratuitous specs either reducing to the simpler equivalent spec or eliding entirely. e.g. (only-in m) => m or (combine-in) => #f. No longer "explode" multi-in forms when de-normalizing and attempt to recover them when normalizing. Instead: Preserve multi-in forms, modifying only for drops. In simple cases like (multi-in a b (c d)), we can modify the multi-in form itself. In the general case -- any Cartesian product -- we must wrap in a subtract-in spec. Improve some doc strings in substance, and prefer active to passive voice.
Motivated by jackfirth/resyntax#432, as well as inspired by racket-review's used of syntax classes. Define syntax classes closely following the require grammar. Use them to drive the matching and simplification, producing attribute values that are `sortable` structs, from which we reconstruct the syntax. Because the macro-debugger-lib drop analysis works in terms of <module phase> tuples, the root-module-path syntax class is the locus -- it may produce #f instead of a `sortable` to indicate elision. This can percolate up through other specs, since they all build directly or transitively on root-module-path. Simplify gratuitous specs either reducing to the simpler equivalent spec or eliding entirely. e.g. (only-in m) => m or (combine-in) => #f. No longer "explode" multi-in forms when de-normalizing and attempt to recover them when normalizing. Instead: Preserve multi-in forms, modifying only for drops. In simple cases like (multi-in a b (c d)), we can modify the multi-in form itself. In the general case -- any Cartesian product -- we must wrap in a subtract-in spec. Improve some doc strings in substance, and prefer active to passive voice.
I took a fresh look at the old "tidying" code and came up with this, squashed commit: greghendershott/racket-mode@ecde6e8 It tries to be more principled about following the require spec grammar. It also tries to reduce or elide useless forms -- even just as part of just basic tidying. (This is independent of the "stronger" business of using IIUC the sorting shouldn't contradict what you're doing @Bogdanp in racket-review. @jackfirth I'm not sure if this is something that you would like to reuse? If so, I could look at making this available as a package (although I might "vendor" that same source directly into the repo for Racket Mode... I would need to think about the pros and cons). |
@greghendershott For Resyntax to reuse it, it would have to use syntax objects instead of plain datums. Resyntax relies on syntax properties and source locations in the inputs and outputs of refactoring rules to figure various things out. So whatever tidying system Resyntax uses has to accept and return a |
Currently I convert to datums because the result of my internal For some alternative API (e.g. for you), I could trivially avoid conversion back to datums. Probably a bit more work to ensure that I'm manipulating syntax objects without losing srcloc and props, everywhere. But probably straightforward. Two questions:
I guess with both questions, my meta-question is, "What's your ideal API?" Using syntax objects, OK, but other details like this? |
I think part of the impedance mismatch is that It also "gathers" multiple So if some file has
it will produce
Also, the So it is pretty basic to the API that the result is some sort of "change list" -- a list of inserts and deletes. The special case of a delete+insert at the same position, can be presented instead as a replace (which can help the client handle surrounding whitespace more nicely). So the change list consists of "delete", "insert", and "replace". I think what this means is that resyntax, status quo, isn't attempting to do "as much" as I think this also means is that any shared library would need to offer an API that allows access to the "sorting" aspect -- but not "gathering"/consolidating. (And of course, you'd want that to work as syntax => syntax. But that alone isn't the biggest deal.) |
Motivated by jackfirth/resyntax#432, as well as inspired by racket-review's use of syntax classes. Define syntax classes closely following the require grammar. Use them to drive the matching and simplification, producing attribute values that are `sortable` structs, from which we reconstruct the syntax. Because the macro-debugger-lib drop analysis works in terms of <module phase> tuples, the root-module-path syntax class is the locus -- it may produce #f instead of a `sortable` to indicate elision. This can percolate up through other specs, since they all build directly or transitively on root-module-path. Simplify gratuitous specs either reducing to the simpler equivalent spec or eliding entirely. e.g. (only-in m) => m or (combine-in) => #f. No longer "explode" multi-in forms when denormalizing and attempt to recover them when normalizing. Instead: Preserve multi-in forms, modifying only for drops. In simple cases like (multi-in a b (c d)), we can modify the multi-in form itself. In the general case -- any Cartesian product -- we must wrap in a subtract-in spec. Change require tidying to work on full file syntax; requires are tidied in all modules. The racket-{trim base}-requires add/drop required modules only in the file's root module, because the macro-debugger lib's analysis only works for that module. As a result of this change, the front end no longer needs to gather and supply a list of require forms. Instead it always just supplies a file path. The back end commands return a list of textual changes -- inserts, deletes, and replaces -- for the front end to make to the buffer. This seems like a cleaner and more appropriate division of labor. Improve some doc strings in substance, and prefer active to passive voice.
This suggestion conflicts with this racket-review rule which ensures that uses of require subforms sort according to their module path. Another example can be found here.
The text was updated successfully, but these errors were encountered: