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 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11057x 11057x 11057x 11057x 32989x 32989x 32989x 32989x 32989x 32989x 32989x 32989x 32989x 11057x 11057x 9x 9x 11057x 11057x 10504x 10504x 11057x 11057x 261x 261x 11057x 11057x 282x 282x 282x 282x 1576x 1576x 1576x 22x 1576x 16x 16x 1554x 146x 146x 146x 1576x 9x 9x 9x 9x 1576x 282x 282x 282x 11057x 11057x 1554x 1554x 1554x 1554x 1x 1x 1x 1x 1554x 1553x 1553x 1553x 16x 16x 1537x 1537x 11057x 11057x 1538x 1538x 1538x 1538x 1538x 1538x 1538x 1538x 1538x 1538x 1538x 1538x 1538x 1538x 1538x 1538x 1538x 1538x 1538x 1538x 1538x 146x 146x 1392x 1392x 11057x 11057x | 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; } } |