Class: SasLinter::Rules::ChooseOneTemplate
- Inherits:
-
SasLinter::Rule
- Object
- SasLinter::Rule
- SasLinter::Rules::ChooseOneTemplate
- Defined in:
- lib/sas_linter/rules/choose_one_template.rb
Overview
Flag SAS sources that ship with the “CHOOSE ONE OF THE BELOW STATEMENTS” banner. The banner introduces a block of mutually-exclusive validity guards (typically ‘[USE FOR HC OR CHA WITH FS]`, `[USE FOR LTCF]`, `[USE FOR CHA WITHOUT FS]`, etc.), all commented out, and asks the downstream consumer to pick one before the source will work.
Why it’s an antipattern:
- The source is broken-by-default — every consumer must mutate it
before use.
- SAS won't error on the dangling `end;` of the (also-commented)
block, but the algorithm runs unguarded if no variant is picked.
- The deployment-context decision should belong to a config file or
a separate per-context source variant, not to a comment-toggle
buried in the middle of the algorithm.
Companion rule: ‘commented_out_guard` flags the individual disabled guards. This rule flags the banner that introduces them, so we can find every file that ships in the multi-template state regardless of whether any variant has already been activated.
Constant Summary collapse
- TT =
SasLexer::Lexer::TokenType
- TC =
SasLexer::Lexer::TokenChannel
- BANNER =
/CHOOSE\s+ONE\s+OF\s+THE\s+BELOW\s+STATEMENTS/i
Instance Attribute Summary
Attributes inherited from SasLinter::Rule
Instance Method Summary collapse
-
#check(_tokens, path:, all_tokens: nil, source: nil) ⇒ Object
rubocop:disable Lint/UnusedMethodArgument.
Methods inherited from SasLinter::Rule
all, #autofix?, description, fetch, from_config, inherited, #initialize, register, registry, rule_id, severity, supports_autofix?
Constructor Details
This class inherits a constructor from SasLinter::Rule
Instance Method Details
#check(_tokens, path:, all_tokens: nil, source: nil) ⇒ Object
rubocop:disable Lint/UnusedMethodArgument
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/sas_linter/rules/choose_one_template.rb', line 39 def check(_tokens, path:, all_tokens: nil, source: nil) # rubocop:disable Lint/UnusedMethodArgument return [] unless all_tokens all_tokens.filter_map do |tok| next unless tok[:channel] == TC::COMMENT next unless tok[:type] == TT::COMMENT_STAT next unless tok[:text] =~ BANNER finding( line: tok[:start_line], column: tok[:start_column] + 1, message: "'CHOOSE ONE OF THE BELOW STATEMENTS' banner — source is " \ "broken-by-default; the alternative validity guards below " \ "are all commented out so every consumer must edit this " \ "file. Pick one variant, delete the others, and remove " \ "this banner.", path: path ) end end |