All files / src/rules space_before_dot.ts

100% Statements 99/99
100% Branches 28/28
100% Functions 7/7
100% Lines 99/99

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 92 93 94 95 96 97 98 991x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 22603x 22603x 22603x 22603x 1x 11302x 11302x 11302x 11302x 11302x 33780x 33780x 33780x 33780x 33780x 33780x 33780x 33780x 33780x 33780x 33780x 33780x 11302x 11302x 10x 10x 11302x 11302x 10807x 10807x 11302x 11302x 234x 234x 11302x 11302x 255x 255x 255x 255x 255x 12x 12x 12x 243x 243x 243x 255x 241x 241x 51x 51x 49x 49x 51x 51x 1x 1x 241x 20x 20x 20x 20x 20x 241x 242x 255x 5749x 1140x 1140x 4609x 5749x 10x 10x 10x 10x 10x 10x 4609x 4609x 242x 242x 242x 11302x 11302x
import {Issue} from "../issue";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import * as Statements from "../abap/2_statements/statements";
import {Class, Interface} from "../objects";
import {IObject} from "../objects/_iobject";
import {Punctuation} from "../abap/1_lexer/tokens";
import {AbstractToken} from "../abap/1_lexer/tokens/abstract_token";
import {Position} from "../position";
import {EditHelper} from "../edit_helper";
import {IRuleMetadata, RuleTag} from "./_irule";
import {DDIC} from "../ddic";
import {ABAPFile} from "../abap/abap_file";
 
export class SpaceBeforeDotConf extends BasicRuleConfig {
  public ignoreGlobalDefinition: boolean = true;
  public ignoreExceptions: boolean = true;
}
 
export class SpaceBeforeDot extends ABAPRule {
 
  private conf = new SpaceBeforeDotConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "space_before_dot",
      title: "Space before dot",
      shortDescription: `Checks for extra spaces before dots at the ends of statements`,
      extendedInformation: `
https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#be-consistent
https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#condense-your-code`,
      tags: [RuleTag.Whitespace, RuleTag.Quickfix, RuleTag.Styleguide, RuleTag.SingleFile],
      badExample: `WRITE bar .`,
      goodExample: `WRITE bar.`,
    };
  }
 
  private getMessage(): string {
    return "Remove space before \",\" or \".\"";
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: SpaceBeforeDotConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile, obj: IObject) {
    const issues: Issue[] = [];
    let prev: AbstractToken | undefined = undefined;
    let startRow = 0;
 
    if (file.getStructure() === undefined) {
      // some parser error exists in file
      return [];
    }
 
    const ddic = new DDIC(this.reg);
 
    if (this.conf.ignoreGlobalDefinition) {
      const structure = file.getStructure();
      if (obj instanceof Class && structure !== undefined) {
        const endclass = structure.findFirstStatement(Statements.EndClass);
        if (endclass !== undefined) {
          startRow = endclass.getFirstToken().getRow();
        }
        const definition = obj.getClassDefinition();
        if (definition !== undefined && this.conf.ignoreExceptions && ddic.isException(definition, obj)) {
          return [];
        }
      } else if (obj instanceof Interface && structure !== undefined) {
        const endinterface = structure.findFirstStatement(Statements.EndInterface);
        if (endinterface !== undefined) {
          startRow = endinterface.getFirstToken().getRow();
        }
      }
    }
 
    for (const t of file.getTokens()) {
      if (t.getRow() < startRow) {
        continue;
      }
 
      if (prev !== undefined && t instanceof Punctuation && prev.getCol() + prev.getStr().length < t.getCol()) {
        const start = new Position(t.getStart().getRow(), prev.getEnd().getCol());
        const end = new Position(t.getStart().getRow(), t.getStart().getCol());
        const fix = EditHelper.deleteRange(file, start, end);
        const issue = Issue.atRange(file, start, end, this.getMessage(), this.getMetadata().key, this.conf.severity, fix);
        issues.push(issue);
      }
      prev = t;
    }
 
    return issues;
  }
 
}