All files / src/rules easy_to_find_messages.ts

100% Statements 80/80
100% Branches 12/12
100% Functions 6/6
100% Lines 80/80

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 801x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 10508x 10508x 10508x 10508x 10508x 31328x 31328x 31328x 31328x 31328x 31328x 31328x 31328x 31328x 31328x 31328x 31328x 31328x 31328x 10508x 10508x 9969x 9969x 10508x 10508x 251x 251x 10508x 10508x 258x 258x 258x 258x 333x 264x 264x 333x 258x 258x 258x 10508x 10508x 324x 324x 324x 10x 10x 10x 10x 3x 3x 3x 3x 10x 1x 1x 1x 1x 1x 10x 10x 324x 324x 324x 10508x 10508x
import {Issue} from "../issue";
import {IRule, IRuleMetadata, RuleTag} from "./_irule";
import {IObject} from "../objects/_iobject";
import {IRegistry} from "../_iregistry";
import {BasicRuleConfig} from "./_basic_rule_config";
import {IMSAGReferences} from "../_imsag_references";
import {Position} from "../position";
import {MessageClass} from "../objects";
import {SyntaxLogic} from "../abap/5_syntax/syntax";
import {ABAPObject} from "../objects/_abap_object";
 
export class EasyToFindMessagesConf extends BasicRuleConfig {
}
 
export class EasyToFindMessages implements IRule {
  private conf = new EasyToFindMessagesConf();
  private msagReferences: IMSAGReferences;
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "easy_to_find_messages",
      title: "Easy to find messages",
      shortDescription: `Make messages easy to find`,
      extendedInformation: `All messages must be statically referenced exactly once
 
Only MESSAGE and RAISE statments are counted as static references
 
Also see rule "message_exists"
 
https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#make-messages-easy-to-find`,
      tags: [RuleTag.Styleguide],
    };
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: EasyToFindMessagesConf) {
    this.conf = conf;
  }
 
  public initialize(reg: IRegistry): IRule {
    this.msagReferences = reg.getMSAGReferences();
 
    // the SyntaxLogic builds the references
    for (const obj of reg.getObjects()) {
      if (obj instanceof ABAPObject) {
        new SyntaxLogic(reg, obj).run();
      }
    }
 
    return this;
  }
 
  public run(object: IObject): Issue[] {
    const issues: Issue[] = [];
 
    if (object.getType() === "MSAG") {
      const msag = object as MessageClass;
      for (const message of msag.getMessages()) {
        const where = this.msagReferences.listByMessage(msag.getName().toUpperCase(), message.getNumber());
        if (where.length === 0) {
          const text = `Message ${message.getNumber()} not statically referenced`;
          const position = new Position(1, 1);
          const issue = Issue.atPosition(object.getFiles()[0], position, text, this.getMetadata().key, this.conf.severity);
          issues.push(issue);
        } else if (where.length >= 2) {
          const text = `Message ${message.getNumber()} referenced more than once`;
          const position = new Position(1, 1);
          const issue = Issue.atPosition(object.getFiles()[0], position, text, this.getMetadata().key, this.conf.severity);
          issues.push(issue);
        }
      }
    }
 
    return issues;
  }
 
}