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 10995x 10995x 10995x 10995x 32804x 32804x 32804x 32804x 32804x 32804x 32804x 32804x 32804x 10995x 10995x 9x 9x 10995x 10995x 10444x 10444x 10995x 10995x 260x 260x 10995x 10995x 281x 281x 281x 281x 1575x 1575x 1575x 22x 1575x 16x 16x 1553x 146x 146x 146x 1575x 9x 9x 9x 9x 1575x 281x 281x 281x 10995x 10995x 1553x 1553x 1553x 1553x 1x 1x 1x 1x 1553x 1552x 1552x 1552x 16x 16x 1536x 1536x 10995x 10995x 1537x 1537x 1537x 1537x 1537x 1537x 1537x 1537x 1537x 1537x 1537x 1537x 1537x 1537x 1537x 1537x 1537x 1537x 1537x 1537x 1537x 146x 146x 1391x 1391x 10995x 10995x | 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; } } |