All files / src/rules check_comments.ts

97.82% Statements 90/92
92% Branches 23/25
100% Functions 7/7
97.82% Lines 90/92

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 921x 1x 1x 1x 1x 1x 1x 22557x 22557x 22557x 22557x 22557x 1x 1x 1x 1x 11278x 11278x 11278x 11278x 33690x 33690x 33690x 33690x 33690x 33690x 33690x 33690x 33690x 33690x 33690x 33690x 33690x 33690x 11278x 11278x 15x 15x 15x 15x 15x 11278x 11278x 11037x 11037x 11278x 11278x 245x 245x 11278x 11278x 255x 255x 255x 7x 7x 248x 248x 255x     248x 248x 255x 1663x 1663x 15x 15x 1663x 248x 255x 1406x 1406x 25x 25x 10x 10x 15x 15x 15x 15x 15x 15x 15x 25x 1x 1x 25x 1406x 248x 248x 11278x
import {Issue} from "../issue";
import {Comment} from "../abap/2_statements/statements/_statement";
import {BasicRuleConfig} from "./_basic_rule_config";
import {ABAPRule} from "./_abap_rule";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
 
export class CheckCommentsConf extends BasicRuleConfig {
  /** Allows the use of end-of-line comments. */
  public allowEndOfLine: boolean = false;
  public maxIssuesPerFile: number | undefined = 10;
}
 
enum IssueType {
  EndOfLine,
}
export class CheckComments extends ABAPRule {
  private conf = new CheckCommentsConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "check_comments",
      title: "Check Comments",
      shortDescription: `
Various checks for comment usage.`,
      extendedInformation: `
Detects end of line comments. Comments starting with "#EC" or "##" are ignored
 
https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#put-comments-before-the-statement-they-relate-to`,
      tags: [RuleTag.Styleguide, RuleTag.SingleFile],
      badExample: `WRITE 2. " descriptive comment`,
      goodExample: `" descriptive comment\nWRITE 2.`,
    };
  }
 
  private getDescription(issueType: IssueType): string {
    switch (issueType) {
      case IssueType.EndOfLine: return `Do not use end of line comments - move comment to previous row instead`;
      default: return "";
    }
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: CheckCommentsConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile): Issue[] {
    const issues: Issue[] = [];
    const rows = file.getRawRows();
    if (this.conf.allowEndOfLine === true) {
      return [];
    }
 
    let max = this.getConfig().maxIssuesPerFile;
    if (max === undefined || max < 1) {
      max = 10;
    }
 
    const commentRows: number[] = [];
    for (let i = 0; i < rows.length; i++) {
      const row = rows[i];
      if (row.trim().startsWith("*") || row.trim().startsWith(`"`)) {
        commentRows.push(i);
      }
    }
    const statements = file.getStatements();
    for (let i = statements.length - 1; i >= 0; i--) {
      const statement = statements[i];
      if (statement.get() instanceof Comment && !commentRows.includes(statement.getStart().getRow() - 1)) {
        if (statement.getFirstToken().getStr().startsWith(`"#EC`)
            || statement.getFirstToken().getStr().startsWith(`"##`)) {
          continue;
        }
        issues.push(
          Issue.atStatement(
            file,
            statement,
            this.getDescription(IssueType.EndOfLine),
            this.getMetadata().key,
            this.conf.severity));
        if (issues.length >= max) {
          break;
        }
      }
    }
    return issues;
  }
}