UNPKG

@abaplint/core

Version:
137 lines (135 loc) 6.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Abapdoc = exports.AbapdocConf = void 0; const _abap_rule_1 = require("./_abap_rule"); const _basic_rule_config_1 = require("./_basic_rule_config"); const issue_1 = require("../issue"); const visibility_1 = require("../abap/4_file_information/visibility"); const _irule_1 = require("./_irule"); class AbapdocConf extends _basic_rule_config_1.BasicRuleConfig { constructor() { super(...arguments); /** Check local classes and interfaces for abapdoc. */ this.checkLocal = false; this.classDefinition = false; this.interfaceDefinition = false; /** Ignores classes flagged as FOR TESTING */ this.ignoreTestClasses = true; } } exports.AbapdocConf = AbapdocConf; class Abapdoc extends _abap_rule_1.ABAPRule { constructor() { super(...arguments); this.conf = new AbapdocConf(); } getMetadata() { return { key: "abapdoc", title: "Check abapdoc", shortDescription: `Various checks regarding abapdoc.`, extendedInformation: `Base rule checks for existence of abapdoc for public class methods and all interface methods. Plus class and interface definitions. https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#abap-doc-only-for-public-apis`, tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Styleguide], }; } getConfig() { return this.conf; } setConfig(conf) { this.conf = conf; } runParsed(file) { var _a, _b; const issues = []; const rows = file.getRawRows(); const regexEmptyTags = '^\\"! .*<[^/>]*><\\/'; const regexEmptyAbapdoc = '^\\"!.+$'; const regexEmptyParameterName = '^\\"! @parameter .+\\|'; let methods = []; for (const classDef of file.getInfo().listClassDefinitions()) { if (this.conf.checkLocal === false && classDef.isLocal === true) { continue; } if (this.conf.ignoreTestClasses === true && classDef.isForTesting === true) { continue; } methods = methods.concat(classDef.methods.filter(m => m.visibility === visibility_1.Visibility.Public)); if (this.conf.classDefinition === true) { const previousRow = classDef.identifier.getStart().getRow() - 2; if (((_a = rows[previousRow]) === null || _a === void 0 ? void 0 : _a.trim().substring(0, 2)) !== "\"!") { const message = "Missing ABAP Doc for class " + classDef.identifier.getToken().getStr(); const issue = issue_1.Issue.atIdentifier(classDef.identifier, message, this.getMetadata().key, this.conf.severity); issues.push(issue); } } } for (const interfaceDef of file.getInfo().listInterfaceDefinitions()) { if (this.conf.checkLocal === false && interfaceDef.isLocal === true) { continue; } methods = methods.concat(interfaceDef.methods); if (this.conf.interfaceDefinition === true) { const previousRow = interfaceDef.identifier.getStart().getRow() - 2; if (((_b = rows[previousRow]) === null || _b === void 0 ? void 0 : _b.trim().substring(0, 2)) !== "\"!") { const message = "Missing ABAP Doc for interface " + interfaceDef.identifier.getToken().getStr(); const issue = issue_1.Issue.atIdentifier(interfaceDef.identifier, message, this.getMetadata().key, this.conf.severity); issues.push(issue); } } } for (const method of methods) { if (method.isRedefinition === true) { continue; } const previousRowsTexts = this.getAbapdoc(rows, method.identifier.getStart()); if (previousRowsTexts === undefined) { continue; } for (const rowText of previousRowsTexts) { if (rowText.trim().match(regexEmptyTags) !== null) { const message = "Empty tag(s) in ABAP Doc for method " + method.identifier.getToken().getStr() + " (" + rowText + ")"; const issue = issue_1.Issue.atIdentifier(method.identifier, message, this.getMetadata().key, this.conf.severity); issues.push(issue); } if (rowText.trim().match(regexEmptyAbapdoc) === null && previousRowsTexts.indexOf(rowText) === previousRowsTexts.length - 1) { const message = "Missing ABAP Doc for method " + method.identifier.getToken().getStr() + " (" + rowText + ")"; const issue = issue_1.Issue.atIdentifier(method.identifier, message, this.getMetadata().key, this.conf.severity); issues.push(issue); } if (rowText.trim().match(regexEmptyParameterName) !== null) { const message = "Missing ABAP Doc parameter name for method " + method.identifier.getToken().getStr() + " (" + rowText + ")"; const issue = issue_1.Issue.atIdentifier(method.identifier, message, this.getMetadata().key, this.conf.severity); issues.push(issue); } } } return issues; } getAbapdoc(rows, pos) { let previousRow = pos.getRow() - 2; let rowText = rows[previousRow].trim().toUpperCase(); const text = []; if (rowText === "METHODS" || rowText === "CLASS-METHODS") { previousRow--; rowText = rows[previousRow].trim().toUpperCase(); } text.push(rowText); //we need to push the first row despite if it is actually an abapdoc or not //if the first row above a method is abapdoc then try to get the rest of the abapdoc block above if (rowText.trim().substring(0, 2) === "\"!") { while (previousRow >= 0) { previousRow--; rowText = rows[previousRow].trim().toUpperCase(); if (rowText.trim().substring(0, 2) !== "\"!") { break; } text.push(rowText); } } return text; } } exports.Abapdoc = Abapdoc; //# sourceMappingURL=abapdoc.js.map