@abaplint/core
Version:
abaplint - Core API
117 lines • 4.36 kB
JavaScript
;
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