UNPKG

@abaplint/core

Version:
375 lines (367 loc) • 14.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AlignParameters = exports.AlignParametersConf = void 0; const issue_1 = require("../issue"); const Expressions = require("../abap/2_statements/expressions"); const _abap_rule_1 = require("./_abap_rule"); const _basic_rule_config_1 = require("./_basic_rule_config"); const _irule_1 = require("./_irule"); const position_1 = require("../position"); const Statements = require("../abap/2_statements/statements"); const edit_helper_1 = require("../edit_helper"); class AlignParametersConf extends _basic_rule_config_1.BasicRuleConfig { } exports.AlignParametersConf = AlignParametersConf; class AlignParameters extends _abap_rule_1.ABAPRule { constructor() { super(...arguments); this.conf = new AlignParametersConf(); } getMetadata() { return { key: "align_parameters", title: "Align Parameters", shortDescription: `Checks for vertially aligned parameters`, extendedInformation: `Checks: * function module calls * method calls * VALUE constructors * NEW constructors * RAISE EXCEPTION statements * CREATE OBJECT statements * RAISE EVENT statements https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#align-parameters Does not take effect on non functional method calls, use https://rules.abaplint.org/functional_writing/ If parameters are on the same row, no issues are reported, see https://rules.abaplint.org/max_one_method_parameter_per_line/ for splitting parameters to lines`, tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Whitespace, _irule_1.RuleTag.Styleguide, _irule_1.RuleTag.Quickfix], badExample: `CALL FUNCTION 'FOOBAR' EXPORTING foo = 2 parameter = 3. foobar( moo = 1 param = 1 ). foo = VALUE #( foo = bar moo = 2 ).`, goodExample: `CALL FUNCTION 'FOOBAR' EXPORTING foo = 2 parameter = 3. foobar( moo = 1 param = 1 ). foo = VALUE #( foo = bar moo = 2 ). DATA(sdf) = VALUE type( common_val = 2 another_common = 5 ( row_value = 4 value_foo = 5 ) ).`, }; } getConfig() { return this.conf; } setConfig(conf) { this.conf = conf; } runParsed(file) { const issues = []; const stru = file.getStructure(); if (stru === undefined) { return issues; // parser error } const candidates = []; candidates.push(...this.functionParameterCandidates(stru)); candidates.push(...this.methodCallParamCandidates(stru)); candidates.push(...this.valueBodyCandidates(stru)); candidates.push(...this.raiseAndCreateCandidates(stru)); candidates.push(...this.newCandidates(stru)); for (const c of candidates) { const i = this.checkCandidate(c, file); if (i) { issues.push(i); } } return issues; } checkCandidate(candidate, file) { if (candidate.parameters.length === 0) { return undefined; } let expectedEqualsColumn = 0; let row = 0; for (const p of candidate.parameters) { const currentCol = p.left.getLastToken().getCol() + p.left.getLastToken().getStr().length + 1; if (p.eq.getRow() === row) { return undefined; } row = p.eq.getRow(); if (currentCol > expectedEqualsColumn) { expectedEqualsColumn = currentCol; } } for (const p of candidate.parameters) { if (p.eq.getCol() !== expectedEqualsColumn) { let fix; if (p.eq.getCol() < expectedEqualsColumn) { fix = edit_helper_1.EditHelper.insertAt(file, p.eq, " ".repeat(expectedEqualsColumn - p.eq.getCol())); } else { fix = edit_helper_1.EditHelper.deleteRange(file, new position_1.Position(p.eq.getRow(), expectedEqualsColumn), p.eq); } const message = "Align parameters to column " + expectedEqualsColumn; return issue_1.Issue.atPosition(file, p.eq, message, this.getMetadata().key, this.getConfig().severity, fix); } } return undefined; } newCandidates(stru) { const candidates = []; for (const vb of stru.findAllExpressionsRecursive(Expressions.NewObject)) { const parameters = []; const fieldAssignments = vb.findDirectExpressions(Expressions.FieldAssignment); if (fieldAssignments.length >= 2) { for (const fs of fieldAssignments) { const children = fs.getChildren(); if (children.length < 3) { continue; // unexpected } parameters.push({ left: children[0], eq: children[1].getFirstToken().getStart(), right: children[2], }); } if (parameters.length > 0) { candidates.push({ parameters }); continue; } } const list = vb.findDirectExpression(Expressions.ParameterListS); if (list) { for (const c of list.getChildren()) { const children = c.getChildren(); if (children.length < 3) { continue; // unexpected } parameters.push({ left: children[0], eq: children[1].getFirstToken().getStart(), right: children[2], }); } if (parameters.length > 0) { candidates.push({ parameters }); } } } return candidates; } valueBodyCandidates(stru) { const candidates = []; for (const vb of stru.findAllExpressionsRecursive(Expressions.ValueBody)) { const parameters = []; const fieldAssignments = vb.findDirectExpressions(Expressions.FieldAssignment); if (fieldAssignments.length <= 1) { continue; } for (const fs of fieldAssignments) { const children = fs.getChildren(); if (children.length < 3) { continue; // unexpected } parameters.push({ left: children[0], eq: children[1].getFirstToken().getStart(), right: children[2], }); } if (parameters.length > 0) { candidates.push({ parameters }); } } for (const vb of stru.findAllExpressionsRecursive(Expressions.ValueBodyLine)) { const parameters = []; const fieldAssignments = vb.findDirectExpressions(Expressions.FieldAssignment); if (fieldAssignments.length <= 1) { continue; } for (const fs of fieldAssignments) { const children = fs.getChildren(); if (children.length < 3) { continue; // unexpected } parameters.push({ left: children[0], eq: children[1].getFirstToken().getStart(), right: children[2], }); } if (parameters.length > 0) { candidates.push({ parameters }); } } return candidates; } raiseAndCreateCandidates(stru) { const candidates = []; const statements = stru.findAllStatements(Statements.Raise); statements.push(...stru.findAllStatements(Statements.CreateObject)); statements.push(...stru.findAllStatements(Statements.RaiseEvent)); for (const raise of statements) { const parameters = []; const param = raise.findDirectExpression(Expressions.ParameterListS); for (const p of (param === null || param === void 0 ? void 0 : param.getChildren()) || []) { const children = p.getChildren(); if (children.length < 3) { continue; // unexpected } parameters.push({ left: children[0], eq: children[1].getFirstToken().getStart(), right: children[2], }); } const ex = raise.findDirectExpression(Expressions.ParameterListExceptions); for (const e of (ex === null || ex === void 0 ? void 0 : ex.getChildren()) || []) { const children = e.getChildren(); if (children.length < 3) { continue; // unexpected } parameters.push({ left: children[0], eq: children[1].getFirstToken().getStart(), right: children[2], }); } if (parameters.length > 0) { candidates.push({ parameters }); } } return candidates; } methodCallParamCandidates(stru) { var _a, _b, _c; const candidates = []; for (const mcp of stru.findAllExpressionsRecursive(Expressions.MethodCallParam)) { const parameters = []; for (const param of ((_a = mcp.findDirectExpression(Expressions.ParameterListS)) === null || _a === void 0 ? void 0 : _a.getChildren()) || []) { const children = param.getChildren(); if (children.length < 3) { continue; // unexpected } parameters.push({ left: children[0], eq: children[1].getFirstToken().getStart(), right: children[2], }); } const mp = mcp.findDirectExpression(Expressions.MethodParameters); if (mp) { for (const p of ((_b = mp.findDirectExpression(Expressions.ParameterListS)) === null || _b === void 0 ? void 0 : _b.getChildren()) || []) { const children = p.getChildren(); if (children.length < 3) { continue; // unexpected } parameters.push({ left: children[0], eq: children[1].getFirstToken().getStart(), right: children[2], }); } for (const l of mp.findDirectExpressions(Expressions.ParameterListT)) { for (const p of l.findDirectExpressions(Expressions.ParameterT) || []) { const children = p.getChildren(); if (children.length < 3) { continue; // unexpected } parameters.push({ left: children[0], eq: children[1].getFirstToken().getStart(), right: children[2], }); } } const rec = mp.findDirectExpression(Expressions.ParameterT); if (rec) { const children = rec.getChildren(); if (children.length < 3) { continue; // unexpected } parameters.push({ left: children[0], eq: children[1].getFirstToken().getStart(), right: children[2], }); } for (const ex of ((_c = mp.findDirectExpression(Expressions.ParameterListExceptions)) === null || _c === void 0 ? void 0 : _c.getChildren()) || []) { const children = ex.getChildren(); if (children.length < 3) { continue; // unexpected } parameters.push({ left: children[0], eq: children[1].getFirstToken().getStart(), right: children[2], }); } } if (parameters.length > 0) { candidates.push({ parameters }); } } return candidates; } functionParameterCandidates(stru) { const candidates = []; for (const fp of stru.findAllExpressionsRecursive(Expressions.FunctionParameters)) { const parameters = []; for (const p of fp.findAllExpressions(Expressions.FunctionExportingParameter)) { const children = p.getChildren(); if (children.length < 3) { continue; // unexpected } parameters.push({ left: children[0], eq: children[1].getFirstToken().getStart(), right: children[2], }); } for (const list of fp.findDirectExpressions(Expressions.ParameterListT)) { for (const pt of list.findDirectExpressions(Expressions.ParameterT)) { const children = pt.getChildren(); if (children.length < 3) { continue; // unexpected } parameters.push({ left: children[0], eq: children[1].getFirstToken().getStart(), right: children[2], }); } } const list = fp.findDirectExpression(Expressions.ParameterListExceptions); if (list) { for (const pt of list.findDirectExpressions(Expressions.ParameterException)) { const children = pt.getChildren(); if (children.length < 3) { continue; // unexpected } parameters.push({ left: children[0], eq: children[1].getFirstToken().getStart(), right: children[2], }); } } if (parameters.length > 0) { candidates.push({ parameters }); } } return candidates; } } exports.AlignParameters = AlignParameters; //# sourceMappingURL=align_parameters.js.map