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 11215x 11215x 11215x 11215x 33490x 33490x 33490x 33490x 33490x 33490x 33490x 33490x 33490x 11215x 11215x 2x 2x 11215x 11215x 10730x 10730x 11215x 11215x 227x 227x 11215x 11215x 248x 248x 248x 248x 1402x 1402x 1402x 21x 1402x 6x 6x 1381x 72x 72x 72x 1402x 2x 2x 2x 2x 1402x 248x 248x 248x 11215x 11215x 1381x 1381x 1381x 1381x 1x 1x 1x 1x 1381x 1380x 1380x 1380x 6x 6x 1374x 1374x 11215x 11215x 1375x 1375x 1375x 1375x 1375x 1375x 1375x 1375x 1375x 1375x 1375x 1375x 1375x 1375x 1375x 1375x 1375x 1375x 1375x 1375x 1375x 72x 72x 1303x 1303x 11215x 11215x | 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; } } |