Class: RuboCop::Cop::Cop

Inherits:
Object
  • Object
show all
Extended by:
AST::Sexp, NodePattern::Macros
Includes:
AST::Sexp, AutocorrectLogic, IgnoredNode, Util
Defined in:
lib/rubocop/cop/cop.rb,
lib/rubocop/rspec/cop_helper.rb

Overview

Monkey-patch Cop for tests to provide easy access to messages and highlights.

Direct Known Subclasses

Bundler::DuplicatedGem, Bundler::OrderedGems, InternalAffairs::NodeTypePredicate, InternalAffairs::UselessMessageAssertion, Layout::AccessModifierIndentation, Layout::AlignArray, Layout::AlignHash, Layout::AlignParameters, Layout::BlockEndNewline, Layout::CaseIndentation, Layout::ClosingParenthesisIndentation, Layout::CommentIndentation, Layout::DotPosition, Layout::ElseAlignment, Layout::EmptyLineAfterMagicComment, Layout::EmptyLineBetweenDefs, Layout::EmptyLines, Layout::EmptyLinesAroundAccessModifier, Layout::EmptyLinesAroundBeginBody, Layout::EmptyLinesAroundBlockBody, Layout::EmptyLinesAroundClassBody, Layout::EmptyLinesAroundExceptionHandlingKeywords, Layout::EmptyLinesAroundMethodBody, Layout::EmptyLinesAroundModuleBody, Layout::EndOfLine, Layout::ExtraSpacing, Layout::FirstArrayElementLineBreak, Layout::FirstHashElementLineBreak, Layout::FirstMethodArgumentLineBreak, Layout::FirstMethodParameterLineBreak, Layout::FirstParameterIndentation, Layout::IndentArray, Layout::IndentAssignment, Layout::IndentHash, Layout::IndentHeredoc, Layout::IndentationConsistency, Layout::IndentationWidth, Layout::InitialIndentation, Layout::LeadingCommentSpace, Layout::MultilineArrayBraceLayout, Layout::MultilineAssignmentLayout, Layout::MultilineBlockLayout, Layout::MultilineHashBraceLayout, Layout::MultilineMethodCallBraceLayout, Layout::MultilineMethodCallIndentation, Layout::MultilineMethodDefinitionBraceLayout, Layout::MultilineOperationIndentation, Layout::RescueEnsureAlignment, Layout::SpaceAfterColon, Layout::SpaceAfterComma, Layout::SpaceAfterMethodName, Layout::SpaceAfterNot, Layout::SpaceAfterSemicolon, Layout::SpaceAroundBlockParameters, Layout::SpaceAroundEqualsInParameterDefault, Layout::SpaceAroundKeyword, Layout::SpaceAroundOperators, Layout::SpaceBeforeBlockBraces, Layout::SpaceBeforeComma, Layout::SpaceBeforeComment, Layout::SpaceBeforeFirstArg, Layout::SpaceBeforeSemicolon, Layout::SpaceInLambdaLiteral, Layout::SpaceInsideArrayPercentLiteral, Layout::SpaceInsideBlockBraces, Layout::SpaceInsideBrackets, Layout::SpaceInsideHashLiteralBraces, Layout::SpaceInsideParens, Layout::SpaceInsidePercentLiteralDelimiters, Layout::SpaceInsideRangeLiteral, Layout::SpaceInsideStringInterpolation, Layout::Tab, Layout::TrailingBlankLines, Layout::TrailingWhitespace, Lint::AmbiguousBlockAssociation, Lint::AmbiguousOperator, Lint::AmbiguousRegexpLiteral, Lint::AssignmentInCondition, Lint::BlockAlignment, Lint::CircularArgumentReference, Lint::ConditionPosition, Lint::Debugger, Lint::DefEndAlignment, Lint::DeprecatedClassMethods, Lint::DuplicateCaseCondition, Lint::DuplicateMethods, Lint::DuplicatedKey, Lint::EachWithObjectArgument, Lint::ElseLayout, Lint::EmptyEnsure, Lint::EmptyExpression, Lint::EmptyInterpolation, Lint::EmptyWhen, Lint::EndAlignment, Lint::EndInMethod, Lint::EnsureReturn, Lint::FloatOutOfRange, Lint::FormatParameterMismatch, Lint::HandleExceptions, Lint::ImplicitStringConcatenation, Lint::IneffectiveAccessModifier, Lint::InheritException, Lint::InvalidCharacterLiteral, Lint::LiteralInCondition, Lint::LiteralInInterpolation, Lint::Loop, Lint::MultipleCompare, Lint::NestedMethodDefinition, Lint::NextWithoutAccumulator, Lint::NonLocalExitFromIterator, Lint::ParenthesesAsGroupedExpression, Lint::PercentStringArray, Lint::PercentSymbolArray, Lint::RandOne, Lint::RequireParentheses, Lint::RescueException, Lint::RescueType, Lint::SafeNavigationChain, Lint::ScriptPermission, Lint::ShadowedException, Lint::ShadowingOuterLocalVariable, Lint::StringConversionInInterpolation, Lint::UnderscorePrefixedVariableName, Lint::UnifiedInteger, Lint::UnneededDisable, Lint::UnneededSplatExpansion, Lint::UnreachableCode, Lint::UnusedBlockArgument, Lint::UnusedMethodArgument, Lint::UselessAccessModifier, Lint::UselessAssignment, Lint::UselessComparison, Lint::UselessElseWithoutRescue, Lint::UselessSetterCall, Lint::Void, Metrics::AbcSize, Metrics::BlockLength, Metrics::BlockNesting, Metrics::ClassLength, Metrics::CyclomaticComplexity, Metrics::LineLength, Metrics::MethodLength, Metrics::ModuleLength, Metrics::ParameterLists, Metrics::PerceivedComplexity, Performance::Caller, Performance::CaseWhenSplat, Performance::Casecmp, Performance::CompareWithBlock, Performance::Count, Performance::Detect, Performance::DoubleStartEndWith, Performance::EndWith, Performance::FixedSize, Performance::FlatMap, Performance::HashEachMethods, Performance::LstripRstrip, Performance::RangeInclude, Performance::RedundantBlockCall, Performance::RedundantMatch, Performance::RedundantMerge, Performance::RedundantSortBy, Performance::RegexpMatch, Performance::ReverseEach, Performance::Sample, Performance::Size, Performance::StartWith, Performance::StringReplacement, Performance::TimesMap, Rails::ActionFilter, Rails::ActiveSupportAliases, Rails::ApplicationJob, Rails::ApplicationRecord, Rails::Blank, Rails::Date, Rails::Delegate, Rails::DelegateAllowBlank, Rails::DynamicFindBy, Rails::EnumUniqueness, Rails::Exit, Rails::FilePath, Rails::FindBy, Rails::FindEach, Rails::HasAndBelongsToMany, Rails::HttpPositionalArguments, Rails::NotNullColumn, Rails::Output, Rails::OutputSafety, Rails::PluralizationGrammar, Rails::Present, Rails::ReadWriteAttribute, Rails::RelativeDateConstant, Rails::RequestReferer, Rails::ReversibleMigration, Rails::SafeNavigation, Rails::SaveBang, Rails::ScopeArgs, Rails::SkipsModelValidations, Rails::TimeZone, Rails::UniqBeforePluck, Rails::Validation, Security::Eval, Security::JSONLoad, Security::MarshalLoad, Security::YAMLLoad, Style::AccessorMethodName, Style::Alias, Style::AndOr, Style::ArrayJoin, Style::AsciiComments, Style::AsciiIdentifiers, Style::Attr, Style::AutoResourceCleanup, Style::BarePercentLiterals, Style::BeginBlock, Style::BlockComments, Style::BlockDelimiters, Style::BracesAroundHashParameters, Style::CaseEquality, Style::CharacterLiteral, Style::ClassAndModuleCamelCase, Style::ClassAndModuleChildren, Style::ClassCheck, Style::ClassMethods, Style::ClassVars, Style::CollectionMethods, Style::ColonMethodCall, Style::CommandLiteral, Style::CommentAnnotation, Style::ConditionalAssignment, Style::ConstantName, Style::Copyright, Style::DefWithParentheses, Style::Documentation, Style::DocumentationMethod, Style::DoubleNegation, Style::EachForSimpleLoop, Style::EachWithObject, Style::EmptyCaseCondition, Style::EmptyElse, Style::EmptyLiteral, Style::EmptyMethod, Style::Encoding, Style::EndBlock, Style::EvenOdd, Style::FileName, Style::FlipFlop, Style::For, Style::FormatString, Style::FormatStringToken, Style::FrozenStringLiteralComment, Style::GlobalVars, Style::GuardClause, Style::HashSyntax, Style::IdenticalConditionalBranches, Style::IfInsideElse, Style::IfUnlessModifier, Style::IfUnlessModifierOfIfUnless, Style::IfWithSemicolon, Style::ImplicitRuntimeError, Style::InfiniteLoop, Style::InlineComment, Style::InverseMethods, Style::Lambda, Style::LambdaCall, Style::LineEndConcatenation, Style::MethodCallWithArgsParentheses, Style::MethodCallWithoutArgsParentheses, Style::MethodCalledOnDoEndBlock, Style::MethodDefParentheses, Style::MethodMissing, Style::MethodName, Style::MissingElse, Style::MixinGrouping, Style::ModuleFunction, Style::MultilineBlockChain, Style::MultilineIfModifier, Style::MultilineIfThen, Style::MultilineMemoization, Style::MultilineTernaryOperator, Style::MultipleComparison, Style::MutableConstant, Style::NegatedIf, Style::NegatedWhile, Style::NestedModifier, Style::NestedParenthesizedCalls, Style::NestedTernaryOperator, Style::Next, Style::NilComparison, Style::NonNilCheck, Style::Not, Style::NumericLiteralPrefix, Style::NumericLiterals, Style::NumericPredicate, Style::OneLineConditional, Style::OpMethod, Style::OptionHash, Style::OptionalArguments, Style::ParallelAssignment, Style::ParenthesesAroundCondition, Style::PercentLiteralDelimiters, Style::PercentQLiterals, Style::PerlBackrefs, Style::PredicateName, Style::PreferredHashMethods, Style::Proc, Style::RaiseArgs, Style::RedundantBegin, Style::RedundantException, Style::RedundantFreeze, Style::RedundantParentheses, Style::RedundantReturn, Style::RedundantSelf, Style::RegexpLiteral, Style::RescueModifier, Style::SafeNavigation, Style::SelfAssignment, Style::Semicolon, Style::Send, Style::SignalException, Style::SingleLineBlockParams, Style::SingleLineMethods, Style::SpecialGlobalVars, Style::StabbyLambdaParentheses, Style::StringLiterals, Style::StringLiteralsInInterpolation, Style::StringMethods, Style::StructInheritance, Style::SymbolArray, Style::SymbolLiteral, Style::SymbolProc, Style::TernaryParentheses, Style::TrailingCommaInArguments, Style::TrailingCommaInLiteral, Style::TrailingUnderscoreVariable, Style::TrivialAccessors, Style::UnlessElse, Style::UnneededCapitalW, Style::UnneededInterpolation, Style::UnneededPercentQ, Style::VariableInterpolation, Style::VariableName, Style::VariableNumber, Style::WhenThen, Style::WhileUntilDo, Style::WhileUntilModifier, Style::WordArray, Style::YodaCondition, Style::ZeroLengthPredicate

Constant Summary

Constants included from Util

Util::ASGN_NODES, Util::BYTE_ORDER_MARK, Util::CONDITIONAL_NODES, Util::EQUALS_ASGN_NODES, Util::LITERAL_REGEX, Util::LOGICAL_OPERATOR_NODES, Util::MODIFIER_NODES, Util::OPERATOR_METHODS, Util::SHORTHAND_ASGN_NODES

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from AST::Sexp

s

Methods included from NodePattern::Macros

def_node_matcher, def_node_search, node_search, node_search_all, node_search_body, node_search_first

Methods included from AutocorrectLogic

#autocorrect?, #autocorrect_enabled?, #autocorrect_requested?, #support_autocorrect?

Methods included from IgnoredNode

#ignore_node, #ignored_node?, #part_of_ignored_node?

Methods included from Util

begins_its_line?, block_length, comment_line?, compatible_external_encoding_for?, directions, double_quotes_required?, effective_column, ends_its_line?, escape_string, first_part_of_call_chain, interpret_string_escapes, line_distance, line_range, move_pos, needs_escaping?, on_node, operator?, parentheses?, parenthesized_call?, preceed?, range_between, range_by_whole_lines, range_with_surrounding_comma, range_with_surrounding_space, same_line?, source_range, strip_quotes, stripped_source_upto, symbol_without_quote?, to_string_literal, to_supported_styles, to_symbol_literal, within_node?

Methods included from PathUtil

absolute?, match_path?, relative_path, smart_path

Constructor Details

#initialize(config = nil, options = nil) ⇒ Cop

Returns a new instance of Cop.



94
95
96
97
98
99
100
101
# File 'lib/rubocop/cop/cop.rb', line 94

def initialize(config = nil, options = nil)
  @config = config || Config.new
  @options = options || { debug: false }

  @offenses = []
  @corrections = []
  @processed_source = nil
end

Class Attribute Details

.registryObject (readonly)

Returns the value of attribute registry.



40
41
42
# File 'lib/rubocop/cop/cop.rb', line 40

def registry
  @registry
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



34
35
36
# File 'lib/rubocop/cop/cop.rb', line 34

def config
  @config
end

#correctionsObject (readonly)

Returns the value of attribute corrections.



34
35
36
# File 'lib/rubocop/cop/cop.rb', line 34

def corrections
  @corrections
end

#offensesObject (readonly)

Returns the value of attribute offenses.



34
35
36
# File 'lib/rubocop/cop/cop.rb', line 34

def offenses
  @offenses
end

#processed_sourceObject

TODO: Bad design.



35
36
37
# File 'lib/rubocop/cop/cop.rb', line 35

def processed_source
  @processed_source
end

Class Method Details

.allObject



43
44
45
# File 'lib/rubocop/cop/cop.rb', line 43

def self.all
  registry.without_department(:Test).cops
end

.autocorrect_incompatible_withArray<RuboCop::Cop::Cop>

List of cops that should not try to autocorrect at the same time as this cop

Returns:



90
91
92
# File 'lib/rubocop/cop/cop.rb', line 90

def self.autocorrect_incompatible_with
  []
end

.badgeObject



59
60
61
# File 'lib/rubocop/cop/cop.rb', line 59

def self.badge
  @badge ||= Badge.for(name)
end

.cop_nameObject



63
64
65
# File 'lib/rubocop/cop/cop.rb', line 63

def self.cop_name
  badge.to_s
end

.departmentObject



67
68
69
# File 'lib/rubocop/cop/cop.rb', line 67

def self.department
  badge.department
end

.inherited(subclass) ⇒ Object



55
56
57
# File 'lib/rubocop/cop/cop.rb', line 55

def self.inherited(subclass)
  registry.enlist(subclass)
end

.lint?Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/rubocop/cop/cop.rb', line 71

def self.lint?
  department == :Lint
end

.match?(given_names) ⇒ Boolean

Returns true if the cop name or the cop namespace matches any of the given names.

Returns:

  • (Boolean)


77
78
79
80
81
82
# File 'lib/rubocop/cop/cop.rb', line 77

def self.match?(given_names)
  return false unless given_names

  given_names.include?(cop_name) ||
    given_names.include?(department.to_s)
end

.non_railsObject



51
52
53
# File 'lib/rubocop/cop/cop.rb', line 51

def self.non_rails
  registry.without_department(:Rails)
end

.qualified_cop_name(name, origin) ⇒ Object



47
48
49
# File 'lib/rubocop/cop/cop.rb', line 47

def self.qualified_cop_name(name, origin)
  registry.qualified_cop_name(name, origin)
end

Instance Method Details

#add_offense(node, loc, message = nil, severity = nil) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/rubocop/cop/cop.rb', line 115

def add_offense(node, loc, message = nil, severity = nil)
  location = find_location(node, loc)

  return if duplicate_location?(location)

  severity = custom_severity || severity || default_severity

  message ||= message(node)
  message = annotate(message)

  status = enabled_line?(location.line) ? correct(node) : :disabled

  @offenses << Offense.new(severity, location, message, name, status)
  yield if block_given? && status != :disabled
end

#config_to_allow_offensesObject



150
151
152
153
# File 'lib/rubocop/cop/cop.rb', line 150

def config_to_allow_offenses
  Formatter::DisabledConfigFormatter
    .config_to_allow_offenses[cop_name] ||= {}
end

#config_to_allow_offenses=(hash) ⇒ Object



155
156
157
158
# File 'lib/rubocop/cop/cop.rb', line 155

def config_to_allow_offenses=(hash)
  Formatter::DisabledConfigFormatter.config_to_allow_offenses[cop_name] =
    hash
end

#cop_configObject



107
108
109
# File 'lib/rubocop/cop/cop.rb', line 107

def cop_config
  @cop_config ||= @config.for_cop(self)
end

#cop_nameObject Also known as: name



172
173
174
# File 'lib/rubocop/cop/cop.rb', line 172

def cop_name
  @cop_name ||= self.class.cop_name
end

#correct(node) ⇒ Object



140
141
142
143
144
145
146
147
148
# File 'lib/rubocop/cop/cop.rb', line 140

def correct(node)
  return :unsupported unless support_autocorrect?
  return :uncorrected unless autocorrect?

  correction = autocorrect(node)
  return :uncorrected unless correction
  @corrections << correction
  :corrected
end

#duplicate_location?(location) ⇒ Boolean

Returns:

  • (Boolean)


136
137
138
# File 'lib/rubocop/cop/cop.rb', line 136

def duplicate_location?(location)
  @offenses.any? { |o| o.location == location }
end

#excluded_file?(file) ⇒ Boolean

Returns:

  • (Boolean)


183
184
185
# File 'lib/rubocop/cop/cop.rb', line 183

def excluded_file?(file)
  !relevant_file?(file)
end

#find_location(node, loc) ⇒ Object



131
132
133
134
# File 'lib/rubocop/cop/cop.rb', line 131

def find_location(node, loc)
  # Location can be provided as a symbol, e.g.: `:keyword`
  loc.is_a?(Symbol) ? node.loc.public_send(loc) : loc
end

#highlightsObject



89
90
91
# File 'lib/rubocop/rspec/cop_helper.rb', line 89

def highlights
  offenses.sort.map { |o| o.location.source }
end

#join_force?(_force_class) ⇒ Boolean

Returns:

  • (Boolean)


103
104
105
# File 'lib/rubocop/cop/cop.rb', line 103

def join_force?(_force_class)
  false
end

#message(_node = nil) ⇒ Object



111
112
113
# File 'lib/rubocop/cop/cop.rb', line 111

def message(_node = nil)
  self.class::MSG
end

#messagesObject



85
86
87
# File 'lib/rubocop/rspec/cop_helper.rb', line 85

def messages
  offenses.sort.map(&:message)
end

#parse(source, path = nil) ⇒ Object



168
169
170
# File 'lib/rubocop/cop/cop.rb', line 168

def parse(source, path = nil)
  ProcessedSource.new(source, target_ruby_version, path)
end

#relevant_file?(file) ⇒ Boolean

Returns:

  • (Boolean)


178
179
180
181
# File 'lib/rubocop/cop/cop.rb', line 178

def relevant_file?(file)
  file_name_matches_any?(file, 'Include', true) &&
    !file_name_matches_any?(file, 'Exclude', false)
end

#target_rails_versionObject



164
165
166
# File 'lib/rubocop/cop/cop.rb', line 164

def target_rails_version
  @config.target_rails_version
end

#target_ruby_versionObject



160
161
162
# File 'lib/rubocop/cop/cop.rb', line 160

def target_ruby_version
  @config.target_ruby_version
end