UNPKG

@abaplint/core

Version:
117 lines 4.36 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CDSFieldOrder = exports.CDSFieldOrderConf = void 0; const issue_1 = require("../issue"); const _irule_1 = require("./_irule"); const _basic_rule_config_1 = require("./_basic_rule_config"); const objects_1 = require("../objects"); const expressions_1 = require("../cds/expressions"); class CDSFieldOrderConf extends _basic_rule_config_1.BasicRuleConfig { } exports.CDSFieldOrderConf = CDSFieldOrderConf; class CDSFieldOrder { constructor() { this.conf = new CDSFieldOrderConf(); } getMetadata() { return { key: "cds_field_order", title: "CDS Field Order", shortDescription: `Checks that CDS key fields are listed first and associations last in the field list`, tags: [_irule_1.RuleTag.SingleFile], badExample: `define view entity test as select from source association [1..1] to target as _Assoc on _Assoc.id = source.id { field1, key id, _Assoc }`, goodExample: `define view entity test as select from source association [1..1] to target as _Assoc on _Assoc.id = source.id { key id, field1, _Assoc }`, }; } getConfig() { return this.conf; } setConfig(conf) { this.conf = conf; } initialize(_reg) { return this; } run(o) { if (o.getType() !== "DDLS" || !(o instanceof objects_1.DataDefinition)) { return []; } const tree = o.getTree(); if (tree === undefined) { return []; } const file = o.findSourceFile(); if (file === undefined) { return []; } const issues = []; const associationNames = this.getAssociationNames(tree); for (const select of tree.findAllExpressions(expressions_1.CDSSelect)) { const elements = select.findDirectExpressions(expressions_1.CDSElement); if (elements.length === 0) { continue; } let seenNonKey = false; let seenAssociation = false; for (const element of elements) { const isKey = element.findDirectTokenByText("KEY") !== undefined; const isAssoc = this.isAssociationElement(element, associationNames); if (isKey && seenNonKey) { const message = "Key fields must be listed before non-key fields"; issues.push(issue_1.Issue.atToken(file, element.getFirstToken(), message, this.getMetadata().key, this.getConfig().severity)); } if (!isAssoc && seenAssociation) { const message = "Associations must be listed last in the field list"; issues.push(issue_1.Issue.atToken(file, element.getFirstToken(), message, this.getMetadata().key, this.getConfig().severity)); } if (!isKey) { seenNonKey = true; } if (isAssoc) { seenAssociation = true; } } } return issues; } getAssociationNames(tree) { const names = new Set(); for (const assoc of tree.findAllExpressions(expressions_1.CDSAssociation)) { const relation = assoc.findDirectExpression(expressions_1.CDSRelation); if (relation === undefined) { continue; } const asNode = relation.findDirectExpression(expressions_1.CDSAs); if (asNode) { const nameNode = asNode.findDirectExpression(expressions_1.CDSName); if (nameNode) { names.add(nameNode.getFirstToken().getStr().toUpperCase()); } } else { const name = relation.getFirstToken().getStr(); names.add(name.toUpperCase()); } } return names; } isAssociationElement(element, associationNames) { const tokens = element.concatTokens().replace(/^(KEY|VIRTUAL)\s+/i, "").trim(); const name = tokens.split(/[\s.,:(]+/)[0]; return associationNames.has(name.toUpperCase()); } } exports.CDSFieldOrder = CDSFieldOrder; //# sourceMappingURL=cds_field_order.js.map