forked from AnwarMohamed/metasploit-framework
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add initial layout cops for the module super hash
- Loading branch information
1 parent
513338c
commit bfd284b
Showing
8 changed files
with
690 additions
and
23 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
module RuboCop | ||
module Cop | ||
module Layout | ||
class ModuleDescriptionIndentation < Cop | ||
include Alignment | ||
|
||
MSG = "Module descriptions should be properly aligned to the 'Description' key, and within %q{ ... }" | ||
|
||
def_node_matcher :find_update_info_node, <<~PATTERN | ||
(def :initialize _args (begin (super $(send nil? {:update_info :merge_info} (lvar :info) (hash ...))) ...)) | ||
PATTERN | ||
|
||
def_node_matcher :find_nested_update_info_node, <<~PATTERN | ||
(def :initialize _args (super $(send nil? {:update_info :merge_info} (lvar :info) (hash ...)) ...)) | ||
PATTERN | ||
|
||
def on_def(node) | ||
update_info_node = find_update_info_node(node) || find_nested_update_info_node(node) | ||
return if update_info_node.nil? | ||
|
||
hash = update_info_node.arguments.find { |argument| hash_arg?(argument) } | ||
hash.each_pair do |key, value| | ||
if key.value == "Description" | ||
if requires_correction?(key, value) | ||
add_offense(value, location: :end) | ||
end | ||
end | ||
end | ||
end | ||
|
||
def autocorrect(description_value) | ||
lambda do |corrector| | ||
description_key = description_value.parent.key | ||
new_content = indent_description_value_correctly(description_key, description_value) | ||
|
||
corrector.replace(description_value.source_range, new_content) | ||
end | ||
end | ||
|
||
private | ||
|
||
def requires_correction?(description_key, description_value) | ||
return false if description_value.single_line? | ||
|
||
current_content = description_value.source | ||
expected_content = indent_description_value_correctly(description_key, description_value) | ||
expected_content != current_content | ||
end | ||
|
||
def indent_description_value_correctly(description_key, description_value) | ||
content_whitespace = indentation(description_key) | ||
final_line_whitespace = offset(description_key) | ||
|
||
description_content = description_value.source.lines[1...-1] | ||
indented_description = description_content.map do |line| | ||
cleaned_content = line.strip | ||
if cleaned_content.empty? | ||
"\n" | ||
else | ||
"#{content_whitespace}#{cleaned_content}\n" | ||
end | ||
end.join | ||
|
||
new_literal = "%q{\n" | ||
new_literal <<= indented_description | ||
new_literal <<= final_line_whitespace | ||
new_literal <<= '}' | ||
|
||
new_literal | ||
end | ||
|
||
def hash_arg?(node) | ||
node.type == :hash | ||
end | ||
end | ||
end | ||
end | ||
end |
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,87 @@ | ||
module RuboCop | ||
module Cop | ||
module Layout | ||
class ModuleHashOnNewLine < Cop | ||
include Alignment | ||
|
||
MSG = "%<name>s should start on its own line" | ||
MISSING_NEW_LINE_MSG = "A new line is missing" | ||
|
||
def_node_matcher :find_update_info_node, <<~PATTERN | ||
(def :initialize _args (begin (super $(send nil? {:update_info :merge_info} (lvar :info) (hash ...))) ...)) | ||
PATTERN | ||
|
||
def_node_matcher :find_nested_update_info_node, <<~PATTERN | ||
(def :initialize _args (super $(send nil? {:update_info :merge_info} (lvar :info) (hash ...)) ...)) | ||
PATTERN | ||
|
||
def on_def(node) | ||
update_info_node = find_update_info_node(node) || find_nested_update_info_node(node) | ||
return if update_info_node.nil? | ||
|
||
unless begins_its_line?(update_info_node.source_range) | ||
add_offense(update_info_node, location: :begin) | ||
end | ||
|
||
# Ensure every argument to update_info is on its own line, i.e. info and the hash arguments | ||
update_info_node.arguments.each do |argument| | ||
unless begins_its_line?(argument.source_range) | ||
add_offense(argument) | ||
end | ||
end | ||
|
||
if missing_new_line_after_parenthesis?(update_info_node) | ||
add_offense(update_info_node, location: :end, message: MISSING_NEW_LINE_MSG) | ||
end | ||
end | ||
|
||
def autocorrect(node) | ||
lambda do |corrector| | ||
if merge_function?(node) && missing_new_line_after_parenthesis?(node) | ||
# Ensure there's always a new line after `update_info(...)` to avoid `))` at the end of the `super(update_info` call | ||
corrector.replace(node.source_range.end, "\n#{offset(node.parent)}") | ||
else | ||
# Force a new line, and indent to the parent node. Other Layout rules will correct the positioning. | ||
corrector.replace(node.source_range, "\n#{indentation(node.parent)}#{node.source}") | ||
end | ||
end | ||
end | ||
|
||
private | ||
|
||
def message(node) | ||
if update_info?(node) | ||
format(MSG, name: :update_info) | ||
elsif merge_info?(node) | ||
format(MSG, name: :merge_info) | ||
elsif info_arg?(node) | ||
format(MSG, name: :info) | ||
else | ||
format(MSG, name: :argument) | ||
end | ||
end | ||
|
||
def merge_function?(node) | ||
update_info?(node) || merge_info?(node) | ||
end | ||
|
||
def update_info?(node) | ||
node.type == :send && node.method_name == :update_info | ||
end | ||
|
||
def merge_info?(node) | ||
node.type == :send && node.method_name == :merge_info | ||
end | ||
|
||
def info_arg?(node) | ||
node.type == :lvar && node.children[0] == :info | ||
end | ||
|
||
def missing_new_line_after_parenthesis?(update_info_node) | ||
super_call = update_info_node.parent | ||
super_call.source.end_with? '))' | ||
end | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.