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

Style/AndOr gets confused about autocorrect #1255

Closed
vrthra opened this issue Aug 7, 2014 · 6 comments
Closed

Style/AndOr gets confused about autocorrect #1255

vrthra opened this issue Aug 7, 2014 · 6 comments
Assignees
Labels

Comments

@vrthra
Copy link
Contributor

vrthra commented Aug 7, 2014

Style/AndOr gets confused when presented with a fragment such as

def z(a,b)
  return true unless a or b
end

And refuses to autocorrect, while happly autocorrects if we pass in

return true unless a or b

It appears that the parser parses a || b as

(or
  (lvar :a)
  (lvar :b))

while it parses the a or b in the above expression as

(or
  (send nil :a)
  (send nil :b))

On the other hand, if I change the definition to def z, the parsed expressions are for a or b

(or
  (send nil :a)
  (send nil :b))

and a || b

(or
  (send nil :a)
  (send nil :b))

However, I don't see why having a def of the variables should result in a different result.

@vrthra
Copy link
Contributor Author

vrthra commented Aug 7, 2014

I think perhaps the autocorrect should look at both possibilities before deciding to fail

@jonas054 jonas054 added the bug label Aug 8, 2014
@jonas054
Copy link
Collaborator

jonas054 commented Aug 8, 2014

I agree. There's something not quite right here. I think the problem is that AutocorrectUnlessChangingAST#autocorrect compares the rewritten a || b, parsed individually, to the a or b that was parsed in the context of the def z(a, b). That's why the AST is different. Maybe that's what you said @vrthra, but I'm restating it for my own understanding.

Anyway it seems that a bit of context is needed when parsing a || b.

@vrthra
Copy link
Contributor Author

vrthra commented Aug 8, 2014

@jonas054 Yes, it seems that the parser interprets the a and b as variables when it is under def z(a,b) and as method calls otherwise. Is there a way we can get the parent nodes of an expression? If not, one option could be to replace all the (lvar _) to (send nil _) and then compare? Because the results of replacement are not dependent on whether the tokens represent variables or not.

@jonas054
Copy link
Collaborator

jonas054 commented Aug 8, 2014

The code that evaluates whether the AST has changed is in AutocorrectUnlessChangingAST and should be generic and usable for any cop that wants this feature. I don't feel comfortable fiddling with the AST there before the comparison. Who knows what bugs that could introduce in the future?

No, it's better to compare a larger scope, as you also suggest. I think we can find a way to do that, even though there is no direct reference to the parent node in each node.

@bbatsov
Copy link
Collaborator

bbatsov commented Aug 8, 2014

I think we can find a way to do that, even though there is no direct reference to the parent node in each node.

Here you go, sir - whitequark/parser#111.

@jonas054 jonas054 self-assigned this Aug 11, 2014
@jonas054
Copy link
Collaborator

@bbatsov Thanks! I still had problems crafting an acceptable solution, even with that bit of help. Luckily I came up with a quite simple fix that we can use instead. Today, we're creating the new source code, build the AST and compare it against the existing node. This doesn't always work, as @vrthra noticed, becuase the existing node is affected by its context. So instead of trying to replicate that context for the rewritten code, we remove it for the existing node. You'll see the details in an upcoming pull request.

bbatsov added a commit that referenced this issue Aug 11, 2014
[Fix #1255] Compare without context in AutocorrectUnlessChangingAST
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants