Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 21569x 21569x 21569x 21569x 21569x 21569x 21569x 21569x 21569x 21569x 21569x 21569x 21569x 21569x 21569x 21569x 21569x 21569x 21569x 21569x 21569x 21569x 21569x 21569x 1x 10792x 10792x 10792x 10792x 32185x 32185x 32185x 32185x 32185x 32185x 32185x 32185x 32185x 32185x 32185x 32185x 32185x 32185x 32185x 32185x 32185x 10792x 10792x 10273x 10273x 10792x 10792x 240x 240x 10792x 10792x 255x 255x 10792x 10792x 329x 312x 312x 17x 17x 329x 1x 1x 16x 16x 329x 16x 16x 329x 16x 16x 16x 329x 16x 16x 329x 6x 6x 6x 6x 10x 10x 10x 10792x 10792x 16x 16x 16x 16x 10792x 10792x 16x 16x 16x 2x 2x 14x 16x 3x 3x 11x 16x 2x 2x 9x 16x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 10792x 10792x | import {Issue} from "../issue";
import {IRule, IRuleMetadata, RuleTag} from "./_irule";
import {IObject} from "../objects/_iobject";
import {IRegistry} from "../_iregistry";
import {BasicRuleConfig} from "./_basic_rule_config";
import {DataDefinition} from "../objects";
import {CDSDefineView, CDSDefineAbstract, CDSDefineCustom, CDSDefineTableFunction, CDSExtendView, CDSDefineProjection} from "../cds/expressions";
import {CDSName} from "../cds/expressions/cds_name";
import {ExpressionNode} from "../abap/nodes/expression_node";
export class CDSNamingConf extends BasicRuleConfig {
/** Expected prefix for basic interface views */
public basicInterfaceView: string = "ZI_";
/** Expected prefix for composite interface views */
public compositeInterfaceView: string = "ZI_";
/** Expected prefix for consumption views */
public consumptionView: string = "ZC_";
/** Expected prefix for basic restricted reuse views */
public basicRestrictedReuseView: string = "ZR_";
/** Expected prefix for composite restricted reuse views */
public compositeRestrictedReuseView: string = "ZR_";
/** Expected prefix for private views */
public privateView: string = "ZP_";
/** Expected prefix for remote API views */
public remoteAPIView: string = "ZA_";
/** Expected prefix for view extends */
public viewExtend: string = "ZX_";
/** Expected prefix for extension include views */
public extensionIncludeView: string = "ZE_";
/** Expected prefix for derivation functions */
public derivationFunction: string = "ZF_";
/** Expected prefix for abstract entities */
public abstractEntity: string = "ZD_";
}
export class CDSNaming implements IRule {
private conf = new CDSNamingConf();
public getMetadata(): IRuleMetadata {
return {
key: "cds_naming",
title: "CDS Naming",
shortDescription: `Checks CDS naming conventions based on the VDM prefix rules`,
extendedInformation: `Validates that CDS entity names follow the expected prefix conventions:
I_ for interface views, C_ for consumption views, R_ for restricted reuse views,
P_ for private views, A_ for remote API views, X_ for view extends,
E_ for extension include views, F_ for derivation functions, D_ for abstract entities.
Names must also start with Z after the prefix (custom namespace).
https://help.sap.com/docs/SAP_S4HANA_ON-PREMISE/ee6ff9b281d8448f96b4fe6c89f2bdc8/8a8cee943ef944fe8936f4cc60ba9bc1.html`,
tags: [RuleTag.SingleFile, RuleTag.Naming],
badExample: `define view entity ZMY_VIEW as select from source { key id }`,
goodExample: `define view entity ZI_MY_VIEW as select from source { key id }`,
};
}
public getConfig() {
return this.conf;
}
public setConfig(conf: CDSNamingConf) {
this.conf = conf;
}
public initialize(_reg: IRegistry): IRule {
return this;
}
public run(o: IObject): Issue[] {
if (o.getType() !== "DDLS" || !(o instanceof DataDefinition)) {
return [];
}
const tree = o.getTree();
if (tree === undefined) {
return [];
}
const file = o.findSourceFile();
if (file === undefined) {
return [];
}
const name = this.getCDSName(tree);
if (name === undefined) {
return [];
}
const nameStr = name.toUpperCase();
const allowedPrefixes = this.getAllowedPrefixes(tree);
if (allowedPrefixes.length === 0) {
return [];
}
const matched = allowedPrefixes.some(p => nameStr.startsWith(p.toUpperCase()));
if (!matched) {
const prefixList = [...new Set(allowedPrefixes)].join(", ");
const message = `CDS name "${name}" should have one of the expected prefixes: ${prefixList}`;
return [Issue.atRow(file, 1, message, this.getMetadata().key, this.getConfig().severity)];
}
return [];
}
private getCDSName(tree: ExpressionNode): string | undefined {
const nameNodes = tree.findDirectExpressions(CDSName);
if (nameNodes.length > 0) {
return nameNodes[0].getFirstToken().getStr();
}
return undefined;
}
private getAllowedPrefixes(tree: ExpressionNode): string[] {
const root = tree.get();
if (root instanceof CDSExtendView) {
return [this.conf.viewExtend];
}
if (root instanceof CDSDefineAbstract) {
return [this.conf.abstractEntity];
}
if (root instanceof CDSDefineTableFunction) {
return [this.conf.derivationFunction];
}
if (root instanceof CDSDefineView || root instanceof CDSDefineProjection || root instanceof CDSDefineCustom) {
return [
this.conf.basicInterfaceView,
this.conf.compositeInterfaceView,
this.conf.consumptionView,
this.conf.basicRestrictedReuseView,
this.conf.compositeRestrictedReuseView,
this.conf.privateView,
this.conf.remoteAPIView,
this.conf.extensionIncludeView,
];
}
return [];
}
}
|