@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.
- package/build/src/abap/2_statements/expressions/sql_function.js +2 -1
- package/build/src/abap/2_statements/statements/authority_check.js +1 -2
- package/build/src/abap/2_statements/statements/method_def.js +2 -2
- package/build/src/abap/types/method_parameters.js +1 -0
- package/build/src/cds/expressions/cds_function.js +2 -1
- package/build/src/registry.js +1 -1
- package/build/src/rules/abapdoc.js +43 -12
- package/build/src/rules/function_module_recommendations.js +1 -0
- package/package.json +4 -4
|
@@ -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
|
|
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
|
-
|
|
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;
|
package/build/src/registry.js
CHANGED
|
@@ -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
|
|
81
|
-
if (
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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.
|
|
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.
|
|
53
|
+
"@types/node": "^18.15.11",
|
|
54
54
|
"chai": "^4.3.7",
|
|
55
|
-
"eslint": "^8.
|
|
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.
|
|
60
|
+
"typescript": "^5.0.3"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"fast-xml-parser": "^4.1.3",
|