class RuboCop::Cop::Sorbet::ValidSigil
If a ‘MinimumStrictness` level is specified, it will be used in offense messages and autocorrect.
* `MinimumStrictness`: If set, make offense if the strictness level in the file is below this one
* `SuggestedStrictness`: Sorbet strictness level suggested in offense messages (default: ’false’)
* ‘RequireSigilOnAllFiles`: make offense if the Sorbet typed is not found in the file (default: false)
Options:
Adapted from: gist.github.com/clarkdave/85aca4e16f33fd52aceb6a0a29936e52<br>This cop checks that every Ruby file contains a valid Sorbet sigil.
def autocorrect(_node)
def autocorrect(_node) lambda do |corrector| return unless require_sigil_on_all_files? return unless extract_sigil(processed_source).nil? token = processed_source.tokens.first corrector.insert_before(token.pos, "# typed: #{minimum_strictness || suggested_strictness}\n") end end
def check_sigil_present(sigil)
def check_sigil_present(sigil) return true unless sigil.nil? token = processed_source.tokens.first if require_sigil_on_all_files? strictness = minimum_strictness || suggested_strictness add_offense( token, location: token.pos, message: 'No Sorbet sigil found in file. ' \ "Try a `typed: #{strictness}` to start (you can also use `rubocop -a` to automatically add this)." ) end false end
def check_strictness_level(sigil, strictness)
def check_strictness_level(sigil, strictness) return true unless minimum_strictness minimum_level = STRICTNESS_LEVELS.index(minimum_strictness) current_level = STRICTNESS_LEVELS.index(strictness) if current_level < minimum_level add_offense( sigil, location: sigil.pos, message: "Sorbet sigil should be at least `#{minimum_strictness}` got `#{strictness}`." ) return false end true end
def check_strictness_not_empty(sigil, strictness)
def check_strictness_not_empty(sigil, strictness) return true if strictness add_offense( sigil, location: sigil.pos, message: 'Sorbet sigil should not be empty.' ) false end
def check_strictness_valid(sigil, strictness)
def check_strictness_valid(sigil, strictness) return true if STRICTNESS_LEVELS.include?(strictness) add_offense( sigil, location: sigil.pos, message: "Invalid Sorbet sigil `#{strictness}`." ) false end
def extract_sigil(processed_source)
def extract_sigil(processed_source) processed_source.tokens .take_while { |token| token.type == :tCOMMENT } .find { |token| SIGIL_REGEX.match?(token.text) } end
def extract_strictness(sigil)
def extract_strictness(sigil) sigil.text.match(SIGIL_REGEX)&.captures&.first end
def investigate(processed_source)
def investigate(processed_source) return if processed_source.tokens.empty? sigil = extract_sigil(processed_source) return unless check_sigil_present(sigil) strictness = extract_strictness(sigil) return unless check_strictness_not_empty(sigil, strictness) return unless check_strictness_valid(sigil, strictness) return unless check_strictness_level(sigil, strictness) end
def minimum_strictness
def minimum_strictness cop_config['MinimumStrictness'] end
def require_sigil_on_all_files?
def require_sigil_on_all_files? !!cop_config['RequireSigilOnAllFiles'] end
def suggested_strictness
def suggested_strictness cop_config['SuggestedStrictness'] || 'false' end