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 23027x 23027x 23027x 23027x 23027x 23027x 23027x 23027x 23027x 23027x 23027x 23027x 23027x 23027x 23027x 23027x 23027x 23027x 23027x 23027x 23027x 23027x 23027x 23027x 1x 11521x 11521x 11521x 11521x 34369x 34369x 34369x 34369x 34369x 34369x 34369x 34369x 34369x 34369x 34369x 34369x 34369x 34369x 34369x 34369x 34369x 11521x 11521x 11012x 11012x 11521x 11521x 235x 235x 11521x 11521x 250x 250x 11521x 11521x 320x 303x 303x 17x 17x 320x 1x 1x 16x 16x 320x 16x 16x 320x 16x 16x 16x 320x 16x 16x 320x 6x 6x 6x 6x 10x 10x 10x 11521x 11521x 16x 16x 16x 16x 11521x 11521x 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 11521x 11521x | 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 [];
}
}
|