All files / src/rules colon_missing_space.ts

100% Statements 73/73
100% Branches 20/20
100% Functions 6/6
100% Lines 73/73

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 731x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11402x 11402x 11402x 11402x 11402x 99327x 99327x 99327x 99327x 99327x 99327x 99327x 99327x 99327x 11402x 11402x 2x 2x 11402x 11402x 10877x 10877x 11402x 11402x 247x 247x 11402x 11402x 272x 272x 272x 1544x 1544x 1544x 1544x 1354x 1354x 190x 190x 190x 190x 190x 190x 1544x 1288x 1288x 1288x 1288x 1288x 2x 2x 2x 2x 2x 2x 1288x 190x 272x 272x 272x 11402x
import {Issue} from "../issue";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import {Position} from "../position";
import {EditHelper} from "../edit_helper";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
import {Comment, NativeSQL} from "../abap/2_statements/statements/_statement";
 
export class ColonMissingSpaceConf extends BasicRuleConfig {
}
 
export class ColonMissingSpace extends ABAPRule {
 
  private conf = new ColonMissingSpaceConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "colon_missing_space",
      title: "Colon missing space",
      shortDescription: `Checks for missing spaces after colons in chained statements.`,
      tags: [RuleTag.Whitespace, RuleTag.Quickfix, RuleTag.SingleFile],
      badExample: `WRITE:hello, world.`,
      goodExample: `WRITE: hello, world.`,
    };
  }
 
  private getMessage(): string {
    return "Missing space after the colon";
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: ColonMissingSpaceConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile) {
    const issues: Issue[] = [];
 
    for (const statement of file.getStatements()) {
      const colon = statement.getColon();
      if (colon === undefined
          || statement.get() instanceof NativeSQL
          || statement.get() instanceof Comment) {
        continue;
      }
 
      // todo: this can be more smart, performance wise
      const tokens = [...statement.getTokens()];
      tokens.push(colon);
      tokens.sort((a, b) => a.getStart().isAfter(b.getStart()) ? 1 : -1);
 
      for (let i = 0; i < tokens.length; i++) {
        const token = tokens[i];
        if (token.getStr() === ":"
            && tokens[i + 1] !== undefined
            && tokens[i + 1].getRow() === token.getRow()
            && tokens[i + 1].getCol() === token.getCol() + 1) {
          const start = token.getStart();
          const end = new Position(start.getRow(), start.getCol() + 1);
          const fix = EditHelper.insertAt(file, end, " ");
          const issue = Issue.atRange(file, start, end, this.getMessage(), this.getMetadata().key, this.conf.severity, fix);
          issues.push(issue);
        }
      }
    }
 
    return issues;
  }
}