Class: SasLinter::Rule

Inherits:
Object
  • Object
show all
Defined in:
lib/sas_linter.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(autofix: false) ⇒ Rule

Returns a new instance of Rule.

Parameters:

  • autofix (Boolean) (defaults to: false)

    when true and the rule supports autofixing, the linter will call ‘#autofix(source)` after `#check` and write the result back to disk. The default constructor accepts this kwarg so every rule’s ‘from_config` can forward it uniformly; rules that don’t support autofix simply ignore it.



95
96
97
# File 'lib/sas_linter.rb', line 95

def initialize(autofix: false)
  @autofix = autofix
end

Instance Attribute Details

#autofix(source) ⇒ Object (readonly)

Override in subclasses that can rewrite source. Return the modified source string. The base implementation is a no-op so rules without autofix can still appear in an autofix-on lint pass without special-casing.



119
120
121
# File 'lib/sas_linter.rb', line 119

def autofix
  @autofix
end

Class Method Details

.allObject



37
38
39
# File 'lib/sas_linter.rb', line 37

def all
  registry.values
end

.description(value = nil) ⇒ Object



60
61
62
63
# File 'lib/sas_linter.rb', line 60

def description(value = nil)
  @description = value if value
  @description
end

.fetch(id) ⇒ Object



41
42
43
44
45
# File 'lib/sas_linter.rb', line 41

def fetch(id)
  registry.fetch(id.to_sym) do
    raise ArgumentError, "Unknown lint rule: #{id.inspect}. Known: #{registry.keys.join(', ')}"
  end
end

.from_config(opts = {}) ⇒ Object

Build a rule instance from a config hash. Subclasses with constructor arguments should override this — the default forwards ‘autofix:` (the only generic option) and ignores the rest.



74
75
76
77
78
79
# File 'lib/sas_linter.rb', line 74

def from_config(opts = {})
  opts = opts.transform_keys(&:to_s)
  kwargs = {}
  kwargs[:autofix] = opts["autofix"] ? true : false if opts.key?("autofix")
  new(**kwargs)
end

.inherited(subclass) ⇒ Object



47
48
49
50
# File 'lib/sas_linter.rb', line 47

def inherited(subclass)
  super
  # Subclasses self-register once they declare an id via `rule_id :foo`.
end

.register(klass) ⇒ Object

Raises:

  • (ArgumentError)


30
31
32
33
34
35
# File 'lib/sas_linter.rb', line 30

def register(klass)
  id = klass.rule_id
  raise ArgumentError, "Rule #{klass} did not declare a rule_id" if id.nil?

  registry[id] = klass
end

.registryObject



26
27
28
# File 'lib/sas_linter.rb', line 26

def registry
  @registry ||= {}
end

.rule_id(value = nil) ⇒ Object



52
53
54
55
56
57
58
# File 'lib/sas_linter.rb', line 52

def rule_id(value = nil)
  if value
    @rule_id = value.to_sym
    Rule.register(self)
  end
  @rule_id
end

.severity(value = nil) ⇒ Object



65
66
67
68
# File 'lib/sas_linter.rb', line 65

def severity(value = nil)
  @severity = value if value
  @severity || :warning
end

.supports_autofix?Boolean

Whether this rule can rewrite source to fix the findings it reports. Rules that override ‘autofix(source)` should also override this to return true.

Returns:

  • (Boolean)


84
85
86
# File 'lib/sas_linter.rb', line 84

def supports_autofix?
  false
end

Instance Method Details

#autofix?Object

Returns the value of attribute autofix.



100
101
102
# File 'lib/sas_linter.rb', line 100

def autofix
  @autofix
end

#check(_tokens, path:, all_tokens: nil, source: nil) ⇒ Object

Subclasses must implement check.

Parameters:

  • tokens (Array<Hash>)

    default-channel tokens (no whitespace, no comments)

  • path (String)

    file path used in Finding output

  • all_tokens (Array<Hash>, nil) (defaults to: nil)

    every token from the lexer including the comment and whitespace channels — supplied for rules that need to inspect comments. Default-channel rules can ignore this.

  • source (String, nil) (defaults to: nil)

    the raw source text, supplied for rules that operate at the byte level (e.g. trailing-whitespace).

Raises:

  • (NotImplementedError)


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

def check(_tokens, path:, all_tokens: nil, source: nil) # rubocop:disable Lint/UnusedMethodArgument
  raise NotImplementedError
end