All files / src/rules unreachable_code.ts

95.24% Statements 40/42
93.62% Branches 44/47
100% Functions 8/8
95.24% Lines 40/42

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 1101x 1x 1x 1x 1x 1x   1x     1x     1x 7272x     21682x                     2x       7015x       114x       137x 137x   137x 756x     2x 754x 5x 5x 749x 45x 45x   704x 2x 2x 2x 2x       137x       754x   754x   754x   754x       5x   749x       749x                                       45x   704x        
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 token = node.getFirstToken();
        const issue = Issue.atToken(file, token, 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
    Iif (s instanceof Statements.Submit && n.findFirstExpression(Expressions.AndReturn) === undefined) {
      return true;
    } else Iif (s instanceof Statements.Leave && n.findFirstExpression(Expressions.AndReturn) === undefined) {
      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;
  }
 
}