All files / src/rules empty_event.ts

100% Statements 91/91
93.1% Branches 27/29
100% Functions 5/5
100% Lines 91/91

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 921x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11211x 11211x 11211x 11211x 11211x 33425x 33425x 33425x 33425x 33425x 33425x 33425x 33425x 33425x 33425x 33425x 33425x 33425x 33425x 33425x 33425x 11211x 11211x 10649x 10649x 11211x 11211x 266x 266x 11211x 11211x 283x 283x 283x 80x 80x 203x 203x 283x 10x 10x 193x 193x 193x 283x 396x 13x 2x 2x 13x 13x 13x 396x 138x 138x 138x 95x 95x 43x 383x 245x 1x 1x 245x 245x 245x 245x 396x 193x 283x 4x 4x 193x 193x 193x 11211x 11211x  
import {Issue} from "../issue";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import * as Structures from "../abap/3_structures/structures";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
import {ABAPObject} from "../objects/_abap_object";
import {Program} from "../objects";
import {StatementNode, StructureNode} from "../abap/nodes";
import {DECLARATION_STUFF, SELECTION_EVENTS} from "../abap/flow/selection_events";
 
export class EmptyEventConf extends BasicRuleConfig {
}
 
export class EmptyEvent extends ABAPRule {
 
  private conf = new EmptyEventConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "empty_event",
      title: "Empty selection screen or list processing event block",
      shortDescription: `Empty selection screen or list processing event block`,
      extendedInformation: ``,
      tags: [RuleTag.SingleFile],
      badExample: `
INITIALIZATION.
  WRITE 'hello'.
END-OF-SELECTION.`,
      goodExample: `
START-OF-SELECTION.
  PERFORM sdf.
  COMMIT WORK.`,
    };
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: EmptyEventConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile, obj: ABAPObject) {
    const issues: Issue[] = [];
 
    if (!(obj instanceof Program) || obj.isInclude()) {
      return issues;
    }
 
    const stru = file.getStructure();
    if (stru === undefined) {
      return [];
    }
 
    let currentEvent: StatementNode | undefined = undefined;
    let children: (StatementNode | StructureNode)[] = [];
    for (const s of stru.getChildren() || []) {
      if (SELECTION_EVENTS.some(f => s.get() instanceof f)) {
        if (currentEvent !== undefined && children.length === 0) {
          issues.push(Issue.atStatement(file, currentEvent, "Empty event", this.getMetadata().key, this.getConfig().severity));
        }
 
        children = [];
        currentEvent = s as StatementNode;
      } else if (s.get() instanceof Structures.Normal) {
        const stru = s as StructureNode;
        // ignore declaration stuff
        if (DECLARATION_STUFF.some(d => stru.getFirstStatement()?.get() instanceof d)) {
          continue;
        }
        children.push(s);
      } else {
        if (currentEvent !== undefined && children.length === 0) {
          issues.push(Issue.atStatement(file, currentEvent, "Empty event", this.getMetadata().key, this.getConfig().severity));
        }
 
        children = [];
        currentEvent = undefined;
      }
    }
 
    if (currentEvent !== undefined && children.length === 0) {
      issues.push(Issue.atStatement(file, currentEvent, "Empty event", this.getMetadata().key, this.getConfig().severity));
    }
 
    return issues;
  }
 
}