All files / src/rules unreachable_code.ts

98.21% Statements 110/112
94% Branches 47/50
100% Functions 8/8
98.21% Lines 110/112

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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 1131x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 9361x 9361x 9361x 9361x 27932x 27932x 27932x 27932x 27932x 27932x 27932x 27932x 27932x 9361x 9361x 9x 9x 9361x 9361x 8898x 8898x 9361x 9361x 216x 216x 9361x 9361x 241x 241x 241x 241x 1380x 1380x 1380x 21x 1380x 15x 15x 1359x 127x 127x 127x 1380x 9x 9x 9x 9x 1380x 241x 241x 241x 9361x 9361x 1359x 1359x 1359x   1359x 1x 1x 1x 1x   1359x 1358x 1358x 1358x 15x 15x 1343x 1343x 9361x 9361x 1344x 1344x 1344x 1344x 1344x 1344x 1344x 1344x 1344x 1344x 1344x 1344x 1344x 1344x 1344x 1344x 1344x 1344x 1344x 1344x 127x 127x 1217x 1217x 9361x 9361x  
import {Issue} from "../issue";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import {IStatement, Comment, MacroContent, Empty} from "../abap/2_statements/statements/_statement";
import * as Statements from "../abap/2_statements/statements";
import * as Expressions from "../abap/2_statements/expressions";
import {StatementNode} from "../abap/nodes";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
 
export class UnreachableCodeConf extends BasicRuleConfig {
}
 
export class UnreachableCode extends ABAPRule {
  private conf = new UnreachableCodeConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "unreachable_code",
      title: "Unreachable code",
      shortDescription: `Checks for unreachable code.`,
      tags: [RuleTag.SingleFile],
      badExample: `RETURN.\nWRITE 'hello'.`,
      goodExample: `WRITE 'hello'.\nRETURN.`,
    };
  }
 
  private getMessage(): string {
    return "Unreachable code";
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: UnreachableCodeConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile) {
    const output: Issue[] = [];
    let exit = false;
 
    for (const node of file.getStatements()) {
      if (node.get() instanceof Comment
          || node.get() instanceof MacroContent
          || node.get() instanceof Empty) {
        continue;
      } else if (this.isExit(node)) {
        exit = true;
        continue;
      } else if (this.isStructure(node.get())) {
        exit = false;
        continue;
      }
      if (exit === true) {
        const issue = Issue.atStatement(file, node, this.getMessage(), this.getMetadata().key, this.conf.severity);
        output.push(issue);
        exit = false;
      }
    }
 
    return output;
  }
 
  private isExit(n: StatementNode): boolean {
    const s = n.get();
    // todo, RESUMABLE exception
    if (s instanceof Statements.Submit && n.findFirstExpression(Expressions.AndReturn) === undefined) {
      return true;
    } else if (s instanceof Statements.Leave && n.findFirstExpression(Expressions.AndReturn) === undefined) {
      const concat = n.concatTokens();
      if (concat.includes(" TO LIST-PROCESSING")) {
        return false;
      }
      return true;
    } else if (s instanceof Statements.Return
        || s instanceof Statements.Continue
        || s instanceof Statements.Exit
        || s instanceof Statements.Raise) {
      return true;
    }
    return false;
  }
 
  private isStructure(s: IStatement): boolean {
    if (s instanceof Statements.EndIf
        || s instanceof Statements.Else
        || s instanceof Statements.EndLoop
        || s instanceof Statements.EndTry
        || s instanceof Statements.EndMethod
        || s instanceof Statements.EndModule
        || s instanceof Statements.EndForm
        || s instanceof Statements.EndAt
        || s instanceof Statements.EndSelect
        || s instanceof Statements.AtSelectionScreen
        || s instanceof Statements.EndFunction
        || s instanceof Statements.EndCase
        || s instanceof Statements.EndWhile
        || s instanceof Statements.EndDo
        || s instanceof Statements.Cleanup
        || s instanceof Statements.When
        || s instanceof Statements.WhenOthers
        || s instanceof Statements.WhenType
        || s instanceof Statements.Catch
        || s instanceof Statements.ElseIf) {
      return true;
    }
    return false;
  }
 
}