From 5c33e91d00848f49ce09cbca3d0f9ea9020b2f3b Mon Sep 17 00:00:00 2001 From: Lars Hvam Date: Sat, 24 Oct 2020 12:50:09 +0200 Subject: [PATCH] 2.58.12, definitions_top, quick fix (#1486) * definitions_top, quick fix, #1477 * 2.58.12 --- packages/cli/package-lock.json | 8 ++--- packages/cli/package.json | 4 +-- packages/core/package-lock.json | 2 +- packages/core/package.json | 2 +- packages/core/scripts/schema.json | 2 +- packages/core/src/rules/definitions_top.ts | 20 +++++++++-- packages/core/test/rules/definitions_top.ts | 38 +++++++++++++++++++-- packages/monaco/package-lock.json | 8 ++--- packages/monaco/package.json | 4 +-- web/playground/package-lock.json | 14 ++++---- web/playground/package.json | 2 +- 11 files changed, 77 insertions(+), 27 deletions(-) diff --git a/packages/cli/package-lock.json b/packages/cli/package-lock.json index fe7f39f89a..ca06de428e 100644 --- a/packages/cli/package-lock.json +++ b/packages/cli/package-lock.json @@ -1,13 +1,13 @@ { "name": "@abaplint/cli", - "version": "2.58.11", + "version": "2.58.12", "lockfileVersion": 1, "requires": true, "dependencies": { "@abaplint/core": { - "version": "2.58.11", - "resolved": "https://registry.npmjs.org/@abaplint/core/-/core-2.58.11.tgz", - "integrity": "sha512-+ykt8pIJyO2GFRFGBPNbY6z3baf8KPvgJMKUS4ItLTc4zzVwavwnwKdk4maY5m7f2J3xfCmYndpcmd9s1q+dyQ==", + "version": "2.58.12", + "resolved": "https://registry.npmjs.org/@abaplint/core/-/core-2.58.12.tgz", + "integrity": "sha512-PztA8oMGiUjI9jzVJZa9eyZmzOwD04NLWBeP3IVBjRg7+uP71zm+73zqrHyUIrsEbEjvZMwSdz4usyMi+TCQ7Q==", "dev": true, "requires": { "json5": "^2.1.3", diff --git a/packages/cli/package.json b/packages/cli/package.json index 9bede715ec..e7dcf7e5ee 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@abaplint/cli", - "version": "2.58.11", + "version": "2.58.12", "description": "abaplint - Command Line Interface", "bin": { "abaplint": "./abaplint" @@ -38,7 +38,7 @@ }, "homepage": "https://abaplint.org", "devDependencies": { - "@abaplint/core": "^2.58.11", + "@abaplint/core": "^2.58.12", "@types/chai": "^4.2.14", "@types/glob": "^7.1.3", "@types/minimist": "^1.2.0", diff --git a/packages/core/package-lock.json b/packages/core/package-lock.json index 37ded4e2f6..53886d6afc 100644 --- a/packages/core/package-lock.json +++ b/packages/core/package-lock.json @@ -1,6 +1,6 @@ { "name": "@abaplint/core", - "version": "2.58.11", + "version": "2.58.12", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/packages/core/package.json b/packages/core/package.json index 5feaccadbf..6c05edc7b7 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@abaplint/core", - "version": "2.58.11", + "version": "2.58.12", "description": "abaplint - Core API", "main": "build/src/index.js", "typings": "build/abaplint.d.ts", diff --git a/packages/core/scripts/schema.json b/packages/core/scripts/schema.json index 787b39d5b6..4c0bbf3350 100644 --- a/packages/core/scripts/schema.json +++ b/packages/core/scripts/schema.json @@ -1405,7 +1405,7 @@ "type": "boolean" } ], - "description": "Checks that definitions are placed at the beginning of methods.\nTags: SingleFile\nhttps://rules.abaplint.org/definitions_top" + "description": "Checks that definitions are placed at the beginning of methods.\nTags: SingleFile, Quickfix\nhttps://rules.abaplint.org/definitions_top" }, "description_empty": { "anyOf": [ diff --git a/packages/core/src/rules/definitions_top.ts b/packages/core/src/rules/definitions_top.ts index 611175fa0d..75dcca903d 100644 --- a/packages/core/src/rules/definitions_top.ts +++ b/packages/core/src/rules/definitions_top.ts @@ -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 { } @@ -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], }; } @@ -45,6 +47,7 @@ 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 @@ -52,6 +55,7 @@ export class DefinitionsTop extends ABAPRule { if (statement.get() instanceof Statements.Form || statement.get() instanceof Statements.Method) { mode = DEFINITION; + start = statement; issue = undefined; } else if (statement.get() instanceof Comment) { continue; @@ -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 @@ -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); + } } \ No newline at end of file diff --git a/packages/core/test/rules/definitions_top.ts b/packages/core/test/rules/definitions_top.ts index 8f7ab6c380..61b10a80fb 100644 --- a/packages/core/test/rules/definitions_top.ts +++ b/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 = [ { @@ -84,4 +88,34 @@ ENDFORM.`, ]; -testRule(tests, DefinitionsTop); \ No newline at end of file +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); + }); + +}); \ No newline at end of file diff --git a/packages/monaco/package-lock.json b/packages/monaco/package-lock.json index 73a9a11ca5..c83f4f22a4 100644 --- a/packages/monaco/package-lock.json +++ b/packages/monaco/package-lock.json @@ -1,13 +1,13 @@ { "name": "@abaplint/monaco", - "version": "2.58.11", + "version": "2.58.12", "lockfileVersion": 1, "requires": true, "dependencies": { "@abaplint/core": { - "version": "2.58.11", - "resolved": "https://registry.npmjs.org/@abaplint/core/-/core-2.58.11.tgz", - "integrity": "sha512-+ykt8pIJyO2GFRFGBPNbY6z3baf8KPvgJMKUS4ItLTc4zzVwavwnwKdk4maY5m7f2J3xfCmYndpcmd9s1q+dyQ==", + "version": "2.58.12", + "resolved": "https://registry.npmjs.org/@abaplint/core/-/core-2.58.12.tgz", + "integrity": "sha512-PztA8oMGiUjI9jzVJZa9eyZmzOwD04NLWBeP3IVBjRg7+uP71zm+73zqrHyUIrsEbEjvZMwSdz4usyMi+TCQ7Q==", "requires": { "json5": "^2.1.3", "vscode-languageserver-types": "^3.15.1", diff --git a/packages/monaco/package.json b/packages/monaco/package.json index 18504cc0d8..3ce0789cea 100644 --- a/packages/monaco/package.json +++ b/packages/monaco/package.json @@ -1,6 +1,6 @@ { "name": "@abaplint/monaco", - "version": "2.58.11", + "version": "2.58.12", "description": "ABAP language support for Monaco Editor", "main": "build/index.js", "typings": "build/index.d.ts", @@ -24,6 +24,6 @@ "vscode-languageserver-types": "^3.15.1" }, "dependencies": { - "@abaplint/core": "^2.58.11" + "@abaplint/core": "^2.58.12" } } diff --git a/web/playground/package-lock.json b/web/playground/package-lock.json index dfc5fb8118..e3b1990e77 100644 --- a/web/playground/package-lock.json +++ b/web/playground/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@abaplint/core": { - "version": "2.58.11", - "resolved": "https://registry.npmjs.org/@abaplint/core/-/core-2.58.11.tgz", - "integrity": "sha512-+ykt8pIJyO2GFRFGBPNbY6z3baf8KPvgJMKUS4ItLTc4zzVwavwnwKdk4maY5m7f2J3xfCmYndpcmd9s1q+dyQ==", + "version": "2.58.12", + "resolved": "https://registry.npmjs.org/@abaplint/core/-/core-2.58.12.tgz", + "integrity": "sha512-PztA8oMGiUjI9jzVJZa9eyZmzOwD04NLWBeP3IVBjRg7+uP71zm+73zqrHyUIrsEbEjvZMwSdz4usyMi+TCQ7Q==", "dev": true, "requires": { "json5": "^2.1.3", @@ -27,12 +27,12 @@ } }, "@abaplint/monaco": { - "version": "2.58.11", - "resolved": "https://registry.npmjs.org/@abaplint/monaco/-/monaco-2.58.11.tgz", - "integrity": "sha512-7fnvAkEMaGlLQCHUt5YyiJV3L4GpGk6VVwJL2L1w7nCGJqeotvgpCVnlM2iWjVaXcA/m4kiHW3eFy0GqXDJYkw==", + "version": "2.58.12", + "resolved": "https://registry.npmjs.org/@abaplint/monaco/-/monaco-2.58.12.tgz", + "integrity": "sha512-eFmXhAlXth5l+6MDFBfrge2PsETgELHfVI0+DzawGTE4G+9gjSbds52mlajNKSNEX1b0i9ego20QosD9fGkDgQ==", "dev": true, "requires": { - "@abaplint/core": "^2.58.11" + "@abaplint/core": "^2.58.12" } }, "@hapi/address": { diff --git a/web/playground/package.json b/web/playground/package.json index 9b4ce875dd..06ef132aa9 100644 --- a/web/playground/package.json +++ b/web/playground/package.json @@ -21,7 +21,7 @@ "vscode-languageserver-types": "^3.15.1" }, "devDependencies": { - "@abaplint/monaco": "^2.58.11", + "@abaplint/monaco": "^2.58.12", "css-loader": "^5.0.0", "file-loader": "^6.1.1", "html-webpack-plugin": "^4.5.0",