All files / src/rules classic_exceptions_overlap.ts

97.22% Statements 70/72
85.71% Branches 12/14
100% Functions 5/5
97.22% Lines 70/72

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 721x 1x 1x 1x 1x 1x 1x 1x 1x 1x 10331x 10331x 10331x 10331x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 10331x 10331x 9817x 9817x 10331x 10331x 241x 241x 10331x 10331x 257x 257x 257x 257x 12x 12x 245x 257x 4x 4x 10x 10x     10x 3x 3x 3x 3x 3x 7x 7x 4x 245x 245x 245x 10331x 10331x
import {Issue} from "../issue";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import * as Expressions from "../abap/2_statements/expressions";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
 
export class ClassicExceptionsOverlapConf extends BasicRuleConfig {
}
 
export class ClassicExceptionsOverlap extends ABAPRule {
  private conf = new ClassicExceptionsOverlapConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "classic_exceptions_overlap",
      title: "Classic exceptions overlap when catching",
      shortDescription: `Find overlapping classic exceptions`,
      extendedInformation: `When debugging its typically good to know exactly which exception is caught`,
      tags: [RuleTag.SingleFile],
      badExample: `CALL FUNCTION 'SOMETHING'
  EXCEPTIONS
    system_failure        = 1 MESSAGE lv_message
    communication_failure = 1 MESSAGE lv_message
    resource_failure      = 1
    OTHERS                = 1.`,
      goodExample: `CALL FUNCTION 'SOMETHING'
  EXCEPTIONS
    system_failure        = 1 MESSAGE lv_message
    communication_failure = 2 MESSAGE lv_message
    resource_failure      = 3
    OTHERS                = 4.`,
    };
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: ClassicExceptionsOverlapConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile) {
    const output: Issue[] = [];
 
    const struc = file.getStructure();
    if (struc === undefined) {
      return []; // syntax error
    }
 
    for (const p of struc.findAllExpressions(Expressions.ParameterListExceptions)) {
      const set = new Set<string>();
      for (const e of p.findAllExpressions(Expressions.ParameterException)) {
        const text = e.findDirectExpression(Expressions.SimpleName)?.concatTokens().toUpperCase();
        if (text === undefined) {
          continue;
        }
        if (set.has(text)) {
          const message = "Exception overlap, " + text;
          const issue = Issue.atToken(file, e.getFirstToken(), message, this.getMetadata().key, this.getConfig().severity);
          output.push(issue);
          break;
        }
        set.add(text);
      }
    }
 
    return output;
  }
 
}