All files / src/rules empty_line_in_statement.ts

98.82% Statements 84/85
88.88% Branches 24/27
100% Functions 7/7
98.82% Lines 84/85

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 851x 1x 1x 1x 1x 1x 1x 1x 1x 1x 22906x 22906x 22906x 22906x 1x 11454x 11454x 11454x 11454x 11454x 34219x 34219x 34219x 34219x 34219x 34219x 34219x 34219x 34219x 34219x 34219x 34219x 11454x 11454x 2x 2x 11454x 11454x 10928x 10928x 11454x 11454x 247x 247x 11454x 11454x 278x 278x 278x 278x 12x 12x 266x 278x 1529x 1529x 9x 9x 1529x 257x 257x 278x 6415x 23x 6415x 1365x 1365x 6415x 2x 2x 2x 2x 6415x 1364x 6415x   5028x 5028x 5028x 6415x 257x 257x 257x 11454x 11454x
import {Issue} from "../issue";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import {Punctuation, Comment as CommentToken} from "../abap/1_lexer/tokens";
import {NativeSQL, Unknown} from "../abap/2_statements/statements/_statement";
import {EditHelper} from "../edit_helper";
import {IRuleMetadata, RuleTag} from "./_irule";
import {Position} from "../position";
import {ABAPFile} from "../abap/abap_file";
 
export class EmptyLineinStatementConf extends BasicRuleConfig {
  /** Allow changed empty lines in chanined statements */
  public allowChained: boolean = false;
}
 
export class EmptyLineinStatement extends ABAPRule {
 
  private conf = new EmptyLineinStatementConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "empty_line_in_statement",
      title: "Find empty lines in statements",
      shortDescription: `Checks that statements do not contain empty lines.`,
      extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#dont-obsess-with-separating-blank-lines
 
https://docs.abapopenchecks.org/checks/41/`,
      tags: [RuleTag.Quickfix, RuleTag.Whitespace, RuleTag.SingleFile, RuleTag.Styleguide],
      badExample: `WRITE\n\nhello.`,
      goodExample: `WRITE hello.`,
    };
  }
 
  private getMessage(): string {
    return "Remove empty line in statement";
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: EmptyLineinStatementConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile) {
    const issues: Issue[] = [];
 
    const stru = file.getStructure();
    if (stru === undefined) {
      return [];
    }
 
    for (const s of file.getStatements()) {
      if (s.get() instanceof Unknown
          || s.get() instanceof NativeSQL) {
        return []; // skip the file if there are parser errors or native/sqlscript
      }
    }
 
    let prevLine: number | undefined = undefined;
    for (const t of file.getTokens()) {
      if (prevLine === undefined && t instanceof CommentToken) {
        continue;
      } else if (prevLine === undefined) {
        prevLine = t.getRow();
      }
      if (prevLine && t.getRow() - prevLine >= 2) {
        const fix = EditHelper.deleteRange(file, new Position(prevLine + 1, 1), t.getStart());
        const issue = Issue.atToken(file, t, this.getMessage(), this.getMetadata().key, this.conf.severity, fix);
        issues.push(issue);
      }
      if (t instanceof Punctuation && t.getStr() === ".") {
        prevLine = undefined;
      } else if (this.conf.allowChained === true && t instanceof Punctuation && t.getStr() === ",") {
        prevLine = undefined;
      } else {
        prevLine = t.getRow();
      }
    }
 
    return issues;
  }
 
}