All files / src/rules reduce_string_templates.ts

93.4% Statements 85/91
83.33% Branches 20/24
100% Functions 5/5
93.4% Lines 85/91

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 911x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11457x 11457x 11457x 11457x 11457x 34211x 34211x 34211x 34211x 34211x 34211x 34211x 34211x 34211x 11457x 11457x 10925x 10925x 11457x 11457x 247x 247x 11457x 11457x 274x 274x 274x 274x 12x 12x 262x 274x 7x 4x 4x 1x 1x 4x 4x 1x 1x 3x 4x 2x 2x 2x 2x 3x 4x 7x 262x 274x 46x 46x 44x 46x   2x   2x     2x 2x 46x     2x 2x 2x 2x 2x 2x 2x 46x 262x 262x 262x 11457x 11457x
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));
          }
 
          if (ts.findDirectExpression(Expressions.StringTemplateFormatting)) {
            continue;
          }
 
          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;
  }
 
}