@abaplint/core 2.102.17 → 2.102.19
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/abaplint.d.ts +1 -0
- package/build/src/abap/5_syntax/_type_utils.js +6 -0
- package/build/src/abap/5_syntax/statements/class_data.js +4 -0
- package/build/src/abap/5_syntax/statements/type.js +4 -0
- package/build/src/lsp/code_lens.js +54 -3
- package/build/src/registry.js +1 -1
- package/build/src/rules/function_module_recommendations.js +2 -0
- package/build/src/rules/select_performance.js +3 -1
- package/build/src/rules/uncaught_exception.js +13 -2
- package/package.json +3 -3
package/build/abaplint.d.ts
CHANGED
|
@@ -429,6 +429,12 @@ class TypeUtils {
|
|
|
429
429
|
}
|
|
430
430
|
return true;
|
|
431
431
|
}
|
|
432
|
+
else if (target instanceof basic_1.SimpleType) {
|
|
433
|
+
if (source instanceof basic_1.ObjectReferenceType
|
|
434
|
+
|| source instanceof basic_1.TableType) {
|
|
435
|
+
return false;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
432
438
|
return true;
|
|
433
439
|
}
|
|
434
440
|
}
|
|
@@ -13,6 +13,10 @@ class ClassData {
|
|
|
13
13
|
if (found === undefined) {
|
|
14
14
|
return undefined;
|
|
15
15
|
}
|
|
16
|
+
if ((found === null || found === void 0 ? void 0 : found.getType().isGeneric()) === true
|
|
17
|
+
&& (found === null || found === void 0 ? void 0 : found.getType().containsVoid()) === false) {
|
|
18
|
+
throw new Error("DATA definition cannot be generic, " + found.getName());
|
|
19
|
+
}
|
|
16
20
|
const meta = [...found.getMeta(), "static" /* IdentifierMeta.Static */];
|
|
17
21
|
return new _typed_identifier_1.TypedIdentifier(found.getToken(), filename, found.getType(), meta, found.getValue());
|
|
18
22
|
}
|
|
@@ -14,6 +14,10 @@ class Type {
|
|
|
14
14
|
}
|
|
15
15
|
const found = new basic_types_1.BasicTypes(filename, scope).simpleType(node, qualifiedNamePrefix);
|
|
16
16
|
if (found) {
|
|
17
|
+
if ((found === null || found === void 0 ? void 0 : found.getType().isGeneric()) === true
|
|
18
|
+
&& (found === null || found === void 0 ? void 0 : found.getType().containsVoid()) === false) {
|
|
19
|
+
throw new Error("TYPES definition cannot be generic, " + found.getName());
|
|
20
|
+
}
|
|
17
21
|
return found;
|
|
18
22
|
}
|
|
19
23
|
const fallback = node.findFirstExpression(Expressions.NamespaceSimpleName);
|
|
@@ -5,11 +5,13 @@ const LServer = require("vscode-languageserver-types");
|
|
|
5
5
|
const _lsp_utils_1 = require("./_lsp_utils");
|
|
6
6
|
const syntax_1 = require("../abap/5_syntax/syntax");
|
|
7
7
|
const _abap_object_1 = require("../objects/_abap_object");
|
|
8
|
+
const _reference_1 = require("../abap/5_syntax/_reference");
|
|
9
|
+
const types_1 = require("../abap/types");
|
|
8
10
|
class CodeLens {
|
|
9
11
|
constructor(reg) {
|
|
10
12
|
this.reg = reg;
|
|
11
13
|
}
|
|
12
|
-
list(textDocument, settings = { messageText: true }) {
|
|
14
|
+
list(textDocument, settings = { messageText: true, dynamicExceptions: true }) {
|
|
13
15
|
var _a;
|
|
14
16
|
const file = _lsp_utils_1.LSPUtils.getABAPFile(this.reg, textDocument.uri);
|
|
15
17
|
if (file === undefined) {
|
|
@@ -19,7 +21,7 @@ class CodeLens {
|
|
|
19
21
|
if (obj === undefined || !(obj instanceof _abap_object_1.ABAPObject)) {
|
|
20
22
|
return [];
|
|
21
23
|
}
|
|
22
|
-
new syntax_1.SyntaxLogic(this.reg, obj).run();
|
|
24
|
+
const top = new syntax_1.SyntaxLogic(this.reg, obj).run().spaghetti.getTop();
|
|
23
25
|
const ret = [];
|
|
24
26
|
if (settings.messageText === true) {
|
|
25
27
|
const list = this.reg.getMSAGReferences().listByFilename(file.getFilename());
|
|
@@ -34,10 +36,59 @@ class CodeLens {
|
|
|
34
36
|
}
|
|
35
37
|
ret.push({
|
|
36
38
|
range: _lsp_utils_1.LSPUtils.tokenToRange(l.token),
|
|
37
|
-
command: LServer.Command.create(text, "")
|
|
39
|
+
command: LServer.Command.create(text, "")
|
|
38
40
|
});
|
|
39
41
|
}
|
|
40
42
|
}
|
|
43
|
+
if (settings.dynamicExceptions === true) {
|
|
44
|
+
for (const ref of this.findMethodReferences(top)) {
|
|
45
|
+
if (!(ref.resolved instanceof types_1.MethodDefinition)) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
let text = "";
|
|
49
|
+
for (const e of ref.resolved.getRaising()) {
|
|
50
|
+
if (this.isDynamicException(e, top)) {
|
|
51
|
+
if (text === "") {
|
|
52
|
+
text = "Dynamic Exceptions: ";
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
text += " & ";
|
|
56
|
+
}
|
|
57
|
+
text += e.toUpperCase();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (text !== "") {
|
|
61
|
+
ret.push({
|
|
62
|
+
range: _lsp_utils_1.LSPUtils.tokenToRange(ref.resolved.getToken()),
|
|
63
|
+
command: LServer.Command.create(text, "")
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return ret;
|
|
69
|
+
}
|
|
70
|
+
isDynamicException(name, top) {
|
|
71
|
+
var _a;
|
|
72
|
+
// todo: this method only works with global exceptions?
|
|
73
|
+
let current = name;
|
|
74
|
+
while (current !== undefined) {
|
|
75
|
+
if (current.toUpperCase() === "CX_DYNAMIC_CHECK") {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
current = (_a = top.findClassDefinition(current)) === null || _a === void 0 ? void 0 : _a.getSuperClass();
|
|
79
|
+
}
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
findMethodReferences(node) {
|
|
83
|
+
const ret = [];
|
|
84
|
+
for (const r of node.getData().references) {
|
|
85
|
+
if (r.referenceType === _reference_1.ReferenceType.MethodReference) {
|
|
86
|
+
ret.push(r);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
for (const c of node.getChildren()) {
|
|
90
|
+
ret.push(...this.findMethodReferences(c));
|
|
91
|
+
}
|
|
41
92
|
return ret;
|
|
42
93
|
}
|
|
43
94
|
}
|
package/build/src/registry.js
CHANGED
|
@@ -16,6 +16,8 @@ class FunctionModuleRecommendationsConf extends _basic_rule_config_1.BasicRuleCo
|
|
|
16
16
|
this.recommendations = [
|
|
17
17
|
{ name: "CALCULATE_HASH_FOR_RAW", replace: "use CL_ABAP_HMAC or CL_ABAP_MESSAGE_DIGEST" },
|
|
18
18
|
{ name: "CCU_TIMESTAMP_DIFFERENCE", replace: "use CL_ABAP_TSTMP" },
|
|
19
|
+
{ name: "CONVERT_DATE_TO_EXTERNAL", replace: "use CL_ABAP_DATFM" },
|
|
20
|
+
{ name: "CONVERT_TIME_INPUT", replace: "use CL_ABAP_TIMEFM" },
|
|
19
21
|
{ name: "ECATT_CONV_XSTRING_TO_STRING", replace: "use CL_BINARY_CONVERT" },
|
|
20
22
|
{ name: "F4_FILENAME", replace: "use CL_GUI_FRONTEND_SERVICES" },
|
|
21
23
|
{ name: "FUNCTION_EXISTS", replace: "surround with try-catch CX_SY_DYN_CALL_ILLEGAL_METHOD instead" },
|
|
@@ -18,7 +18,9 @@ class SelectPerformanceConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
|
18
18
|
this.endSelect = true;
|
|
19
19
|
/** Detects SELECT * */
|
|
20
20
|
this.selectStar = true;
|
|
21
|
-
/** "SELECT" * is considered okay if the table is less than X columns, the table must be known to the linter
|
|
21
|
+
/** "SELECT" * is considered okay if the table is less than X columns, the table must be known to the linter
|
|
22
|
+
* @default 10
|
|
23
|
+
*/
|
|
22
24
|
this.starOkayIfFewColumns = DEFAULT_COLUMNS;
|
|
23
25
|
}
|
|
24
26
|
}
|
|
@@ -15,6 +15,11 @@ const syntax_1 = require("../abap/5_syntax/syntax");
|
|
|
15
15
|
const _reference_1 = require("../abap/5_syntax/_reference");
|
|
16
16
|
const types_1 = require("../abap/types");
|
|
17
17
|
class UncaughtExceptionConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
18
|
+
constructor() {
|
|
19
|
+
super(...arguments);
|
|
20
|
+
this.reportDynamic = false;
|
|
21
|
+
this.reportNoCheck = false;
|
|
22
|
+
}
|
|
18
23
|
}
|
|
19
24
|
exports.UncaughtExceptionConf = UncaughtExceptionConf;
|
|
20
25
|
class UncaughtException extends _abap_rule_1.ABAPRule {
|
|
@@ -181,11 +186,17 @@ class UncaughtException extends _abap_rule_1.ABAPRule {
|
|
|
181
186
|
return true;
|
|
182
187
|
}
|
|
183
188
|
const sup = this.globalExceptions[name.toUpperCase()];
|
|
184
|
-
if (sup === "CX_DYNAMIC_CHECK"
|
|
189
|
+
if (sup === "CX_DYNAMIC_CHECK" && this.getConfig().reportDynamic !== true) {
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
if (sup === "CX_NO_CHECK" && this.getConfig().reportNoCheck !== true) {
|
|
185
193
|
return true;
|
|
186
194
|
}
|
|
187
195
|
const lsup = this.localExceptions[name.toUpperCase()];
|
|
188
|
-
if (lsup === "CX_DYNAMIC_CHECK"
|
|
196
|
+
if (lsup === "CX_DYNAMIC_CHECK" && this.getConfig().reportDynamic !== true) {
|
|
197
|
+
return true;
|
|
198
|
+
}
|
|
199
|
+
if (lsup === "CX_NO_CHECK" && this.getConfig().reportNoCheck !== true) {
|
|
189
200
|
return true;
|
|
190
201
|
}
|
|
191
202
|
return this.sinked.some(a => a.toUpperCase() === name.toUpperCase())
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/core",
|
|
3
|
-
"version": "2.102.
|
|
3
|
+
"version": "2.102.19",
|
|
4
4
|
"description": "abaplint - Core API",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/abaplint.d.ts",
|
|
@@ -53,9 +53,9 @@
|
|
|
53
53
|
"@microsoft/api-extractor": "^7.36.4",
|
|
54
54
|
"@types/chai": "^4.3.5",
|
|
55
55
|
"@types/mocha": "^10.0.1",
|
|
56
|
-
"@types/node": "^20.
|
|
56
|
+
"@types/node": "^20.5.0",
|
|
57
57
|
"chai": "^4.3.7",
|
|
58
|
-
"eslint": "^8.
|
|
58
|
+
"eslint": "^8.47.0",
|
|
59
59
|
"mocha": "^10.2.0",
|
|
60
60
|
"c8": "^8.0.1",
|
|
61
61
|
"source-map-support": "^0.5.21",
|