@abaplint/core 2.117.3 → 2.118.0

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.
@@ -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
  }
@@ -74,7 +74,7 @@ class Registry {
74
74
  }
75
75
  static abaplintVersion() {
76
76
  // magic, see build script "version.sh"
77
- return "2.117.3";
77
+ return "2.118.0";
78
78
  }
79
79
  getDDICReferences() {
80
80
  return this.ddicReferences;
@@ -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
@@ -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.117.3",
3
+ "version": "2.118.0",
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.5",
66
+ "fast-xml-parser": "^5.5.7",
67
67
  "json5": "^2.2.3",
68
68
  "vscode-languageserver-types": "^3.17.5"
69
69
  }