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 29256x 29256x 29256x 29256x 1x 14629x 14629x 14629x 14629x 14629x 100013x 100013x 100013x 100013x 100013x 100013x 100013x 100013x 100013x 100013x 100013x 100013x 14629x 14629x 2x 2x 14629x 14629x 14066x 14066x 14629x 14629x 264x 264x 14629x 14629x 303x 303x 303x 303x 12x 12x 291x 303x 1651x 1651x 9x 9x 1651x 282x 282x 303x 6887x 29x 6887x 1476x 1476x 6887x 2x 2x 2x 2x 6887x 1475x 6887x   5383x 5383x 5383x 6887x 282x 282x 282x 14629x 14629x
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;
  }
 
}