@abaplint/core 2.95.49 → 2.95.51

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.
@@ -28,9 +28,10 @@ class SQLFunction extends combi_1.Expression {
28
28
  const lower = (0, combi_1.ver)(version_1.Version.v751, (0, combi_1.seq)("lower", (0, combi_1.tok)(tokens_1.ParenLeftW), param, (0, combi_1.tok)(tokens_1.WParenRightW)));
29
29
  const mod = (0, combi_1.ver)(version_1.Version.v740sp05, (0, combi_1.seq)("mod", (0, combi_1.tok)(tokens_1.ParenLeftW), param, ",", param, (0, combi_1.tok)(tokens_1.WParenRightW)));
30
30
  const replace = (0, combi_1.ver)(version_1.Version.v750, (0, combi_1.seq)("replace", (0, combi_1.tok)(tokens_1.ParenLeftW), param, ",", param, ",", param, (0, combi_1.tok)(tokens_1.WParenRightW)));
31
+ const round = (0, combi_1.ver)(version_1.Version.v750, (0, combi_1.seq)("round", (0, combi_1.tok)(tokens_1.ParenLeftW), param, ",", param, (0, combi_1.tok)(tokens_1.WParenRightW)));
31
32
  const upper = (0, combi_1.ver)(version_1.Version.v751, (0, combi_1.seq)("upper", (0, combi_1.tok)(tokens_1.ParenLeftW), param, (0, combi_1.tok)(tokens_1.WParenRightW)));
32
33
  const uuid = (0, combi_1.ver)(version_1.Version.v754, (0, combi_1.seq)("uuid", (0, combi_1.tok)(tokens_1.ParenLeftW), (0, combi_1.tok)(tokens_1.WParenRightW)));
33
- return (0, combi_1.altPrio)(uuid, abs, ceil, floor, cast, div, mod, coalesce, concat, replace, length, lower, upper);
34
+ return (0, combi_1.altPrio)(uuid, abs, ceil, floor, cast, div, mod, coalesce, concat, replace, length, lower, upper, round);
34
35
  }
35
36
  }
36
37
  exports.SQLFunction = SQLFunction;
@@ -3,13 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AuthorityCheck = void 0;
4
4
  const combi_1 = require("../combi");
5
5
  const expressions_1 = require("../expressions");
6
- const version_1 = require("../../../version");
7
6
  class AuthorityCheck {
8
7
  getMatcher() {
9
8
  const field = (0, combi_1.seq)("FIELD", expressions_1.Source);
10
9
  const id = (0, combi_1.seq)("ID", expressions_1.Source, (0, combi_1.alt)(field, "DUMMY"));
11
10
  const ret = (0, combi_1.seq)("AUTHORITY-CHECK OBJECT", expressions_1.Source, (0, combi_1.opt)((0, combi_1.seq)("FOR USER", expressions_1.Source)), (0, combi_1.plus)(id));
12
- return (0, combi_1.verNot)(version_1.Version.Cloud, ret);
11
+ return ret;
13
12
  }
14
13
  }
15
14
  exports.AuthorityCheck = AuthorityCheck;
@@ -16,8 +16,8 @@ class MethodDef {
16
16
  const result = (0, combi_1.seq)("RESULT", expressions_1.MethodParamName);
17
17
  const link = (0, combi_1.seq)("LINK", expressions_1.MethodParamName);
18
18
  const full = (0, combi_1.seq)("FULL", expressions_1.MethodParamName);
19
- const modify = (0, combi_1.alt)((0, combi_1.seq)("FOR ACTION", expressions_1.TypeName, result), (0, combi_1.seq)("FOR CREATE", (0, combi_1.alt)(expressions_1.TypeName, expressions_1.EntityAssociation)), (0, combi_1.seq)("FOR DELETE", expressions_1.TypeName), (0, combi_1.seq)("FOR UPDATE", expressions_1.TypeName));
20
- const behavior = (0, combi_1.altPrio)((0, combi_1.seq)("VALIDATE ON SAVE IMPORTING", expressions_1.MethodParamName, "FOR", expressions_1.TypeName), (0, combi_1.seq)("MODIFY IMPORTING", expressions_1.MethodParamName, modify), (0, combi_1.seq)("READ IMPORTING", expressions_1.MethodParamName, "FOR READ", (0, combi_1.alt)(expressions_1.TypeName, expressions_1.EntityAssociation), (0, combi_1.optPrio)(full), result, (0, combi_1.optPrio)(link)), (0, combi_1.seq)("FEATURES IMPORTING", expressions_1.MethodParamName, "REQUEST", expressions_1.NamespaceSimpleName, "FOR", expressions_1.NamespaceSimpleName, result), (0, combi_1.seq)("BEHAVIOR IMPORTING", expressions_1.MethodParamName, "FOR CREATE", expressions_1.TypeName, expressions_1.MethodParamName, "FOR UPDATE", expressions_1.TypeName, expressions_1.MethodParamName, "FOR DELETE", expressions_1.TypeName), (0, combi_1.seq)("BEHAVIOR IMPORTING", expressions_1.MethodParamName, "FOR READ", expressions_1.TypeName, result), (0, combi_1.seq)((0, combi_1.alt)("BEHAVIOR", "LOCK"), "IMPORTING", expressions_1.MethodParamName, "FOR LOCK", expressions_1.TypeName), (0, combi_1.seq)("DETERMINE", (0, combi_1.alt)("ON MODIFY", "ON SAVE"), "IMPORTING", expressions_1.MethodParamName, "FOR", expressions_1.TypeName));
19
+ const modify = (0, combi_1.alt)((0, combi_1.seq)("FOR ACTION", expressions_1.TypeName, (0, combi_1.optPrio)(result)), (0, combi_1.seq)("FOR CREATE", (0, combi_1.alt)(expressions_1.TypeName, expressions_1.EntityAssociation)), (0, combi_1.seq)("FOR DELETE", expressions_1.TypeName), (0, combi_1.seq)("FOR UPDATE", expressions_1.TypeName));
20
+ const behavior = (0, combi_1.altPrio)((0, combi_1.seq)("VALIDATE ON SAVE IMPORTING", expressions_1.MethodParamName, "FOR", expressions_1.TypeName), (0, combi_1.seq)("MODIFY IMPORTING", expressions_1.MethodParamName, modify), (0, combi_1.seq)("READ IMPORTING", expressions_1.MethodParamName, "FOR READ", (0, combi_1.alt)(expressions_1.TypeName, expressions_1.EntityAssociation), (0, combi_1.optPrio)(full), result, (0, combi_1.optPrio)(link)), (0, combi_1.seq)("FEATURES IMPORTING", expressions_1.MethodParamName, "REQUEST", expressions_1.NamespaceSimpleName, "FOR", expressions_1.NamespaceSimpleName, result), (0, combi_1.seq)("BEHAVIOR IMPORTING", expressions_1.MethodParamName, "FOR CREATE", expressions_1.TypeName, expressions_1.MethodParamName, "FOR UPDATE", expressions_1.TypeName, expressions_1.MethodParamName, "FOR DELETE", expressions_1.TypeName), (0, combi_1.seq)("BEHAVIOR IMPORTING", expressions_1.MethodParamName, "FOR READ", expressions_1.TypeName, result), (0, combi_1.seq)((0, combi_1.alt)("BEHAVIOR", "LOCK"), "IMPORTING", expressions_1.MethodParamName, "FOR LOCK", expressions_1.TypeName), (0, combi_1.seq)("DETERMINE", (0, combi_1.alt)("ON MODIFY", "ON SAVE"), "IMPORTING", expressions_1.MethodParamName, "FOR", expressions_1.TypeName), (0, combi_1.seq)("GLOBAL AUTHORIZATION IMPORTING REQUEST", expressions_1.MethodParamName, "FOR", expressions_1.TypeName, result));
21
21
  // todo, this is only from version something
22
22
  const amdp = (0, combi_1.seq)("AMDP OPTIONS CDS SESSION CLIENT CURRENT", (0, combi_1.optPrio)(expressions_1.MethodDefImporting), (0, combi_1.optPrio)(expressions_1.MethodDefExporting), (0, combi_1.optPrio)(expressions_1.MethodDefRaising));
23
23
  const ret = (0, combi_1.seq)((0, combi_1.altPrio)("CLASS-METHODS", "METHODS"), expressions_1.MethodName, (0, combi_1.alt)((0, combi_1.seq)((0, combi_1.optPrio)(expressions_1.Abstract), expressions_1.EventHandler), parameters, testing, (0, combi_1.seq)("FOR", (0, combi_1.alt)(tableFunction, ddl, behavior)), amdp, "NOT AT END OF MODE", (0, combi_1.optPrio)(expressions_1.Redefinition)));
@@ -177,6 +177,7 @@ class MethodParameters {
177
177
  }
178
178
  if (node.concatTokens().toUpperCase().includes(" FOR VALIDATE ")
179
179
  || node.concatTokens().toUpperCase().includes(" FOR BEHAVIOR ")
180
+ || node.concatTokens().toUpperCase().includes(" FOR FEATURES ")
180
181
  || node.concatTokens().toUpperCase().includes(" FOR MODIFY ")) {
181
182
  const token = isRap.getFirstToken();
182
183
  this.exporting.push(new _typed_identifier_1.TypedIdentifier(new identifier_1.Identifier(token.getStart(), "failed"), filename, new basic_1.VoidType("RapMethodParameter"), ["exporting" /* IdentifierMeta.MethodExporting */]));
@@ -27,7 +27,8 @@ class CDSFunction extends combi_1.Expression {
27
27
  const tstmp_add_seconds = (0, combi_1.seq)("TSTMP_ADD_SECONDS", "(", input, ",", input, ",", input, ")");
28
28
  const abap_system_timezone = (0, combi_1.seq)("ABAP_SYSTEM_TIMEZONE", "(", input, ",", input, ")");
29
29
  const abap_user_timezone = (0, combi_1.seq)("ABAP_USER_TIMEZONE", "(", input, ",", input, ",", input, ")");
30
- return (0, combi_1.altPrio)(substring, coalesce, tstmp_to_dats, concat, tstmp_to_tims, concat_with_space, dats_is_valid, dats_days_between, tstmp_add_seconds, tstmp_seconds_between, tstmp_current_utctimestamp, tstmp_is_valid, abap_system_timezone, abap_user_timezone, bintohex, hextobin, dats_add_days, dats_add_months, tstmp_to_dst, dats_tims_to_tstmp);
30
+ const mod = (0, combi_1.seq)("MOD", "(", input, ",", input, ")");
31
+ return (0, combi_1.altPrio)(substring, coalesce, tstmp_to_dats, concat, tstmp_to_tims, concat_with_space, dats_is_valid, dats_days_between, tstmp_add_seconds, tstmp_seconds_between, tstmp_current_utctimestamp, tstmp_is_valid, abap_system_timezone, abap_user_timezone, bintohex, hextobin, dats_add_days, dats_add_months, tstmp_to_dst, dats_tims_to_tstmp, mod);
31
32
  }
32
33
  }
33
34
  exports.CDSFunction = CDSFunction;
@@ -63,7 +63,7 @@ class Registry {
63
63
  }
64
64
  static abaplintVersion() {
65
65
  // magic, see build script "version.sh"
66
- return "2.95.49";
66
+ return "2.95.51";
67
67
  }
68
68
  getDDICReferences() {
69
69
  return this.references;
@@ -44,6 +44,9 @@ https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#abap-doc-on
44
44
  var _a, _b;
45
45
  const issues = [];
46
46
  const rows = file.getRawRows();
47
+ const regexEmptyTags = '^\\"! .*<[^>]*><';
48
+ const regexEmptyAbapdoc = '^\\"!.+$';
49
+ const regexEmptyParameterName = '^\\"! @parameter .+\\|';
47
50
  let methods = [];
48
51
  for (const classDef of file.getInfo().listClassDefinitions()) {
49
52
  if (this.conf.checkLocal === false && classDef.isLocal === true) {
@@ -77,22 +80,50 @@ https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#abap-doc-on
77
80
  if (method.isRedefinition === true) {
78
81
  continue;
79
82
  }
80
- const previousRowText = this.getPreviousRow(rows, method.identifier.getStart());
81
- if (!(previousRowText.substring(0, 2) === "\"!")) {
82
- const message = "Missing ABAP Doc for method " + method.identifier.getToken().getStr();
83
- const issue = issue_1.Issue.atIdentifier(method.identifier, message, this.getMetadata().key, this.conf.severity);
84
- issues.push(issue);
83
+ const previousRowsTexts = this.getAbapdoc(rows, method.identifier.getStart());
84
+ if (previousRowsTexts === undefined) {
85
+ continue;
86
+ }
87
+ for (const rowText of previousRowsTexts) {
88
+ if (rowText.trim().match(regexEmptyTags) !== null) {
89
+ const message = "Empty tag(s) in ABAP Doc for method " + method.identifier.getToken().getStr() + " (" + rowText + ")";
90
+ const issue = issue_1.Issue.atIdentifier(method.identifier, message, this.getMetadata().key, this.conf.severity);
91
+ issues.push(issue);
92
+ }
93
+ if (rowText.trim().match(regexEmptyAbapdoc) === null && previousRowsTexts.indexOf(rowText) === previousRowsTexts.length - 1) {
94
+ const message = "Missing ABAP Doc for method " + method.identifier.getToken().getStr() + " (" + rowText + ")";
95
+ const issue = issue_1.Issue.atIdentifier(method.identifier, message, this.getMetadata().key, this.conf.severity);
96
+ issues.push(issue);
97
+ }
98
+ if (rowText.trim().match(regexEmptyParameterName) !== null) {
99
+ const message = "Missing ABAP Doc parameter name for method " + method.identifier.getToken().getStr() + " (" + rowText + ")";
100
+ const issue = issue_1.Issue.atIdentifier(method.identifier, message, this.getMetadata().key, this.conf.severity);
101
+ issues.push(issue);
102
+ }
85
103
  }
86
104
  }
87
105
  return issues;
88
106
  }
89
- getPreviousRow(rows, pos) {
90
- const previousRow = pos.getRow() - 2;
91
- const text = rows[previousRow].trim().toUpperCase();
92
- if (text === "METHODS" || text === "CLASS-METHODS") {
93
- const previousRow = pos.getRow() - 3;
94
- const text = rows[previousRow].trim().toUpperCase();
95
- return text;
107
+ getAbapdoc(rows, pos) {
108
+ let previousRow = pos.getRow() - 2;
109
+ let rowText = rows[previousRow].trim().toUpperCase();
110
+ const text = [];
111
+ if (rowText === "METHODS" || rowText === "CLASS-METHODS") {
112
+ previousRow--;
113
+ rowText = rows[previousRow].trim().toUpperCase();
114
+ }
115
+ text.push(rowText);
116
+ //we need to push the first row despite if it is actually an abapdoc or not
117
+ //if the first row above a method is abapdoc then try to get the rest of the abapdoc block above
118
+ if (rowText.trim().substring(0, 2) === "\"!") {
119
+ while (previousRow >= 0) {
120
+ previousRow--;
121
+ rowText = rows[previousRow].trim().toUpperCase();
122
+ if (rowText.trim().substring(0, 2) !== "\"!") {
123
+ break;
124
+ }
125
+ text.push(rowText);
126
+ }
96
127
  }
97
128
  return text;
98
129
  }
@@ -24,6 +24,7 @@ class FunctionModuleRecommendationsConf extends _basic_rule_config_1.BasicRuleCo
24
24
  { name: "JOB_CREATE", replace: "use CL_BP_ABAP_JOB" },
25
25
  { name: "JOB_SUBMIT", replace: "use CL_BP_ABAP_JOB" },
26
26
  { name: "POPUP_TO_DECIDE", replace: "use POPUP_TO_CONFIRM" },
27
+ { name: "POPUP_TO_CONFIRM_STEP", replace: "use POPUP_TO_CONFIRM" },
27
28
  { name: "POPUP_TO_GET_VALUE", replace: "use POPUP_GET_VALUES" },
28
29
  { name: "REUSE_ALV_GRID_DISPLAY", replace: "use CL_SALV_TABLE=>FACTORY or CL_GUI_ALV_GRID" },
29
30
  { name: "ROUND", replace: "use built in function: round()" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.95.49",
3
+ "version": "2.95.51",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",
@@ -50,14 +50,14 @@
50
50
  "@microsoft/api-extractor": "^7.34.4",
51
51
  "@types/chai": "^4.3.4",
52
52
  "@types/mocha": "^10.0.1",
53
- "@types/node": "^18.15.5",
53
+ "@types/node": "^18.15.11",
54
54
  "chai": "^4.3.7",
55
- "eslint": "^8.36.0",
55
+ "eslint": "^8.37.0",
56
56
  "mocha": "^10.2.0",
57
57
  "c8": "^7.13.0",
58
58
  "source-map-support": "^0.5.21",
59
59
  "ts-json-schema-generator": "^1.2.0",
60
- "typescript": "^5.0.2"
60
+ "typescript": "^5.0.3"
61
61
  },
62
62
  "dependencies": {
63
63
  "fast-xml-parser": "^4.1.3",