Class: RemLint::Rules::UnbalancedBlocks
- Inherits:
-
RemLint::Rule
- Object
- RemLint::Rule
- RemLint::Rules::UnbalancedBlocks
- Defined in:
- lib/remlint/rules/unbalanced_blocks.rb
Overview
Block commands that never close, close the wrong thing, or close nothing.
Remind has its own "Warning: Missing ENDIF" (src/err.h E_MISS_ENDIF), but only for the file it actually reaches the end of, and only once it has run everything above. A linter can say it before anything runs, name the line the block opened on, and cover the three context stacks Remind's own warning does not:
IF / IFTRIG ... ELSE ... ENDIF
PUSH-OMIT-CONTEXT ... POP-OMIT-CONTEXT
PUSH-VARS ... POP-VARS
PUSH-FUNCS ... POP-FUNCS
defs.rem nests IF inside ELSE inside IF for its Yom Hazikaron
calculation and brackets its US Tax Day block in PUSH/POP-OMIT-CONTEXT,
so all of this is load-bearing in the shipped examples.
Matching is by canonical keyword, so the abbreviations Remind allows --
PUSH for PUSH-OMIT-CONTEXT, POP for POP-OMIT-CONTEXT -- are matched
like the long forms rather than missed.
Constant Summary collapse
- PAIRS =
{ "IF" => "ENDIF", "IFTRIG" => "ENDIF", "PUSH-OMIT-CONTEXT" => "POP-OMIT-CONTEXT", "PUSH-VARS" => "POP-VARS", "PUSH-FUNCS" => "POP-FUNCS", }.freeze
- CLOSERS =
PAIRS.values.uniq.freeze
- MAX_IF_DEPTH =
IF_NESTin src/ifelse.c. The 65th level is an error rather than a deeper nesting, and the linter can say so before the file runs -- though a script at that depth has larger problems than this rule. 64- OPENERS_FOR =
Which openers a given closer is allowed to close.
CLOSERS.to_h do |closer| [closer, PAIRS.select { |_opener, close| close == closer }.keys] end.freeze
Constants inherited from RemLint::Rule
Instance Attribute Summary
Attributes inherited from RemLint::Rule
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_severity ⇒ Object
48 49 50 |
# File 'lib/remlint/rules/unbalanced_blocks.rb', line 48 def self.default_severity "error" end |
.description ⇒ Object
52 53 54 |
# File 'lib/remlint/rules/unbalanced_blocks.rb', line 52 def self.description "IF/ENDIF, ELSE and the PUSH/POP context commands that do not pair up." end |
Instance Method Details
#check ⇒ Object
56 57 58 59 60 61 62 63 64 |
# File 'lib/remlint/rules/unbalanced_blocks.rb', line 56 def check @stack = [] document.code_commands.each do |command| dispatch(command) end report_unclosed end |