2018-01-29 22:25:36 +00:00
|
|
|
module Ameba
|
|
|
|
# A module that represents inline comments parsing and processing logic.
|
|
|
|
module InlineComments
|
|
|
|
COMMENT_DIRECTIVE_REGEX = Regex.new "# ameba : (\\w+) ([\\w, ]+)".gsub(" ", "\\s*")
|
|
|
|
|
|
|
|
# Returns true if current location is disabled for a particular rule,
|
|
|
|
# false otherwise.
|
|
|
|
#
|
|
|
|
# Location is disabled in two cases:
|
|
|
|
# 1. The line of the location ends with a comment directive.
|
|
|
|
# 2. The line above the location is a comment directive.
|
|
|
|
#
|
2018-01-30 13:46:11 +00:00
|
|
|
# For example, here are two examples of disabled location:
|
2018-01-29 22:25:36 +00:00
|
|
|
#
|
|
|
|
# ```
|
|
|
|
# # ameba:disable LargeNumbers
|
|
|
|
# Time.epoch(1483859302)
|
|
|
|
#
|
|
|
|
# Time.epoch(1483859302) # ameba:disable LargeNumbers
|
|
|
|
# ```
|
|
|
|
#
|
|
|
|
# But here are examples which are not considered as disabled location:
|
|
|
|
#
|
|
|
|
# ```
|
|
|
|
# # ameba:disable LargeNumbers
|
|
|
|
# #
|
|
|
|
# Time.epoch(1483859302)
|
|
|
|
#
|
|
|
|
# if use_epoch? # ameba:disable LargeNumbers
|
|
|
|
# Time.epoch(1483859302)
|
|
|
|
# end
|
|
|
|
# ```
|
|
|
|
#
|
|
|
|
def location_disabled?(location, rule)
|
|
|
|
return false unless line_number = location.try &.line_number.try &.- 1
|
|
|
|
return false unless line = lines[line_number]?
|
|
|
|
|
|
|
|
line_disabled?(line, rule) ||
|
|
|
|
(line_number > 0 &&
|
|
|
|
(prev_line = lines[line_number - 1]) &&
|
|
|
|
comment?(prev_line) &&
|
|
|
|
line_disabled?(prev_line, rule))
|
|
|
|
end
|
|
|
|
|
|
|
|
private def comment?(line)
|
|
|
|
line.lstrip.starts_with? '#'
|
|
|
|
end
|
|
|
|
|
|
|
|
private def line_disabled?(line, rule)
|
|
|
|
return false unless inline_comment = parse_inline_comment(line)
|
|
|
|
inline_comment[:action] == "disable" && inline_comment[:rules].includes?(rule)
|
|
|
|
end
|
|
|
|
|
|
|
|
private def parse_inline_comment(line)
|
|
|
|
if comment = COMMENT_DIRECTIVE_REGEX.match(line)
|
|
|
|
{
|
|
|
|
action: comment[1],
|
|
|
|
rules: comment[2].split(/[\s,]/, remove_empty: true),
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|