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 10503x 10503x 10503x 10503x 31337x 31337x 31337x 31337x 31337x 31337x 31337x 31337x 31337x 10503x 10503x 9x 9x 10503x 10503x 9970x 9970x 10503x 10503x 251x 251x 10503x 10503x 273x 273x 273x 273x 1532x 1532x 1532x 21x 1532x 16x 16x 1511x 139x 139x 139x 1532x 9x 9x 9x 9x 1532x 273x 273x 273x 10503x 10503x 1511x 1511x 1511x 1511x 1x 1x 1x 1x 1511x 1510x 1510x 1510x 16x 16x 1494x 1494x 10503x 10503x 1495x 1495x 1495x 1495x 1495x 1495x 1495x 1495x 1495x 1495x 1495x 1495x 1495x 1495x 1495x 1495x 1495x 1495x 1495x 1495x 1495x 139x 139x 1356x 1356x 10503x 10503x | 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; } } |