All files / src/rules no_chained_assignment.ts

100% Statements 70/70
100% Branches 11/11
100% Functions 6/6
100% Lines 70/70

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 711x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 13676x 13676x 13676x 13676x 13676x 40873x 40873x 40873x 40873x 40873x 40873x 40873x 40873x 40873x 40873x 40873x 13676x 13676x 13166x 13166x 13676x 13676x 240x 240x 13676x 13676x 255x 255x 255x 1436x 1423x 1423x 13x 1436x 2x 2x 2x 2x 2x 1436x 255x 255x 255x 13676x 13676x 2x 2x 2x 2x 2x 4x 4x 4x 2x 2x 13676x 13676x  
import * as Expressions from "../abap/2_statements/expressions";
import * as Statements from "../abap/2_statements/statements";
import {Issue} from "../issue";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
import {StatementNode} from "../abap/nodes";
import {EditHelper, IEdit} from "../edit_helper";
 
export class NoChainedAssignmentConf extends BasicRuleConfig {
}
 
export class NoChainedAssignment extends ABAPRule {
 
  private conf = new NoChainedAssignmentConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "no_chained_assignment",
      title: "No chained assignment",
      shortDescription: `Find chained assingments and reports issues`,
      extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#dont-chain-assignments`,
      tags: [RuleTag.SingleFile, RuleTag.Styleguide, RuleTag.Quickfix],
      badExample: `var1 = var2 = var3.`,
      goodExample: `var2 = var3.
var1 = var2.`,
    };
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: NoChainedAssignmentConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile) {
    const issues: Issue[] = [];
 
    for (const s of file.getStatements()) {
      if (!(s.get() instanceof Statements.Move)) {
        continue;
      }
 
      if (s.findDirectExpressions(Expressions.Target).length >= 2) {
        const message = "No chained assignment";
        const fix = this.buildFix(file, s);
        const issue = Issue.atStatement(file, s, message, this.getMetadata().key, this.getConfig().severity, fix);
        issues.push(issue);
      }
    }
 
    return issues;
  }
 
  private buildFix(file: ABAPFile, node: StatementNode): IEdit | undefined{
    // window of 3 expressions
    const children = node.getChildren();
    let res = "";
 
    for (let i = children.length - 4; i >= 0 ; i = i - 2) {
      const concat = children[i].concatTokens() + " " + children[i + 1].concatTokens() + " " + children[i + 2].concatTokens();
      res += concat + ".\n";
    }
    return EditHelper.replaceRange(file, node.getStart(), node.getEnd(), res.trimEnd());
  }
 
}