Class: RemLint::Rules::CallbackSignature

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

Overview

Callback functions defined with the wrong number of arguments.

Remind calls a dozen or so functions by name and by shape. It does not look them up and adapt -- it checks the arity and, if it does not match, walks away:

UserFuncExists("msgprefix") == 1     src/dorem.c
check_subst_args(func, 3)            src/dosubst.c

So a msgprefix(p, q) is never called. Not called with an error, not called with a warning: the prefix simply does not appear, and the obvious conclusion is that the callback mechanism is broken rather than that the signature is.

This is FunctionArity turned around. That rule checks calls against the functions they name; this one checks definitions against the shape Remind will call them with.

Constant Summary collapse

ONE_ARGUMENT =

name => arity Remind insists on.

One argument: the prefix and suffix callbacks (given the priority) and the two ordinal helpers. Three: the substitution-filter family, called as name(altmode, date, time).

%w[msgprefix msgsuffix calprefix calsuffix ordx subst_ampm subst_ordinal].freeze
THREE_ARGUMENTS =
%w[
  subst_at subst_atx subst_bang subst_bangx subst_colon subst_colonx
  subst_hash subst_hashx subst_question subst_questionx
].freeze
ARITIES =
(
  ONE_ARGUMENT.to_h { |name| [name, 1] }
    .merge(THREE_ARGUMENTS.to_h { |name| [name, 3] })
).freeze
OVERRIDE =

get_function_override builds subst_<c> and subst_<c>x for a single alphanumeric or underscore character (src/dosubst.c). So subst_a and subst_ax are callbacks and subst_a_alt is not -- it is an ordinary helper, and Remind's own language packs are full of them. Getting this wrong reports 45 offences against include/lang.

/\Asubst_[a-z0-9_]x?\z/
NAMED =

A %{name} in the file makes subst_name a callback, called with the same three arguments.

/%\{(?<name>[^}]*)\}/
DEFINITION =
/\A(?:-\s*)?(?<name>[A-Za-z_]\w*)\s*\((?<params>[^)]*)\)/

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



55
56
57
# File 'lib/remlint/rules/callback_signature.rb', line 55

def self.default_severity
  "warning"
end

.descriptionObject



59
60
61
# File 'lib/remlint/rules/callback_signature.rb', line 59

def self.description
  "A Remind callback function defined with the wrong number of arguments."
end

Instance Method Details

#checkObject



63
64
65
66
67
68
69
70
71
# File 'lib/remlint/rules/callback_signature.rb', line 63

def check
  @named = named_substitutions

  document.code_commands.each do |command|
    if command.keyword?("FSET")
      check_definition(command)
    end
  end
end