All files / src/rules prefer_abap_bool.ts

100% Statements 75/75
100% Branches 13/13
100% Functions 5/5
100% Lines 75/75

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 761x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 14683x 14683x 14683x 14683x 142765x 142765x 142765x 142765x 142765x 142765x 142765x 142765x 142765x 142765x 142765x 14683x 14683x 14120x 14120x 14683x 14683x 264x 264x 14683x 14683x 320x 320x 320x 12x 12x 308x 308x 308x 308x 308x 308x 308x 308x 308x 320x 296x 296x 24x 24x 272x 272x 296x 256x 256x 16x 16x 16x 16x 16x 16x 16x 16x 308x 308x 308x 14683x  
import {Issue} from "../issue";
import {ABAPRule} from "./_abap_rule";
import * as Expressions from "../abap/2_statements/expressions";
import * as Statements from "../abap/2_statements/statements";
import {BasicRuleConfig} from "./_basic_rule_config";
import {IRuleMetadata, RuleTag} from "./_irule";
import {EditHelper} from "../edit_helper";
import {ABAPFile} from "../abap/abap_file";
 
const FORBIDDEN_TYPES = new Set(["XFELD", "SAP_BOOL", "BOOLE_D", "FLAG"]);
 
export class PreferAbapBoolConf extends BasicRuleConfig {
}
 
export class PreferAbapBool extends ABAPRule {
  private conf = new PreferAbapBoolConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "prefer_abap_bool",
      title: "Prefer abap_bool",
      shortDescription: `Use abap_bool instead of XFELD, SAP_BOOL, BOOLE_D, FLAG for boolean variables`,
      extendedInformation:
        `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#use-abap_bool-for-booleans`,
      tags: [RuleTag.Styleguide, RuleTag.SingleFile, RuleTag.Quickfix],
      badExample: `DATA foo TYPE xfeld.`,
      goodExample: `DATA foo TYPE abap_bool.`,
    };
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: PreferAbapBoolConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile): Issue[] {
    const issues: Issue[] = [];
    const structure = file.getStructure();
    if (structure === undefined) {
      return [];
    }
 
    const statements = [
      ...structure.findAllStatements(Statements.Data),
      ...structure.findAllStatements(Statements.ClassData),
      ...structure.findAllStatements(Statements.Constant),
      ...structure.findAllStatements(Statements.Type),
      ...structure.findAllStatements(Statements.FieldSymbol),
    ];
 
    for (const stat of statements) {
      const typeNameExpr = stat.findFirstExpression(Expressions.TypeName);
      if (typeNameExpr === undefined) {
        continue;
      }
 
      const typeName = typeNameExpr.concatTokens().toUpperCase();
      if (FORBIDDEN_TYPES.has(typeName) === false) {
        continue;
      }
 
      const token = typeNameExpr.getFirstToken();
      const fix = EditHelper.replaceToken(file, token, "abap_bool");
      issues.push(Issue.atToken(
        file, token,
        `Use abap_bool instead of ${typeName}`,
        this.getMetadata().key, this.conf.severity, fix));
    }
 
    return issues;
  }
}