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 10898x 10898x 10898x 10898x 10898x 32494x 32494x 32494x 32494x 32494x 32494x 32494x 32494x 32494x 32494x 32494x 32494x 32494x 32494x 32494x 32494x 10898x 10898x 10352x 10352x 10898x 10898x 258x 258x 10898x 10898x 275x 275x 275x 80x 80x 195x 195x 275x 10x 10x 185x 185x 185x 275x 382x 13x 2x 2x 13x 13x 13x 382x 134x 134x 134x 69x 69x 65x 369x 235x 1x 1x 235x 235x 235x 235x 382x 185x 275x 4x 4x 185x 185x 185x 10898x 10898x  
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;
  }
 
}