All files / src/rules start_at_tab.ts

97.43% Statements 76/78
95.45% Branches 21/22
100% Functions 6/6
97.43% Lines 76/78

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 781x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11087x 11087x 11087x 11087x 11087x 33124x 33124x 33124x 33124x 33124x 33124x 33124x 33124x 33124x 33124x 33124x 11087x 11087x 3x 3x 11087x 11087x 10568x 10568x 11087x 11087x 244x 244x 11087x 11087x 270x 270x 270x 270x 270x 270x 270x 1489x 24x 1489x 33x 1465x 33x 1432x 50x 50x 1415x 1415x 1489x 81x 81x 1334x 1489x 3x 3x 3x     3x 1334x 1334x 270x 270x 270x 11087x 11087x
import {Issue} from "../issue";
import {Position} from "../position";
import {Comment} from "../abap/2_statements/statements/_statement";
import {TypeBegin, TypeEnd} from "../abap/2_statements/statements";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
 
export class StartAtTabConf extends BasicRuleConfig {
}
 
export class StartAtTab extends ABAPRule {
 
  private conf = new StartAtTabConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "start_at_tab",
      title: "Start at tab",
      shortDescription: `Checks that statements start at tabstops.`,
      extendedInformation: `Reports max 100 issues per file
https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#indent-and-snap-to-tab`,
      tags: [RuleTag.Whitespace, RuleTag.Styleguide, RuleTag.SingleFile],
      badExample: ` WRITE a.`,
      goodExample: `  WRITE a.`,
    };
  }
 
  private getMessage(): string {
    return "Start statement at tab position";
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: StartAtTabConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile) {
    const issues: Issue[] = [];
 
    let inType = false;
    let previous: Position | undefined = undefined;
    const raw = file.getRawRows();
 
    for (const statement of file.getStatements()) {
      if (statement.get() instanceof Comment) {
        continue;
      } else if (statement.get() instanceof TypeBegin) {
        inType = true;
      } else if (statement.get() instanceof TypeEnd) {
        inType = false;
      } else if (inType) {
        continue;
      }
 
      const pos = statement.getStart();
      if (previous !== undefined && pos.getRow() === previous.getRow()) {
        continue;
      }
// just skip rows that contains tabs, this will be reported by the contains_tab rule
      if ((pos.getCol() - 1) % 2 !== 0 && raw[pos.getRow() - 1].includes("\t") === false) {
        const issue = Issue.atPosition(file, pos, this.getMessage(), this.getMetadata().key, this.conf.severity);
        issues.push(issue);
        if (issues.length >= 100) {
          return issues; // only max 100 issues perfile
        }
      }
      previous = pos;
    }
 
    return issues;
  }
 
}