All files / src/rules unreachable_code.ts

98.15% Statements 106/108
93.75% Branches 45/48
100% Functions 8/8
98.15% Lines 106/108

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 1091x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 7653x 7653x 7653x 7653x 22818x 22818x 22818x 22818x 22818x 22818x 22818x 22818x 22818x 7653x 7653x 4x 4x 7653x 7653x 7346x 7346x 7653x 7653x 139x 139x 7653x 7653x 158x 158x 158x 158x 869x 869x 869x 2x 869x 7x 7x 867x 70x 70x 70x 869x 4x 4x 4x 4x 869x 158x 158x 158x 7653x 7653x 867x 867x 867x   867x   867x 867x 867x 867x 7x 7x 860x 860x 7653x 7653x 860x 860x 860x 860x 860x 860x 860x 860x 860x 860x 860x 860x 860x 860x 860x 860x 860x 860x 860x 860x 70x 70x 790x 790x 7653x 7653x  
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) {
      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;
  }
 
}