All files / src/rules unreachable_code.ts

98.23% Statements 111/113
94.11% Branches 48/51
100% Functions 8/8
98.23% Lines 111/113

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 113 1141x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11121x 11121x 11121x 11121x 33176x 33176x 33176x 33176x 33176x 33176x 33176x 33176x 33176x 11121x 11121x 9x 9x 11121x 11121x 10558x 10558x 11121x 11121x 266x 266x 11121x 11121x 287x 287x 287x 287x 1621x 1621x 1621x 22x 1621x 16x 16x 1599x 149x 149x 149x 1621x 9x 9x 9x 9x 1621x 287x 287x 287x 11121x 11121x 1599x 1599x 1599x   1599x 1x 1x 1x 1x   1599x 1598x 1598x 1598x 16x 16x 1582x 1582x 11121x 11121x 1583x 1583x 1583x 1583x 1583x 1583x 1583x 1583x 1583x 1583x 1583x 1583x 1583x 1583x 1583x 1583x 1583x 1583x 1583x 1583x 1583x 149x 149x 1434x 1434x 11121x 11121x  
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.EndTestSeam
        || 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;
  }
 
}