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 10784x 10784x 10784x 10784x 10784x 32186x 32186x 32186x 32186x 32186x 32186x 32186x 32186x 32186x 32186x 32186x 32186x 32186x 32186x 32186x 32186x 10784x 10784x 10274x 10274x 10784x 10784x 240x 240x 10784x 10784x 257x 257x 257x 81x 81x 176x 176x 257x 10x 10x 166x 166x 166x 257x 378x 12x 2x 2x 12x 12x 12x 378x 148x 148x 148x 106x 106x 42x 366x 218x 1x 1x 218x 218x 218x 218x 378x 166x 257x 4x 4x 166x 166x 166x 10784x 10784x  
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 "../stuff";
 
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;
  }
 
}