All files / src/rules reduce_string_templates.ts

93.1% Statements 81/87
80.95% Branches 17/21
100% Functions 5/5
93.1% Lines 81/87

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 871x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 8928x 8928x 8928x 8928x 8928x 35097x 35097x 35097x 35097x 35097x 35097x 35097x 35097x 35097x 8928x 8928x 8485x 8485x 8928x 8928x 202x 202x 8928x 8928x 220x 220x 220x 220x 12x 12x 208x 220x 6x 3x 3x 1x 1x 3x 3x 2x 2x 2x 2x 3x 3x 6x 208x 220x 105x 105x 103x 105x   2x   2x     2x 2x 105x     2x 2x 2x 2x 2x 2x 2x 105x 208x 208x 208x 8928x 8928x
import * as Expressions from "../abap/2_statements/expressions";
import {Issue} from "../issue";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import {IObject} from "../objects/_iobject";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
 
export class ReduceStringTemplatesConf extends BasicRuleConfig {
}
 
export class ReduceStringTemplates extends ABAPRule {
 
  private conf = new ReduceStringTemplatesConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "reduce_string_templates",
      title: "Reduce string templates",
      shortDescription: `Checks for string templates`,
      tags: [RuleTag.SingleFile],
      badExample: `WRITE |{ |sdf| }|.\nWRITE |{ 'sdf' }|.`,
      goodExample: `WRITE |sdf|.`,
    };
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: ReduceStringTemplatesConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile, _obj: IObject) {
    const issues: Issue[] = [];
 
    const structure = file.getStructure();
    if (structure === undefined) {
      return [];
    }
 
    for (const template of structure.findAllExpressions(Expressions.StringTemplate)) {
      for (const ts of template.findAllExpressions(Expressions.StringTemplateSource)) {
        for (const source of ts.findDirectExpressions(Expressions.Source)) {
          for (const second of source.findDirectExpressions(Expressions.StringTemplate)) {
            issues.push(Issue.atToken(file, second.getFirstToken(), "Nested string templates, reduce", this.getMetadata().key, this.conf.severity));
          }
 
          for (const constant of source.findDirectExpressions(Expressions.Constant)) {
            for (const constantString of constant.findDirectExpressions(Expressions.ConstantString)) {
              issues.push(Issue.atToken(file, constantString.getFirstToken(), "Constant string in text template, reduce", this.getMetadata().key, this.conf.severity));
            }
          }
        }
      }
    }
 
    for (const source of structure.findAllExpressions(Expressions.Source)) {
      const children = source.getChildren();
      if (children.length !== 3) {
        continue;
      } else if (!(children[0].get() instanceof Expressions.StringTemplate)) {
        continue;
      } else if (children[1].getFirstToken().getStr() !== "&&") {
        continue;
      } else if (!(children[2].get() instanceof Expressions.Source)) {
        continue;
      }
 
      const sub = children[2].getChildren();
      if (sub.length !== 1) {
        continue;
      }
 
      const start = children[0].getFirstToken().getStart();
      const end = sub[0].getLastToken().getEnd();
      if (start.getRow() === end.getRow()) {
        const message = "Reduce template, remove \"&&\"";
        issues.push(Issue.atToken(file, children[1].getFirstToken(), message, this.getMetadata().key, this.conf.severity));
      }
    }
 
    return issues;
  }
 
}