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 11009x 11009x 11009x 11009x 11009x 32887x 32887x 32887x 32887x 32887x 32887x 32887x 32887x 32887x 32887x 32887x 11009x 11009x 10493x 10493x 11009x 11009x 243x 243x 11009x 11009x 267x 267x 267x 1481x 1468x 1468x 13x 1481x 2x 2x 2x 2x 2x 1481x 267x 267x 267x 11009x 11009x 2x 2x 2x 2x 2x 4x 4x 4x 2x 2x 11009x 11009x  
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());
  }
 
}