@abaplint/core 2.117.3 → 2.118.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/src/abap/2_statements/expressions/sql_into_list.js +1 -1
- package/build/src/abap/5_syntax/expressions/function_parameters.js +54 -0
- package/build/src/abap/5_syntax/statements/call_function.js +6 -13
- package/build/src/abap/5_syntax/statements/move.js +9 -0
- package/build/src/registry.js +1 -1
- package/build/src/rules/cds_association_name.js +75 -0
- package/build/src/rules/cds_field_order.js +117 -0
- package/build/src/rules/cds_naming.js +132 -0
- package/build/src/rules/index.js +3 -0
- package/package.json +2 -2
|
@@ -8,7 +8,7 @@ const wparen_left_1 = require("../../1_lexer/tokens/wparen_left");
|
|
|
8
8
|
const version_1 = require("../../../version");
|
|
9
9
|
class SQLIntoList extends combi_1.Expression {
|
|
10
10
|
getRunnable() {
|
|
11
|
-
const intoList = (0, combi_1.seq)((0, combi_1.altPrio)((0, combi_1.tok)(wparen_left_1.WParenLeft), (0, combi_1.ver)(version_1.Version.v740sp02, (0, combi_1.tok)(wparen_leftw_1.WParenLeftW))), (0, combi_1.starPrio)((0, combi_1.seq)(_1.SQLTarget, ",")), _1.SQLTarget, ")");
|
|
11
|
+
const intoList = (0, combi_1.seq)((0, combi_1.altPrio)((0, combi_1.tok)(wparen_left_1.WParenLeft), (0, combi_1.ver)(version_1.Version.v740sp02, (0, combi_1.tok)(wparen_leftw_1.WParenLeftW), version_1.Version.OpenABAP)), (0, combi_1.starPrio)((0, combi_1.seq)(_1.SQLTarget, ",")), _1.SQLTarget, ")");
|
|
12
12
|
return (0, combi_1.seq)("INTO", intoList);
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FunctionParameters = void 0;
|
|
4
|
+
const Expressions = require("../../2_statements/expressions");
|
|
5
|
+
const source_1 = require("./source");
|
|
6
|
+
const target_1 = require("./target");
|
|
7
|
+
const field_chain_1 = require("./field_chain");
|
|
8
|
+
const _reference_1 = require("../_reference");
|
|
9
|
+
const _syntax_input_1 = require("../_syntax_input");
|
|
10
|
+
class FunctionParameters {
|
|
11
|
+
static runSyntax(node, input) {
|
|
12
|
+
// EXPORTING: process sources in each FunctionExportingParameter
|
|
13
|
+
for (const param of node.findAllExpressions(Expressions.FunctionExportingParameter)) {
|
|
14
|
+
const s = param.findDirectExpression(Expressions.Source);
|
|
15
|
+
if (s) {
|
|
16
|
+
source_1.Source.runSyntax(s, input);
|
|
17
|
+
}
|
|
18
|
+
const s3 = param.findDirectExpression(Expressions.SimpleSource3);
|
|
19
|
+
if (s3) {
|
|
20
|
+
source_1.Source.runSyntax(s3, input);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// IMPORTING / CHANGING / TABLES: process targets in each ParameterT
|
|
24
|
+
const changingList = node.findExpressionAfterToken("CHANGING");
|
|
25
|
+
for (const paramList of node.findDirectExpressions(Expressions.ParameterListT)) {
|
|
26
|
+
for (const param of paramList.findDirectExpressions(Expressions.ParameterT)) {
|
|
27
|
+
const t = param.findDirectExpression(Expressions.Target);
|
|
28
|
+
if (t) {
|
|
29
|
+
target_1.Target.runSyntax(t, input);
|
|
30
|
+
}
|
|
31
|
+
if (paramList === changingList && t !== undefined) {
|
|
32
|
+
// hmm, does this do the scoping correctly? handle constants etc? todo
|
|
33
|
+
const found = input.scope.findVariable(t.concatTokens());
|
|
34
|
+
if (found && found.getMeta().includes("read_only" /* IdentifierMeta.ReadOnly */)) {
|
|
35
|
+
const message = `"${t.concatTokens()}" cannot be modified, it is readonly`;
|
|
36
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, t.getFirstToken(), message));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// EXCEPTIONS: process field chains and optional MESSAGE targets
|
|
42
|
+
for (const exc of node.findAllExpressions(Expressions.ParameterException)) {
|
|
43
|
+
for (const s of exc.findDirectExpressions(Expressions.SimpleFieldChain)) {
|
|
44
|
+
field_chain_1.FieldChain.runSyntax(s, input, _reference_1.ReferenceType.DataReadReference);
|
|
45
|
+
}
|
|
46
|
+
const t = exc.findDirectExpression(Expressions.Target);
|
|
47
|
+
if (t) {
|
|
48
|
+
target_1.Target.runSyntax(t, input);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.FunctionParameters = FunctionParameters;
|
|
54
|
+
//# sourceMappingURL=function_parameters.js.map
|
|
@@ -3,11 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CallFunction = void 0;
|
|
4
4
|
const Expressions = require("../../2_statements/expressions");
|
|
5
5
|
const source_1 = require("../expressions/source");
|
|
6
|
-
const target_1 = require("../expressions/target");
|
|
7
6
|
const field_chain_1 = require("../expressions/field_chain");
|
|
8
7
|
const _reference_1 = require("../_reference");
|
|
9
8
|
const version_1 = require("../../../version");
|
|
10
9
|
const _syntax_input_1 = require("../_syntax_input");
|
|
10
|
+
const function_parameters_1 = require("../expressions/function_parameters");
|
|
11
11
|
class CallFunction {
|
|
12
12
|
runSyntax(node, input) {
|
|
13
13
|
// todo, lots of work here, similar to receive.ts
|
|
@@ -25,22 +25,15 @@ class CallFunction {
|
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
for (const s of node.findAllExpressions(Expressions.Source)) {
|
|
30
|
-
source_1.Source.runSyntax(s, input);
|
|
31
|
-
}
|
|
32
|
-
for (const s of node.findAllExpressions(Expressions.SimpleSource3)) {
|
|
28
|
+
for (const s of node.findDirectExpressions(Expressions.SimpleSource2)) {
|
|
33
29
|
source_1.Source.runSyntax(s, input);
|
|
34
30
|
}
|
|
35
|
-
for (const
|
|
36
|
-
target_1.Target.runSyntax(t, input);
|
|
37
|
-
}
|
|
38
|
-
for (const s of node.findDirectExpressions(Expressions.SimpleSource2)) {
|
|
31
|
+
for (const s of node.findDirectExpressions(Expressions.Source)) {
|
|
39
32
|
source_1.Source.runSyntax(s, input);
|
|
40
33
|
}
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
const fp = node.findDirectExpression(Expressions.FunctionParameters);
|
|
35
|
+
if (fp) {
|
|
36
|
+
function_parameters_1.FunctionParameters.runSyntax(fp, input);
|
|
44
37
|
}
|
|
45
38
|
}
|
|
46
39
|
}
|
|
@@ -23,6 +23,15 @@ class Move {
|
|
|
23
23
|
target_1.Target.runSyntax(t, input);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
+
if (inline === undefined && firstTarget !== undefined) {
|
|
27
|
+
// hmm, does this do the scoping correctly? handle constants etc? todo
|
|
28
|
+
const found = input.scope.findVariable(firstTarget.concatTokens());
|
|
29
|
+
if (found && found.getMeta().includes("read_only" /* IdentifierMeta.ReadOnly */)) {
|
|
30
|
+
const message = `"${firstTarget.concatTokens()}" cannot be modified, it is readonly`;
|
|
31
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, firstTarget.getFirstToken(), message));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
26
35
|
const source = node.findDirectExpression(Expressions.Source);
|
|
27
36
|
let sourceType = source ? source_1.Source.runSyntax(source, input, targetType) : undefined;
|
|
28
37
|
if (sourceType === undefined) {
|
package/build/src/registry.js
CHANGED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CDSAssociationName = exports.CDSAssociationNameConf = void 0;
|
|
4
|
+
const issue_1 = require("../issue");
|
|
5
|
+
const _irule_1 = require("./_irule");
|
|
6
|
+
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
7
|
+
const objects_1 = require("../objects");
|
|
8
|
+
const expressions_1 = require("../cds/expressions");
|
|
9
|
+
class CDSAssociationNameConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
10
|
+
}
|
|
11
|
+
exports.CDSAssociationNameConf = CDSAssociationNameConf;
|
|
12
|
+
class CDSAssociationName {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.conf = new CDSAssociationNameConf();
|
|
15
|
+
}
|
|
16
|
+
getMetadata() {
|
|
17
|
+
return {
|
|
18
|
+
key: "cds_association_name",
|
|
19
|
+
title: "CDS Association Name",
|
|
20
|
+
shortDescription: `CDS association names should start with an underscore`,
|
|
21
|
+
extendedInformation: `By convention, CDS association names must start with an underscore character.
|
|
22
|
+
|
|
23
|
+
https://help.sap.com/docs/abap-cloud/abap-data-models/cds-associations`,
|
|
24
|
+
tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Naming],
|
|
25
|
+
badExample: `define view entity test as select from source
|
|
26
|
+
association [1..1] to target as Assoc on Assoc.id = source.id
|
|
27
|
+
{ key id }`,
|
|
28
|
+
goodExample: `define view entity test as select from source
|
|
29
|
+
association [1..1] to target as _Assoc on _Assoc.id = source.id
|
|
30
|
+
{ key id }`,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
getConfig() {
|
|
34
|
+
return this.conf;
|
|
35
|
+
}
|
|
36
|
+
setConfig(conf) {
|
|
37
|
+
this.conf = conf;
|
|
38
|
+
}
|
|
39
|
+
initialize(_reg) {
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
run(o) {
|
|
43
|
+
if (o.getType() !== "DDLS" || !(o instanceof objects_1.DataDefinition)) {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
const tree = o.getTree();
|
|
47
|
+
if (tree === undefined) {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
const file = o.findSourceFile();
|
|
51
|
+
if (file === undefined) {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
const issues = [];
|
|
55
|
+
for (const assoc of tree.findAllExpressions(expressions_1.CDSAssociation)) {
|
|
56
|
+
const asExpr = assoc.findFirstExpression(expressions_1.CDSAs);
|
|
57
|
+
if (asExpr === undefined) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const nameExpr = asExpr.findDirectExpression(expressions_1.CDSName);
|
|
61
|
+
if (nameExpr === undefined) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const name = nameExpr.getFirstToken().getStr();
|
|
65
|
+
if (!name.startsWith("_")) {
|
|
66
|
+
const token = nameExpr.getFirstToken();
|
|
67
|
+
const message = `CDS association name "${name}" should start with an underscore`;
|
|
68
|
+
issues.push(issue_1.Issue.atToken(file, token, message, this.getMetadata().key, this.getConfig().severity));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return issues;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
exports.CDSAssociationName = CDSAssociationName;
|
|
75
|
+
//# sourceMappingURL=cds_association_name.js.map
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CDSFieldOrder = exports.CDSFieldOrderConf = void 0;
|
|
4
|
+
const issue_1 = require("../issue");
|
|
5
|
+
const _irule_1 = require("./_irule");
|
|
6
|
+
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
7
|
+
const objects_1 = require("../objects");
|
|
8
|
+
const expressions_1 = require("../cds/expressions");
|
|
9
|
+
class CDSFieldOrderConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
10
|
+
}
|
|
11
|
+
exports.CDSFieldOrderConf = CDSFieldOrderConf;
|
|
12
|
+
class CDSFieldOrder {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.conf = new CDSFieldOrderConf();
|
|
15
|
+
}
|
|
16
|
+
getMetadata() {
|
|
17
|
+
return {
|
|
18
|
+
key: "cds_field_order",
|
|
19
|
+
title: "CDS Field Order",
|
|
20
|
+
shortDescription: `Checks that CDS key fields are listed first and associations last in the field list`,
|
|
21
|
+
tags: [_irule_1.RuleTag.SingleFile],
|
|
22
|
+
badExample: `define view entity test as select from source
|
|
23
|
+
association [1..1] to target as _Assoc on _Assoc.id = source.id
|
|
24
|
+
{
|
|
25
|
+
field1,
|
|
26
|
+
key id,
|
|
27
|
+
_Assoc
|
|
28
|
+
}`,
|
|
29
|
+
goodExample: `define view entity test as select from source
|
|
30
|
+
association [1..1] to target as _Assoc on _Assoc.id = source.id
|
|
31
|
+
{
|
|
32
|
+
key id,
|
|
33
|
+
field1,
|
|
34
|
+
_Assoc
|
|
35
|
+
}`,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
getConfig() {
|
|
39
|
+
return this.conf;
|
|
40
|
+
}
|
|
41
|
+
setConfig(conf) {
|
|
42
|
+
this.conf = conf;
|
|
43
|
+
}
|
|
44
|
+
initialize(_reg) {
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
run(o) {
|
|
48
|
+
if (o.getType() !== "DDLS" || !(o instanceof objects_1.DataDefinition)) {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
const tree = o.getTree();
|
|
52
|
+
if (tree === undefined) {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
const file = o.findSourceFile();
|
|
56
|
+
if (file === undefined) {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
const issues = [];
|
|
60
|
+
const associationNames = this.getAssociationNames(tree);
|
|
61
|
+
for (const select of tree.findAllExpressions(expressions_1.CDSSelect)) {
|
|
62
|
+
const elements = select.findDirectExpressions(expressions_1.CDSElement);
|
|
63
|
+
if (elements.length === 0) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
let seenNonKey = false;
|
|
67
|
+
let seenAssociation = false;
|
|
68
|
+
for (const element of elements) {
|
|
69
|
+
const isKey = element.findDirectTokenByText("KEY") !== undefined;
|
|
70
|
+
const isAssoc = this.isAssociationElement(element, associationNames);
|
|
71
|
+
if (isKey && seenNonKey) {
|
|
72
|
+
const message = "Key fields must be listed before non-key fields";
|
|
73
|
+
issues.push(issue_1.Issue.atToken(file, element.getFirstToken(), message, this.getMetadata().key, this.getConfig().severity));
|
|
74
|
+
}
|
|
75
|
+
if (!isAssoc && seenAssociation) {
|
|
76
|
+
const message = "Associations must be listed last in the field list";
|
|
77
|
+
issues.push(issue_1.Issue.atToken(file, element.getFirstToken(), message, this.getMetadata().key, this.getConfig().severity));
|
|
78
|
+
}
|
|
79
|
+
if (!isKey) {
|
|
80
|
+
seenNonKey = true;
|
|
81
|
+
}
|
|
82
|
+
if (isAssoc) {
|
|
83
|
+
seenAssociation = true;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return issues;
|
|
88
|
+
}
|
|
89
|
+
getAssociationNames(tree) {
|
|
90
|
+
const names = new Set();
|
|
91
|
+
for (const assoc of tree.findAllExpressions(expressions_1.CDSAssociation)) {
|
|
92
|
+
const relation = assoc.findDirectExpression(expressions_1.CDSRelation);
|
|
93
|
+
if (relation === undefined) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
const asNode = relation.findDirectExpression(expressions_1.CDSAs);
|
|
97
|
+
if (asNode) {
|
|
98
|
+
const nameNode = asNode.findDirectExpression(expressions_1.CDSName);
|
|
99
|
+
if (nameNode) {
|
|
100
|
+
names.add(nameNode.getFirstToken().getStr().toUpperCase());
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
const name = relation.getFirstToken().getStr();
|
|
105
|
+
names.add(name.toUpperCase());
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return names;
|
|
109
|
+
}
|
|
110
|
+
isAssociationElement(element, associationNames) {
|
|
111
|
+
const tokens = element.concatTokens().replace(/^(KEY|VIRTUAL)\s+/i, "").trim();
|
|
112
|
+
const name = tokens.split(/[\s.,:(]+/)[0];
|
|
113
|
+
return associationNames.has(name.toUpperCase());
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.CDSFieldOrder = CDSFieldOrder;
|
|
117
|
+
//# sourceMappingURL=cds_field_order.js.map
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CDSNaming = exports.CDSNamingConf = void 0;
|
|
4
|
+
const issue_1 = require("../issue");
|
|
5
|
+
const _irule_1 = require("./_irule");
|
|
6
|
+
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
7
|
+
const objects_1 = require("../objects");
|
|
8
|
+
const expressions_1 = require("../cds/expressions");
|
|
9
|
+
const cds_name_1 = require("../cds/expressions/cds_name");
|
|
10
|
+
class CDSNamingConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
/** Expected prefix for basic interface views */
|
|
14
|
+
this.basicInterfaceView = "ZI_";
|
|
15
|
+
/** Expected prefix for composite interface views */
|
|
16
|
+
this.compositeInterfaceView = "ZI_";
|
|
17
|
+
/** Expected prefix for consumption views */
|
|
18
|
+
this.consumptionView = "ZC_";
|
|
19
|
+
/** Expected prefix for basic restricted reuse views */
|
|
20
|
+
this.basicRestrictedReuseView = "ZR_";
|
|
21
|
+
/** Expected prefix for composite restricted reuse views */
|
|
22
|
+
this.compositeRestrictedReuseView = "ZR_";
|
|
23
|
+
/** Expected prefix for private views */
|
|
24
|
+
this.privateView = "ZP_";
|
|
25
|
+
/** Expected prefix for remote API views */
|
|
26
|
+
this.remoteAPIView = "ZA_";
|
|
27
|
+
/** Expected prefix for view extends */
|
|
28
|
+
this.viewExtend = "ZX_";
|
|
29
|
+
/** Expected prefix for extension include views */
|
|
30
|
+
this.extensionIncludeView = "ZE_";
|
|
31
|
+
/** Expected prefix for derivation functions */
|
|
32
|
+
this.derivationFunction = "ZF_";
|
|
33
|
+
/** Expected prefix for abstract entities */
|
|
34
|
+
this.abstractEntity = "ZD_";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.CDSNamingConf = CDSNamingConf;
|
|
38
|
+
class CDSNaming {
|
|
39
|
+
constructor() {
|
|
40
|
+
this.conf = new CDSNamingConf();
|
|
41
|
+
}
|
|
42
|
+
getMetadata() {
|
|
43
|
+
return {
|
|
44
|
+
key: "cds_naming",
|
|
45
|
+
title: "CDS Naming",
|
|
46
|
+
shortDescription: `Checks CDS naming conventions based on the VDM prefix rules`,
|
|
47
|
+
extendedInformation: `Validates that CDS entity names follow the expected prefix conventions:
|
|
48
|
+
I_ for interface views, C_ for consumption views, R_ for restricted reuse views,
|
|
49
|
+
P_ for private views, A_ for remote API views, X_ for view extends,
|
|
50
|
+
E_ for extension include views, F_ for derivation functions, D_ for abstract entities.
|
|
51
|
+
|
|
52
|
+
Names must also start with Z after the prefix (custom namespace).
|
|
53
|
+
|
|
54
|
+
https://help.sap.com/docs/SAP_S4HANA_ON-PREMISE/ee6ff9b281d8448f96b4fe6c89f2bdc8/8a8cee943ef944fe8936f4cc60ba9bc1.html`,
|
|
55
|
+
tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Naming],
|
|
56
|
+
badExample: `define view entity ZMY_VIEW as select from source { key id }`,
|
|
57
|
+
goodExample: `define view entity ZI_MY_VIEW as select from source { key id }`,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
getConfig() {
|
|
61
|
+
return this.conf;
|
|
62
|
+
}
|
|
63
|
+
setConfig(conf) {
|
|
64
|
+
this.conf = conf;
|
|
65
|
+
}
|
|
66
|
+
initialize(_reg) {
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
run(o) {
|
|
70
|
+
if (o.getType() !== "DDLS" || !(o instanceof objects_1.DataDefinition)) {
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
const tree = o.getTree();
|
|
74
|
+
if (tree === undefined) {
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
77
|
+
const file = o.findSourceFile();
|
|
78
|
+
if (file === undefined) {
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
const name = this.getCDSName(tree);
|
|
82
|
+
if (name === undefined) {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
const nameStr = name.toUpperCase();
|
|
86
|
+
const allowedPrefixes = this.getAllowedPrefixes(tree);
|
|
87
|
+
if (allowedPrefixes.length === 0) {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
const matched = allowedPrefixes.some(p => nameStr.startsWith(p.toUpperCase()));
|
|
91
|
+
if (!matched) {
|
|
92
|
+
const prefixList = [...new Set(allowedPrefixes)].join(", ");
|
|
93
|
+
const message = `CDS name "${name}" should have one of the expected prefixes: ${prefixList}`;
|
|
94
|
+
return [issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.getConfig().severity)];
|
|
95
|
+
}
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
getCDSName(tree) {
|
|
99
|
+
const nameNodes = tree.findDirectExpressions(cds_name_1.CDSName);
|
|
100
|
+
if (nameNodes.length > 0) {
|
|
101
|
+
return nameNodes[0].getFirstToken().getStr();
|
|
102
|
+
}
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
getAllowedPrefixes(tree) {
|
|
106
|
+
const root = tree.get();
|
|
107
|
+
if (root instanceof expressions_1.CDSExtendView) {
|
|
108
|
+
return [this.conf.viewExtend];
|
|
109
|
+
}
|
|
110
|
+
if (root instanceof expressions_1.CDSDefineAbstract) {
|
|
111
|
+
return [this.conf.abstractEntity];
|
|
112
|
+
}
|
|
113
|
+
if (root instanceof expressions_1.CDSDefineTableFunction) {
|
|
114
|
+
return [this.conf.derivationFunction];
|
|
115
|
+
}
|
|
116
|
+
if (root instanceof expressions_1.CDSDefineView || root instanceof expressions_1.CDSDefineProjection || root instanceof expressions_1.CDSDefineCustom) {
|
|
117
|
+
return [
|
|
118
|
+
this.conf.basicInterfaceView,
|
|
119
|
+
this.conf.compositeInterfaceView,
|
|
120
|
+
this.conf.consumptionView,
|
|
121
|
+
this.conf.basicRestrictedReuseView,
|
|
122
|
+
this.conf.compositeRestrictedReuseView,
|
|
123
|
+
this.conf.privateView,
|
|
124
|
+
this.conf.remoteAPIView,
|
|
125
|
+
this.conf.extensionIncludeView,
|
|
126
|
+
];
|
|
127
|
+
}
|
|
128
|
+
return [];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
exports.CDSNaming = CDSNaming;
|
|
132
|
+
//# sourceMappingURL=cds_naming.js.map
|
package/build/src/rules/index.js
CHANGED
|
@@ -28,8 +28,11 @@ __exportStar(require("./avoid_use"), exports);
|
|
|
28
28
|
__exportStar(require("./begin_end_names"), exports);
|
|
29
29
|
__exportStar(require("./begin_single_include"), exports);
|
|
30
30
|
__exportStar(require("./call_transaction_authority_check"), exports);
|
|
31
|
+
__exportStar(require("./cds_association_name"), exports);
|
|
31
32
|
__exportStar(require("./cds_comment_style"), exports);
|
|
33
|
+
__exportStar(require("./cds_field_order"), exports);
|
|
32
34
|
__exportStar(require("./cds_legacy_view"), exports);
|
|
35
|
+
__exportStar(require("./cds_naming"), exports);
|
|
33
36
|
__exportStar(require("./cds_parser_error"), exports);
|
|
34
37
|
__exportStar(require("./chain_mainly_declarations"), exports);
|
|
35
38
|
__exportStar(require("./change_if_to_case"), exports);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.118.1",
|
|
4
4
|
"description": "abaplint - Core API",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/abaplint.d.ts",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"typescript": "^5.9.3"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"fast-xml-parser": "^5.5.
|
|
66
|
+
"fast-xml-parser": "^5.5.8",
|
|
67
67
|
"json5": "^2.2.3",
|
|
68
68
|
"vscode-languageserver-types": "^3.17.5"
|
|
69
69
|
}
|