All files / src/rules identical_descriptions.ts

96.15% Statements 100/104
91.66% Branches 33/36
100% Functions 7/7
96.15% Lines 100/104

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 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 1041x 1x 1x 1x 1x 1x 1x 1x 1x 1x 10134x 10134x 10134x 10134x 10134x 10134x 30231x 30231x 30231x 30231x 30231x 30231x 30231x 30231x 30231x 30231x 30231x 30231x 30231x 30231x 10134x 10134x 9633x 9633x 10134x 10134x 238x 238x 10134x 10134x 241x 241x 241x 307x     307x 307x 100x 100x 66x 66x 100x 30x 30x 100x 30x 30x 34x 34x 307x 241x 241x 10134x 10134x 305x 305x 305x 98x 98x 65x 65x 33x 33x 98x 7x 7x 7x 98x 240x 305x 2x 2x 240x 240x 240x 10134x 10134x 2x 2x 3x 3x     3x 1x 1x 1x 2x 2x 1x 1x 10134x 10134x
import {Issue} from "../issue";
import {IRule, IRuleMetadata} from "./_irule";
import {IObject} from "../objects/_iobject";
import {IRegistry} from "../_iregistry";
import {BasicRuleConfig} from "./_basic_rule_config";
import {FunctionGroup} from "../objects";
 
export class IdenticalDescriptionsConf extends BasicRuleConfig {
}
 
export class IdenticalDescriptions implements IRule {
  private conf = new IdenticalDescriptionsConf();
  private descriptions: {[type: string]: {[description: string]: string[]}};
  private types: string[];
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "identical_descriptions",
      title: "Identical descriptions",
      shortDescription: `Searches for objects with the same type and same description`,
      extendedInformation: `Case insensitive
 
Only checks the master language descriptions
 
Dependencies are skipped
 
Works for: INTF, CLAS, DOMA, DTEL, FUNC in same FUGR`,
      tags: [],
    };
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: IdenticalDescriptionsConf) {
    this.conf = conf;
  }
 
  public initialize(reg: IRegistry) {
    this.descriptions = {};
    this.types = ["INTF", "CLAS", "DOMA", "DTEL"];
    for (const o of reg.getObjects()) {
      if (reg.isDependency(o)) {
        continue;
      }
      const type = o.getType();
      if (this.types.includes(type)) {
        const description = o.getDescription()?.toUpperCase();
        if (description === undefined || description === "") {
          continue;
        }
        if (this.descriptions[type] === undefined) {
          this.descriptions[type] = {};
        }
        if (this.descriptions[type][description] === undefined) {
          this.descriptions[type][description] = [];
        }
        this.descriptions[type][description].push(o.getName());
      }
    }
    return this;
  }
 
  public run(o: IObject): Issue[] {
    const issues: Issue[] = [];
    const type = o.getType();
    if (this.types.includes(type)) {
      const description = o.getDescription()?.toUpperCase();
      if (description === undefined || description === "") {
        return issues;
      }
 
      const found = this.descriptions[type][description].filter(a => a !== o.getName());
      if (found.length > 0) {
        const message = "Identical description: " + found[0];
        issues.push(Issue.atRow(o.getXMLFile()!, 1, message, this.getMetadata().key, this.getConfig().severity));
      }
    }
 
    if (o instanceof FunctionGroup) {
      issues.push(...this.checkFunctionModules(o));
    }
 
    return issues;
  }
 
  private checkFunctionModules(fugr: FunctionGroup): Issue[] {
    const descriptions: {[type: string]: boolean} = {};
    for (const fm of fugr.getModules()) {
      const d = fm.getDescription()?.toUpperCase();
      if (d === undefined || d === "") {
        continue;
      }
      if (descriptions[d] !== undefined) {
        const message = "FUGR " + fugr.getName() + " contains function modules with identical descriptions";
        return [Issue.atRow(fugr.getXMLFile()!, 1, message, this.getMetadata().key, this.getConfig().severity)];
      }
      descriptions[d] = true;
    }
    return [];
  }
 
}