Skip to content
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

Add support for chained gets, sets, and methods #69

Merged
merged 5 commits into from
Sep 5, 2019
Merged

Conversation

jackbsteinberg
Copy link
Owner

Resolves #29

Copy link
Collaborator

@domenic domenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good but I'd like to get that particular tricky case to be a bit more self-documenting.

Is there no need to do this same kind of recursive application for the other mods? For example what about new Document(new String('foo')) or something like that?

@@ -48,7 +48,8 @@ function isDataPropertyAccess(node) {
*/
function isGlobalPropertyAccess(node) {
return nodeTypes.isPropertyAccessExpression(node) &&
!nodeTypes.isCallExpression(node.getParent()) &&
!(nodeTypes.isCallExpression(node.getParent()) &&
node.getParent().getExpression() === node) &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to express what this condition is asking? e.g.

const ___something___ = nodeTYpes.isCallExpression(node.getParent()) && node.getParent().getExpression === node;

and then just use !___something__? Where __something__ is a semantic name indicating what actually you're testing for...

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was considering documenting via comments but this seems like a good way to do it, I'll change to this

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to a separate var with a explanatory comment

@jackbsteinberg
Copy link
Owner Author

We only need the recursive application for methods and gets/sets, since, as of a few PRs ago, constructors don't rewrite. It's also unnecessary for the remove console mod as that only rewrites to undefined or deletes itself.

@jackbsteinberg jackbsteinberg merged commit 0c34261 into master Sep 5, 2019
@jackbsteinberg jackbsteinberg deleted the nesting branch September 5, 2019 19:43
@fergald fergald mentioned this pull request Sep 9, 2019
@fergald
Copy link
Collaborator

fergald commented Sep 9, 2019

We only need the recursive application for methods and gets/sets, since, as of a few PRs ago, constructors don't rewrite. It's also unnecessary for the remove console mod as that only rewrites to undefined or deletes itself.

I still haven't figured out how this change works. If recursion only happens within a module, how does

document.body.querySelector('class');

get rewritten correctly, that seems like we have to recurse into 2 modules.

Maybe I don't understand how the tree traversal works at all.

@jackbsteinberg
Copy link
Owner Author

I did some digging and that particular example works, but there is still an issue.

document.body.querySelector('class');

This would first have the replaceMethods mod run, which would transform it into:

Reflect_apply(HTMLElement_querySelector, document.body, ['class']

After the replaceMethods mod recursed and found no more methods to replace, it would have the replaceGetsSets mod run, which would replace document.body giving this:

Reflect_apply(HTMLElement_querySelector, Reflect_apply(Document_body_get, document), ['class']);

After this replaceGetsSets would recurse, replacing document and leaving us with the final result of:

Reflect_apply(HTMLElement_querySelector, Reflect_apply(Document_body_get, Window_document_get()), ['class']);

@jackbsteinberg
Copy link
Owner Author

This example works, but only because of the order of the accesses, with method coming before gets/sets. If, for example, we had something closer to:

const otherDiff = document.querySelector('body').textContent;

Then the textContent portion of the statement would not be rewritten, leaving:

Reflect_apply(Document_querySelector, Window_document_get(), ['body']).textContent;

This is an issue, and will likely require rethinking the strategy of only recursing with the current method.

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.

Nested accessors and methods
3 participants