All files / src/rules line_only_punc.ts

100% Statements 90/90
100% Branches 21/21
100% Functions 7/7
100% Lines 90/90

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 901x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 20648x 20648x 20648x 20648x 1x 10325x 10325x 10325x 10325x 10325x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 10325x 10325x 10x 10x 10325x 10325x 9811x 9811x 10325x 10325x 241x 241x 10325x 10325x 273x 273x 273x 273x 273x 53x 53x 4x 53x 1x 1x 53x 268x 268x 268x 268x 273x 1740x 10x 10x 10x 10x 10x 10x 10x 4x 4x 10x 10x 2x 2x 10x 10x 10x 10x 10x 10x 10x 1740x 268x 268x 268x 10325x 10325x
import {Issue} from "../issue";
import {Position} from "../position";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import {IObject} from "../objects/_iobject";
import {Class} from "../objects";
import {IRuleMetadata, RuleTag} from "./_irule";
import {EditHelper} from "../edit_helper";
import {DDIC} from "../ddic";
import {ABAPFile} from "../abap/abap_file";
 
export class LineOnlyPuncConf extends BasicRuleConfig {
  /** Ignore lines with only puncutation in global exception classes */
  public ignoreExceptions: boolean = true;
}
 
export class LineOnlyPunc extends ABAPRule {
 
  private conf = new LineOnlyPuncConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "line_only_punc",
      title: "Line containing only punctuation",
      shortDescription: `Detects lines containing only punctuation.`,
      extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#close-brackets-at-line-end
https://docs.abapopenchecks.org/checks/16/`,
      tags: [RuleTag.Styleguide, RuleTag.Quickfix, RuleTag.SingleFile],
      badExample: "zcl_class=>method(\n).",
      goodExample: "zcl_class=>method( ).",
    };
  }
 
  private getMessage(): string {
    return "A line should not contain only \".\" or \").\"";
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: LineOnlyPuncConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile, obj: IObject) {
    const issues: Issue[] = [];
 
    const ddic = new DDIC(this.reg);
 
    if (obj instanceof Class) {
      const definition = obj.getClassDefinition();
      if (definition === undefined) {
        return [];
      } else if (this.conf.ignoreExceptions && ddic.isException(definition, obj)) {
        return [];
      }
    }
 
    const rows = file.getRawRows();
    const reg = new RegExp("^\\)?\\. *(\\\".*)?$");
 
    for (let i = 0; i < rows.length; i++) {
      if (reg.exec(rows[i].trim())) {
        const column = rows[i].indexOf(")") >= 0 ? rows[i].indexOf(")") + 1 : rows[i].indexOf(".") + 1;
        const position = new Position(i + 1, column);
 
        // merge punc into previous row
        let rowContent = rows[i].trim();
        // if reported row contains a paranthesis, prefix with space if needed
        if (rowContent.length > 1 && !rows[i - 1].endsWith(" ") && !rows[i - 1].endsWith(" \r")) {
          rowContent = " " + rowContent;
        }
        let offset = 0;
        if (rows[i - 1].endsWith("\r")) {
          offset = -1;
        }
        const startPos = new Position(i, rows[i - 1].length + 1 + offset);
        const endPos = new Position(i + 1, rows[i].length + 1);
        const fix = EditHelper.replaceRange(file, startPos, endPos, rowContent);
 
        const issue = Issue.atPosition(file, position, this.getMessage(), this.getMetadata().key, this.conf.severity, fix);
        issues.push(issue);
      }
    }
 
    return issues;
  }
 
}