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 22903x 22903x 22903x 22903x 1x 11452x 11452x 11452x 11452x 11452x 34243x 34243x 34243x 34243x 34243x 34243x 34243x 34243x 34243x 34243x 34243x 34243x 11452x 11452x 10x 10x 11452x 11452x 10927x 10927x 11452x 11452x 249x 249x 11452x 11452x 279x 279x 279x 279x 279x 12x 12x 12x 267x 267x 267x 279x 265x 265x 51x 51x 49x 49x 51x 51x 1x 1x 265x 20x 20x 20x 20x 20x 265x 266x 279x 6372x 1140x 1140x 5232x 6372x 10x 10x 10x 10x 10x 10x 5232x 5232x 266x 266x 266x 11452x 11452x
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;
  }
 
}