All files / src/rules empty_line_in_statement.ts

98.77% Statements 80/81
88.89% Branches 24/27
100% Functions 7/7
98.77% Lines 80/81

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 811x 1x 1x 1x 1x 1x 1x 1x 1x 1x 15306x 15306x 15306x 15306x 1x 7654x 7654x 7654x 7654x 7654x 22817x 22817x 22817x 22817x 22817x 22817x 22817x 22817x 7654x 7654x 2x 2x 7654x 7654x 7346x 7346x 7654x 7654x 139x 139x 7654x 7654x 161x 161x 161x 161x 12x 12x 149x 161x 844x 844x 7x 7x 844x 142x 142x 161x 3367x 2x 3367x 779x 779x 3367x 2x 2x 2x 2x 3367x 779x 3367x   2586x 2586x 2586x 3367x 142x 142x 142x 7654x 7654x
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://docs.abapopenchecks.org/checks/41/`,
      tags: [RuleTag.Quickfix, RuleTag.Whitespace, RuleTag.SingleFile],
    };
  }
 
  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;
  }
 
}