All files / src/rules unnecessary_return.ts

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

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 841x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 10347x 10347x 10347x 10347x 30858x 30858x 30858x 30858x 30858x 30858x 30858x 30858x 30858x 30858x 30858x 30858x 30858x 30858x 30858x 30858x 30858x 30858x 30858x 30858x 30858x 10347x 10347x 9833x 9833x 10347x 10347x 241x 241x 10347x 10347x 259x 259x 259x 259x 12x 12x 247x 247x 247x 247x 259x 1446x 1446x 1446x 1446x 1362x 1362x 84x 84x 1446x 3x 3x 3x 84x 84x 84x 84x 1446x 1446x 1x 1x 1x 1446x 247x 247x 247x 10347x 10347x
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 * as Statements from "../abap/2_statements/statements";
import {EditHelper} from "../edit_helper";
 
export class UnnecessaryReturnConf extends BasicRuleConfig {
}
 
export class UnnecessaryReturn extends ABAPRule {
  private conf = new UnnecessaryReturnConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "unnecessary_return",
      title: "Unnecessary Return",
      shortDescription: `Finds unnecessary RETURN statements`,
      extendedInformation: `Finds unnecessary RETURN statements`,
      tags: [RuleTag.SingleFile, RuleTag.Quickfix],
      badExample: `FORM hello1.
  WRITE 'world'.
  RETURN.
ENDFORM.
 
FORM foo.
  IF 1 = 2.
    RETURN.
  ENDIF.
ENDFORM.`,
      goodExample: `FORM hello2.
  WRITE 'world'.
ENDFORM.`,
    };
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: UnnecessaryReturnConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile) {
    const issues: Issue[] = [];
 
    const structure = file.getStructure();
    if (structure === undefined) {
      return [];
    }
 
    const message = "Unnecessary RETURN";
 
    const statements = file.getStatements();
    for (let i = 0; i < statements.length; i++) {
      const node = statements[i];
      if (!(node.get() instanceof Statements.EndMethod
          || node.get() instanceof Statements.EndForm
          || node.get() instanceof Statements.EndFunction)) {
        continue;
      }
 
      const prev = statements[i - 1];
      if (prev && prev.get() instanceof Statements.Return) {
        const fix = EditHelper.deleteStatement(file, prev);
        issues.push(Issue.atStatement(file, prev, message, this.getMetadata().key, this.getConfig().severity, fix));
      }
 
      // note: ENDTRY is not checked, it will usually just make it an empty catch handler, which is also bad
      const prevprev = statements[i - 2];
      if (prev && prevprev
          && prevprev.get() instanceof Statements.Return
          && prev.get() instanceof Statements.EndIf) {
        const fix = EditHelper.deleteStatement(file, prevprev);
        issues.push(Issue.atStatement(file, prevprev, message, this.getMetadata().key, this.getConfig().severity, fix));
      }
    }
 
    return issues;
  }
 
}