-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rule:
comprehension-term-assignment
(#1098)
Flag redundant assignment of simple values that could be used directly as the comprehension term (or key/value). Fixes #1073 Signed-off-by: Anders Eknert <[email protected]>
- Loading branch information
1 parent
6f9b32f
commit b567b5d
Showing
15 changed files
with
500 additions
and
123 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 86 additions & 0 deletions
86
bundle/regal/rules/style/comprehension-term-assignment/comprehension_term_assignment.rego
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# METADATA | ||
# description: Assignment can be moved to comprehension term | ||
package regal.rules.style["comprehension-term-assignment"] | ||
|
||
import rego.v1 | ||
|
||
import data.regal.ast | ||
import data.regal.result | ||
import data.regal.util | ||
|
||
# METADATA | ||
# description: | | ||
# find comprehensions where assignment in the body may be replaced by | ||
# using the value in the comprehension term (or key/value) directly | ||
# scope: document | ||
|
||
# METADATA | ||
# description: find in set and array comprehensions | ||
report contains violation if { | ||
comp := ast.found.comprehensions[_][_].value | ||
|
||
# a single expression can't be moved to term position | ||
count(comp.body) > 1 | ||
|
||
# limit to simple vars, not term vars in nested | ||
# composite structures, function calls or whatever | ||
comp.term.type == "var" | ||
|
||
some expr in comp.body | ||
|
||
[lhs, rhs] := ast.assignment_terms(expr) | ||
|
||
lhs.type == comp.term.type | ||
lhs.value == comp.term.value | ||
|
||
# using any of these at the term position may be OK when the value | ||
# is simple, like [{"first_name": name.first} | some name in names] | ||
# but almost certainly hard to understand when more complex composite values | ||
# or call chains are involved.. | ||
# trying to determine "complexity" is... hard / undesirable | ||
# so let's just allow these assignnments and focus on what we do know | ||
rhs.type in {"var", "ref"} | ||
not _dynamic_ref(rhs) | ||
|
||
violation := result.fail(rego.metadata.chain(), result.ranged_location_from_text(expr)) | ||
} | ||
|
||
# METADATA | ||
# description: find in object comprehensions (both keys and values) | ||
report contains violation if { | ||
comp := ast.found.comprehensions[_][_].value | ||
|
||
# a single expression can't be moved to term position | ||
count(comp.body) > 1 | ||
|
||
# only true for object comprehension | ||
comp.key | ||
|
||
some expr in comp.body | ||
|
||
[lhs, rhs] := ast.assignment_terms(expr) | ||
|
||
some kind in ["key", "value"] | ||
|
||
lhs.type == comp[kind].type | ||
lhs.value == comp[kind].value | ||
|
||
rhs.type in {"var", "ref"} | ||
not _dynamic_ref(rhs) | ||
|
||
violation := result.fail(rego.metadata.chain(), result.ranged_location_from_text(expr)) | ||
} | ||
|
||
_dynamic_ref(value) if { | ||
value.type == "ref" | ||
|
||
_call_or_non_static(value) | ||
} | ||
|
||
_call_or_non_static(ref) if ref.value[0].type == "call" | ||
|
||
_call_or_non_static(ref) if not _static_ref(ref) | ||
|
||
_static_ref(ref) if every part in util.rest(ref.value) { | ||
part.type == "string" | ||
} |
Oops, something went wrong.