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
feat: mathtransform with jscodeshift #389
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The transformer looks good to me. I mainly want to know more about how the comment marker works and discuss a bit more about integration with the main system.
On the latter, one thought is to use ttsc
(typescript compiler wrapper that allows plugins), or wait until tsc
supports plugins and custom transforms. I also found an article about integrating custom transforms, which uses ttsc
.
I still don't fully understand how typescript's built-in transforms are supported and if jscodeshift
can work with ttsc
. Let me know if you experimented with any of the above.
Anyway, really cool work ❤️ !
@@ -0,0 +1,107 @@ | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much of this module remains untyped. There seems to be @types/jscodeshift on npm. Do you think it'll help with readability/error prevention?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a great idea, I definitely think it will.
return transformData ? transformData[1](transformData[0], node) : node; | ||
}) | ||
}; | ||
const MARKTAG = "mathtrans"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be great to clarify the usage of this marker. Looks like it will transform any functions following this marker? Can you transform only some lines in a function then?
I wonder if decorators can be a viable alternative, but they are probably not expressive enough for meta tasks like this.
Finally, something like differentiable
or autodiff
would be more meaningful markers here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will actually transform the nearest AST node below the marker. If that's a function, or a statement, or something else. It checks the LeadingComments node that the parser attaches to another AST node, which I believe is whatever the main type of a line is (method call, function, variable declaration, etc.).
Sample Input:
export const objDict = {
above: (x: number[]): number => {
//autodiff
x = t2 - z * 34 + (2 / 4)
y = a + bigint
}
}
Sample Output:
export const objDict = {
above: (x: number[]): number => {
//autodiff
x = add(sub(t2, mul(z, 34)), div(2, 4))
y = a + bigint
}
}
Renamed in 635db53
}; | ||
|
||
const root = j(fileInfo.source); | ||
const tNodes = root.find(j.Node).filter((nodePath: any) => needsTransform(nodePath)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe link to an API reference for future use. Seems like jscodeshift is using Mozilla's parser API?
|
||
// the below line is theoretically bad practice per https://stackoverflow.com/questions/1098040/checking-if-a-key-exists-in-a-javascript-object | ||
// however, given that our opmaps are manually generated it is low-risk. | ||
return transformData ? transformData[1](transformData[0], node) : node; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe not a ton better: at least make sure getTransformData
returns Node | undefined
, which will let the type checker do some checking. Also can you destructure transformData
to give the outputs meaningful names, e.g. const [operator, transformer] = getTransformData(node)
?
Thanks for doing this Stella! Super exciting work and it will be really helpful for our users; I definitely want to integrate it into our system as soon as we can 🙂 I was able to repro the example too. Some fixes that would make life easier for us:
Maybe @wodeni can comment on how this might be done?
Sample input:
Sample output:
If wrapping things in On documentation:
For us (@wodeni @maxkrieger and I)
|
Thanks for the sample input and output, btw, those were super helpful!
This can totally be done. I'll start working on it. The transforms have to be written differently for each type of expression though, so any examples of any other types of expressions (beyond the method call type and ternary expression type you provided below) that you think should be translatable would be great. For one, I would think it's also useful to be able to rename a method, like
This could be trickier. I could set it up so it would work for that example and for a lot of situations that are similar. But JSCodeshift doesn't know about the inferred types of variables, only the actual (untyped) AST node of the variable itself, so if the "number" nodes look exactly like nodes of another type, it would transform the other undesirable node as well. For instance, Also is |
Awesome, thanks, this will be super useful! Nothing else comes to mind, except that the translation rules might need to apply with some specificity/precedence if more than one of them matches, e.g.
Both would match
Agreed.
Ok, I'm gonna backtrack on this one. On second thought, I would prefer What should change is the name of the function used; it will probably be something like So, in the end, it's just fine to convert something like BTW, I forgot to confirm: you are converting function type signatures too, right? So anything that has a
Let me know if anything is confusing, or when this is ready to re-review! |
@hypotext @wodeni This is ready for re-review! Sorry this took so long to get done. In order to implement those changes you requested, I had to do a fairly significant refactoring. But it should be much easier to adapt to your needs now. I also added to the README a section breaking down the code further. The current functionality is also listed in the README. It should be pretty easy to change it to what exactly you want (e.g. |
Thanks Stella, this looks very helpful! I did a quick check of the functionality--can you just make sure that the pattern replacement works on nested nodes? For example, replacing Input code: (I know the # args to
Output code:
Expected code:
I'd just ask that you test for this kind of case more thoroughly, for patterns nested in other patterns as well (e.g. a |
Btw, is there some way to turn off the auto-build for the test typescript files for this feature @wodeni? I tried to push my test cases but I get a bunch of build errors on files like |
There's If they are test cases, maybe it's better to include them in our test suite eventually btw. |
Thanks. @strout18 Can you try and add the tests and commit them? I tried various things (including decorating the files |
You can use the --no-verify flag in git iirc
… On Dec 9, 2020, at 22:14, Katherine Ye ***@***.***> wrote:
Thanks. @strout18 <https://github.com/strout18> Can you try and add the tests and commit them?
I tried various things (including decorating the files mathtransform/Constraints.ts, mathtransform/bugtest.ts, and mathtransform/mathtest.ts with // @ts-nocheck, as well as adding those files to an exclude list in both mathtransform/tsconfig.json and ROOT/tsconfig.json) without success; I'm not able to commit my changes.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#389 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAUJSGVEO2A6PL6UPD23U2DSUA4J5ANCNFSM4SS32ZKQ>.
|
@wodeni @hypotext This is ready for re-review. I added a bunch of tests in the |
Hey Stella, I had a look at this and it looks great! One final request: Can you rewrite your tests ( We've been adding tests for all the new parts of You can see an example test suite here: https://github.com/penrose/penrose/blob/style-compiler-port/penrose-web/src/compiler/Style.test.ts It should be pretty quick to port (@wodeni Does Stella need to do anything special on her branch to get tests working with |
We never ejected |
@hypotext @wodeni Okay, I set it up with Jest, so
|
Hey Stella, thanks for doing this! I was able to replicate it but had to run
@wodeni Can you weigh in on how Stella should integrate the dependencies? (After we get @wodeni's feedback it should be good to merge) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update @strout18! The test suite worked for me as well after I manually install jscodeshift
. See my comments for some lower-level questions. Hopefully after you address them, CI will pass again.
Re integration with the core: my understanding is one will need to run jscodeshift
as a part of our build step eventually. We are finishing up the port to TS on #419. It's ok to merge this as an independent package for now, and I'll integrate it into the new system after #446.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! @hypotext is there any comment from your end? I think it's good to merge.
Codecov Report
@@ Coverage Diff @@
## main #389 +/- ##
==========================================
+ Coverage 70.61% 71.06% +0.45%
==========================================
Files 31 32 +1
Lines 5373 5520 +147
Branches 1029 1052 +23
==========================================
+ Hits 3794 3923 +129
- Misses 1574 1592 +18
Partials 5 5
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, feel free to merge! (It looks like there are minor package.json
, yarn.lock
etc. conflicts with main
. Maybe @wodeni can weigh in on how to resolve those?)
db12a26
to
cd29ee4
Compare
Checking in on this -- could we get this PR merged before any more merge conflicts arise? Looks like it's just some package dependency files that have conflicts. Maybe we can resolve during today's "office" time? @wodeni @maxkrieger |
Turns out that the default export of |
Description
The code in this branch is meant to allow users to write constraints/objs in basic math, and translate them afterward to the specific optimization framework. See the README in
react-renderer/src/mathtransform
for more details.Ideally it would run each time a file is changed (or at least a file from a specific list of files we want to transform), so hot-reloading functionality. It’s currently built to run on the command line (sample line:
jscodeshift bugtest.ts -t toCustomAD.ts -p -d
) , but I think it could also be modified to use the API functions (more detail is here). Another thing to note (also mentioned in the README) is that jscodeshift modifies in place the file you call it on (unless you call a dry run). So if we wanted to keep an unmodified version of that file we would need to make a copy. The CLI for jscodeshift apparently does not support redirecting the output (though the API does) But the program doesn’t change much code, and which code it changes is well-defined and easily reversible so maybe storing the old version is not necessary.Sample Input/Output
Sample Input
Sample Output
Remaining issues
Dependencies
I’m not sure what to do with the new dependencies. I was just originally working on this project outside of the Penrose directory, so I had to download the jscodeshift package and make my own tsconfig file to get it to work. I assume it should be merged into the main dependency list and node_modules folder but I'm not sure how to do that.