-
Notifications
You must be signed in to change notification settings - Fork 419
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
Create CondFinalCondition readability check #935
Conversation
@@ -0,0 +1,78 @@ | |||
defmodule Credo.Check.Readability.CondCatchallTrue do |
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.
Open to suggestions on what to name this check. I had a hard time picking a name and I'm not sure this name is best.
defp catchall_other_than_true?({:->, _meta, [[{:{}, _meta2, _values}], _args]}), do: true | ||
# Atom literal catch-all clause | ||
defp catchall_other_than_true?({:->, _meta, [[name], _args]}) when is_atom(name), do: true | ||
defp catchall_other_than_true?(_), do: false |
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.
Returns true of the clause condition is a catchall that isn't the literal value true
.
Great 👍 Since the Elixir website & documentation call this the "final condition", we should name this Also, I do think the |
PR updated! |
@rrrene this is ready for review again! |
@rrrene any chance you can take a look at this PR again? |
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.
Apologies, I'm having the first cold in 2.5 years and am no longer used to that *%&/!.
Did you use a formatter on the code?
defp catchall_other_than_value?({:->, _meta, [[{:{}, _meta2, _values}], _args]}, _value), do: true | ||
# Atom literal catch-all clause | ||
defp catchall_other_than_value?({:->, _meta, [[name], _args]}, _value) when is_atom(name), do: true | ||
defp catchall_other_than_value?(_clause, _value), do: false |
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.
If the clauses "above" this one are "catch alls" for all cases, what are examples where we need this clause?
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.
This is for a non catch-all clause. A contrived example:
cond do
n > 5 ->
"greater than 5"
n >= 0 ->
"positive"
n < 0 ->
"negative"
end
The last clause is not a catchall and is not composed of a single literal. I will add a comment for this final clause. Let me know if you think I should rename this function.
{ast, issues} | ||
end | ||
|
||
defp catchall_other_than_value?({:->, _meta, [[value], _args]}, value), do: false |
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.
Please rename this function to something that gives a hint at what it does.
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.
PR updated. Let me know if the new name is acceptable.
|
||
defp catchall_other_than_value?({:->, _meta, [[value], _args]}, value), do: false | ||
# Integer literal catch-all clause | ||
defp catchall_other_than_value?({:->, _meta, ['{', _args]}, _value), do: true |
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.
Why does this always return true
, no matter what I specified in the config?
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.
This function returns false when the value
variable bound by the match of the first argument ({:->, _meta, [[value], _args]}
) matches the second argument value
. The second argument passed to this function is value specified in the config.
if conditions | ||
|> List.last() | ||
|> catchall_other_than_value?(final_condition_value) do | ||
{ast, issues ++ [issue_for(issue_meta, meta[:line], :cond)]} |
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.
Why is the trigger
for the issue always "cond"? The trigger is the word in the code that "triggers" the issue and that should be the "wrong" final condition, e.g. using :else
when using true
is expected.
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.
PR updated. The trigger is now the literal catchall value, or in the case of maps, tuples, and integers, the atom :map
, :tuple
or :integer
. Let me know if this is acceptable.
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.
As I mentioned before
The trigger is the word in the code that "triggers" the issue
which means the actual string that should get squiggly lines in your editor.
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.
I'm sorry about that. I don't know how to do that but I'll see if I can figure it out. Are there any other checks that I could refer to that do this?
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.
PR updated. I have added assertions to the tests for this check to verify that the clause expression that triggers issue is what is set for the issue's trigger
parameter.
Sorry to hear you have been sick. Thanks for the review and thank you for all your work on credo! I forgot to run the formatter when I opened the PR. I ran it and pushed the reformatted code. Everything is ready to review again. |
I have updated the PR again based on your reply to one of my comments about the issue trigger value. The trigger is now set to the string of code that triggered the issue. The PR is ready to review again. |
Any chance this can get merged soon? |
This is good in principle, but it does not work if I modify your tests to something that might very well happen in real life (a dangling space somewhere):
|
@rrrene I copied what was done in the existing checks. I used Can you provide a suggestion on how to improve this? Happy to change things but not sure how. |
@rrrene, I'd like to get this merged, can you show me how to address this in credo? I'm not sure I can get the cond clause with whitespace in credo.
Thanks! |
Re-opening this PR as I closed it in error. @rrrene happy to make any changes to get this merged! |
@rrrene you've merged several of my checks but not this one. If you can provide any info as to why this hasn't been accepted yet I will be happy to make any necessary changes (or close it permanently if that is needed). |
Hi, sorry for being a slow responder. This check won't get merged as long as it assumes that people write code the same way that I do not have an "obvious" solution for your specific problem here (a.k.a. I'm not trolling you). |
I am closing this for age/inactivity. If you find a way to make the final changes, please feel free to re-open this issue at your discretion. |
Hi @rrrene , sorry for the late reply here.
Are you referring to this line? https://github.com/rrrene/credo/pull/935/files#diff-cbac4e2c2b102d2eba670658d03634fb4b21022007e98f39f5b7bccd674e52daR57 The Is there a reason this is problematic? I understand the code may not be formatted exactly as the user typed it in, but I'm not sure this will be a big problem as we do output the line number as well, so the user should be able to locate the problem without issue. Remember, this AST in this case is only ever going to be a catchall clause literal value. So for example, |
This PR adds a check named
Credo.Check.Readability.CondCatchallTrue
that checks forcond
s that end in a catchall clause that use a literal value other thantrue
. I created this check to catch violations of the rule about catchallcond
clauses specified in the Christopher Adam's style guide (https://github.com/christopheradams/elixir_style_guide#true-as-last-condition). See the tests for examples.Context: