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 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 29373x 29373x 29373x 29373x 29373x 29373x 29373x 29373x 29373x 29373x 1x 14688x 14688x 14688x 14688x 43925x 43925x 43925x 43925x 43925x 43925x 43925x 14688x 14688x 17x 17x 17x 17x 17x 17x 14688x 14688x 14120x 14120x 14688x 14688x 285x 285x 14688x 14688x 318x 318x 318x 5x 5x 318x 1917x 1917x 1885x 1885x 32x 1917x 52x 52x 52x 1917x 1917x 1917x 17x 17x 17x 17x 17x 17x 17x 17x 17x 1917x 313x 313x 14688x 14688x 17x 17x 10x 10x 17x 17x 8x 8x 17x 9x 9x 9x 9x 14688x 14688x 318x 5x 318x 313x 313x 318x 14688x | import {Issue} from "../issue";
import {BasicRuleConfig} from "./_basic_rule_config";
import {ABAPRule} from "./_abap_rule";
import {SequentialBlank} from "./sequential_blank";
import * as Statements from "../abap/2_statements/statements";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
import {EditHelper, IEdit} from "../edit_helper";
import {Position} from "../position";
export enum NewlineLogic {
Exact = "exact",
Less = "less",
}
export class NewlineBetweenMethodsConf extends BasicRuleConfig {
/** Amount of newlines, works in conjunction with "newlineLogic" */
public count: number = 3;
/**
* Exact: the exact number of required newlines between methods is defined by "newlineAmount"
*
* Less: the required number of newlines has to be less than "newlineAmount"
*/
public logic: NewlineLogic = NewlineLogic.Less;
}
export class NewlineBetweenMethods extends ABAPRule {
private conf = new NewlineBetweenMethodsConf();
public getMetadata(): IRuleMetadata {
return {
key: "newline_between_methods",
title: "New line between methods",
shortDescription: `Checks for newlines between method implementations.`,
tags: [RuleTag.Whitespace, RuleTag.Quickfix, RuleTag.SingleFile],
};
}
private getMessage(): string {
switch (this.conf.logic) {
case NewlineLogic.Exact: return `Exactly ${this.conf.count} newlines are required in between methods`;
case NewlineLogic.Less: return `Less than ${this.conf.count} newlines and at least a single newline are required in between methods`;
default: return "";
}
}
public getConfig() {
return this.conf;
}
public setConfig(conf: NewlineBetweenMethodsConf) {
this.conf = conf;
}
public runParsed(file: ABAPFile): Issue[] {
const issues: Issue[] = [];
const rows = file.getRawRows();
if (!this.isConfigurationValid()) {
return [];
}
for (const statement of file.getStatements()) {
let nextRow = statement.getStart().getRow();
if (!(statement.get() instanceof Statements.EndMethod) || rows[nextRow]?.toUpperCase().includes("ENDCLASS.")) {
continue;
}
let counter = 0;
while (SequentialBlank.isBlankOrWhitespace(rows[nextRow])) {
counter++;
nextRow++;
}
if ((counter !== this.conf.count && this.conf.logic === NewlineLogic.Exact)
|| (counter >= this.conf.count && this.conf.logic === NewlineLogic.Less)
|| counter === 0) {
const fix = this.buildFix(file, rows, statement.getStart().getRow(), counter);
issues.push(Issue.atStatement(
file,
statement,
this.getMessage(),
this.getMetadata().key,
this.conf.severity,
fix));
}
}
return issues;
}
private buildFix(file: ABAPFile, rows: string[], row: number, blanks: number): IEdit | undefined {
let target = this.conf.count;
if (this.conf.logic === NewlineLogic.Less) {
target = blanks === 0 ? 1 : this.conf.count - 1;
}
if (blanks < target) {
const end = new Position(row, rows[row - 1].length + 1);
return EditHelper.insertAt(file, end, "\n".repeat(target - blanks));
} else if (blanks > target) {
const start = new Position(row + target, rows[row + target - 1].length + 1);
const end = new Position(row + blanks, rows[row + blanks - 1].length + 1);
return EditHelper.deleteRange(file, start, end);
}
return undefined;
}
private isConfigurationValid(): boolean {
if (this.conf.count < 1 || (this.conf.count === 1 && this.conf.logic === NewlineLogic.Less)) {
return false;
} else {
return true;
}
}
} |