Skip to content

Commit

Permalink
definitions_top, quick fix, #1477
Browse files Browse the repository at this point in the history
  • Loading branch information
larshp committed Oct 24, 2020
1 parent a0b0526 commit f85d83c
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 4 deletions.
20 changes: 18 additions & 2 deletions packages/core/src/rules/definitions_top.ts
Expand Up @@ -5,6 +5,8 @@ import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
import {EditHelper, IEdit} from "../edit_helper";
import {StatementNode} from "../abap/nodes/statement_node";

export class DefinitionsTopConf extends BasicRuleConfig {
}
Expand All @@ -25,7 +27,7 @@ export class DefinitionsTop extends ABAPRule {
title: "Place definitions in top of routine",
shortDescription: `Checks that definitions are placed at the beginning of methods.`,
extendedInformation: `https://docs.abapopenchecks.org/checks/17/`,
tags: [RuleTag.SingleFile],
tags: [RuleTag.SingleFile, RuleTag.Quickfix],
};
}

Expand All @@ -45,13 +47,15 @@ export class DefinitionsTop extends ABAPRule {
const issues: Issue[] = [];

let mode = ANY;
let start: StatementNode | undefined = undefined;
let issue: Issue | undefined = undefined;

// todo, this needs refactoring when the paser has become better
for (const statement of file.getStatements()) {
if (statement.get() instanceof Statements.Form
|| statement.get() instanceof Statements.Method) {
mode = DEFINITION;
start = statement;
issue = undefined;
} else if (statement.get() instanceof Comment) {
continue;
Expand All @@ -78,7 +82,8 @@ export class DefinitionsTop extends ABAPRule {
|| statement.get() instanceof Statements.StaticEnd
|| statement.get() instanceof Statements.FieldSymbol) {
if (mode === AFTER) {
issue = Issue.atStatement(file, statement, this.getMessage(), this.getMetadata().key, this.conf.severity);
const fix = issues.length === 0 && start ? this.buildFix(file, statement, start) : undefined;
issue = Issue.atStatement(file, statement, this.getMessage(), this.getMetadata().key, this.conf.severity, fix);
mode = ANY;
}
} else if (statement.get() instanceof Statements.Define
Expand All @@ -91,4 +96,15 @@ export class DefinitionsTop extends ABAPRule {

return issues;
}

//////////////////

private buildFix(file: ABAPFile, statement: StatementNode, start: StatementNode): IEdit {
const concat = statement.concatTokens();

const fix1 = EditHelper.deleteStatement(file, statement);
const fix2 = EditHelper.insertAt(file, start.getEnd(), "\n" + concat);

return EditHelper.merge(fix1, fix2);
}
}
38 changes: 36 additions & 2 deletions packages/core/test/rules/definitions_top.ts
@@ -1,5 +1,9 @@
import {DefinitionsTop} from "../../src/rules/definitions_top";
import {testRule} from "./_utils";
import {testRule, testRuleFixSingle} from "./_utils";

function testFix(input: string, expected: string) {
testRuleFixSingle(input, expected, new DefinitionsTop());
}

const tests = [
{
Expand Down Expand Up @@ -84,4 +88,34 @@ ENDFORM.`,

];

testRule(tests, DefinitionsTop);
testRule(tests, DefinitionsTop);


describe("Rule: definitions_top", () => {

it("quick fix 1", async () => {
const abap = `CLASS lcl_bar DEFINITION.
PUBLIC SECTION.
METHODS bar.
ENDCLASS.
CLASS lcl_bar IMPLEMENTATION.
METHOD bar.
WRITE 2.
DATA foo TYPE c.
ENDMETHOD.
ENDCLASS.`;
const expected = `CLASS lcl_bar DEFINITION.
PUBLIC SECTION.
METHODS bar.
ENDCLASS.
CLASS lcl_bar IMPLEMENTATION.
METHOD bar.
DATA foo TYPE c.
WRITE 2.
` + " " + `
ENDMETHOD.
ENDCLASS.`;
testFix(abap, expected);
});

});

0 comments on commit f85d83c

Please sign in to comment.