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 114 115 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11712x 11712x 11712x 11712x 46175x 46175x 46175x 46175x 46175x 46175x 46175x 46175x 46175x 11712x 11712x 3x 3x 11712x 11712x 11175x 11175x 11712x 11712x 253x 253x 11712x 11712x 283x 283x 283x 283x 1604x 1604x 1604x 32x 1604x 89x 89x 89x 1604x 3x 3x 3x 3x 1604x 7x 7x 7x 1604x 283x 283x 283x 11712x 11712x 1480x 1480x 1480x 1480x 1x 1x 1x 1x 1480x 1479x 1479x 1479x 7x 7x 1472x 1472x 11712x 11712x 1572x 1572x 1572x 1572x 1572x 1572x 1572x 1572x 1572x 1572x 1572x 1572x 1572x 1572x 1572x 1572x 1572x 1572x 1572x 1572x 1572x 89x 89x 1483x 1483x 11712x 11712x | 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.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;
continue;
} else if (this.isExit(node)) {
exit = true;
continue;
}
}
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;
}
}
|