All files / src/rules expand_macros.ts

100% Statements 88/88
100% Branches 18/18
100% Functions 5/5
100% Lines 88/88

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 891x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11011x 11011x 11011x 11011x 11011x 32887x 32887x 32887x 32887x 32887x 32887x 32887x 32887x 32887x 32887x 32887x 32887x 32887x 32887x 32887x 11011x 11011x 10487x 10487x 11011x 11011x 243x 243x 11011x 11011x 280x 280x 280x 280x 280x 1553x 1553x 1553x 1553x 1539x 1539x 14x 14x 1553x 18x 18x 12x 1x 1x 12x 2x 2x 11x 18x 6x 6x 18x 1553x 3x 3x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 280x 280x 280x 11011x 11011x  
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 {EditHelper} from "../edit_helper";
import {MacroCall} from "../abap/2_statements/statements/_statement";
import {VirtualPosition} from "../virtual_position";
 
export class ExpandMacrosConf extends BasicRuleConfig {
 
}
 
export class ExpandMacros extends ABAPRule {
 
  private conf = new ExpandMacrosConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "expand_macros",
      title: "Expand Macros",
      shortDescription: `Allows expanding macro calls with quick fixes`,
      extendedInformation: `Macros: https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-US/abenmacros_guidl.htm
 
Note that macros/DEFINE cannot be used in the ABAP Cloud programming model`,
      badExample: `DEFINE _hello.
  WRITE 'hello'.
END-OF-DEFINITION.
_hello.`,
      goodExample: `WRITE 'hello'.`,
      tags: [RuleTag.Styleguide, RuleTag.Quickfix, RuleTag.Upport],
    };
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: ExpandMacrosConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile) {
    const issues: Issue[] = [];
    const message = "Expand macro call";
 
    const statements = file.getStatements();
    for (let i = 0; i < statements.length; i++) {
      const statementNode = statements[i];
      const statement = statementNode.get();
 
      if (!(statement instanceof MacroCall)) {
        continue;
      }
 
      let replace = "";
      for (let j = i + 1; j < statements.length; j++) {
        const sub = statements[j];
        if (sub.getFirstToken().getStart() instanceof VirtualPosition) {
          if (sub.get() instanceof MacroCall) {
            continue;
          }
          if (replace !== "") {
            replace += "\n";
          }
          replace += sub.concatTokensVirtual();
        } else {
          break;
        }
      }
      if (statementNode.getColon()) {
        replace += "\n";
      }
 
      const fix1 = EditHelper.deleteStatement(file, statementNode);
      const fix2 = EditHelper.insertAt(file, statementNode.getStart(), replace);
      const fix = EditHelper.merge(fix1, fix2);
 
      issues.push(Issue.atStatement(file, statementNode, message, this.getMetadata().key, this.conf.severity, fix));
 
      // only one fix at a time per file
      break;
    }
 
    return issues;
  }
 
}