Class: RemLint::Rules::FunctionRedefinition

Inherits:
RemLint::Rule show all
Defined in:
lib/remlint/rules/function_redefinition.rb

Overview

A function defined twice without saying so.

Remind warns about a redefinition itself, and gives you a way to say the redefinition is deliberate: FSET - name(...) sets suppress_redefined_function_warning and the warning goes away (src/userfns.c). So this rule is not telling you something Remind would not -- it is telling you where the - goes.

Worth having anyway, because the two definitions are usually a long way apart. Remind's own tests/test.rem defines g(x, y) on line 356 and redefines it as g(x) on line 1545, and every call in between is checked against a different function than the one the reader is looking at.

A definition inside a PUSH-FUNCS block is left alone: pushing the function table is exactly how you say "this redefinition is scoped", and Remind skips its own warning for a pushed function too (!existing->been_pushed).

Constant Summary collapse

DEFINITION =

FSET name(args) and the FSET - name(args) that suppresses the warning.

/\A(?<deliberate>-\s*)?(?<name>[A-Za-z_]\w*)\s*\(/

Constants inherited from RemLint::Rule

RemLint::Rule::REGISTRY

Instance Attribute Summary

Attributes inherited from RemLint::Rule

#config, #document, #offenses

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from RemLint::Rule

all, enabled_by_default?, find, inherited, #initialize, rule_name, #rule_name, #run

Constructor Details

This class inherits a constructor from RemLint::Rule

Class Method Details

.default_severityObject



31
32
33
# File 'lib/remlint/rules/function_redefinition.rb', line 31

def self.default_severity
  "warning"
end

.descriptionObject



35
36
37
# File 'lib/remlint/rules/function_redefinition.rb', line 35

def self.description
  "A function redefined without the FSET - form that says so."
end

Instance Method Details

#checkObject



39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/remlint/rules/function_redefinition.rb', line 39

def check
  seen = {}
  pushed = 0

  document.code_commands.each do |command|
    pushed = track(command, pushed)

    if command.keyword?("FSET") && pushed.zero?
      check_definition(command, seen)
    end
  end
end