@abaplint/core 2.95.51 → 2.96.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.
- package/build/src/abap/5_syntax/basic_types.js +13 -3
- package/build/src/abap/5_syntax/statements/data.js +6 -1
- package/build/src/abap/types/basic/data_reference_type.js +2 -1
- package/build/src/abap/types/basic/generic_object_reference_type.js +2 -1
- package/build/src/abap/types/basic/table_type.js +5 -0
- package/build/src/registry.js +1 -1
- package/build/src/rules/fully_type_itabs.js +59 -0
- package/build/src/rules/index.js +1 -0
- package/build/src/rules/select_add_order_by.js +2 -1
- package/package.json +1 -1
|
@@ -276,13 +276,18 @@ class BasicTypes {
|
|
|
276
276
|
return undefined;
|
|
277
277
|
}
|
|
278
278
|
let type = undefined;
|
|
279
|
-
if (text.startsWith("TYPE STANDARD TABLE ")
|
|
279
|
+
if (text.startsWith("TYPE STANDARD TABLE ")
|
|
280
|
+
|| text.startsWith("TYPE TABLE ")
|
|
281
|
+
|| text.startsWith("LIKE TABLE ")
|
|
282
|
+
|| text.startsWith("LIKE STANDARD TABLE ")) {
|
|
280
283
|
type = basic_1.TableAccessType.standard;
|
|
281
284
|
}
|
|
282
|
-
else if (text.startsWith("TYPE SORTED TABLE ")
|
|
285
|
+
else if (text.startsWith("TYPE SORTED TABLE ")
|
|
286
|
+
|| text.startsWith("LIKE SORTED TABLE ")) {
|
|
283
287
|
type = basic_1.TableAccessType.sorted;
|
|
284
288
|
}
|
|
285
|
-
else if (text.startsWith("TYPE HASHED TABLE ")
|
|
289
|
+
else if (text.startsWith("TYPE HASHED TABLE ")
|
|
290
|
+
|| text.startsWith("LIKE HASHED TABLE ")) {
|
|
286
291
|
type = basic_1.TableAccessType.hashed;
|
|
287
292
|
}
|
|
288
293
|
const typeTableKeys = node.findAllExpressions(expressions_1.TypeTableKey);
|
|
@@ -299,6 +304,9 @@ class BasicTypes {
|
|
|
299
304
|
for (const k of (firstKey === null || firstKey === void 0 ? void 0 : firstKey.findDirectExpressions(expressions_1.FieldSub)) || []) {
|
|
300
305
|
primaryKey.keyFields.push(k.concatTokens().toUpperCase());
|
|
301
306
|
}
|
|
307
|
+
if (primaryKey.keyFields.length === 0 && text.includes(" DEFAULT KEY")) {
|
|
308
|
+
primaryKey.keyFields.push("TABLE_LINE");
|
|
309
|
+
}
|
|
302
310
|
}
|
|
303
311
|
else {
|
|
304
312
|
start = 0;
|
|
@@ -373,6 +381,7 @@ class BasicTypes {
|
|
|
373
381
|
{ name: "low", type: found },
|
|
374
382
|
{ name: "high", type: found },
|
|
375
383
|
]);
|
|
384
|
+
options.primaryKey.type = basic_1.TableAccessType.standard;
|
|
376
385
|
return new Types.TableType(structure, options, name);
|
|
377
386
|
}
|
|
378
387
|
else if (text.startsWith("LIKE RANGE OF ")) {
|
|
@@ -387,6 +396,7 @@ class BasicTypes {
|
|
|
387
396
|
{ name: "low", type: found },
|
|
388
397
|
{ name: "high", type: found },
|
|
389
398
|
], name);
|
|
399
|
+
options.primaryKey.type = basic_1.TableAccessType.standard;
|
|
390
400
|
return new Types.TableType(structure, options);
|
|
391
401
|
}
|
|
392
402
|
else if (typename && (text.startsWith("TYPE TABLE FOR CREATE ")
|
|
@@ -9,7 +9,12 @@ class Data {
|
|
|
9
9
|
runSyntax(node, scope, filename) {
|
|
10
10
|
const dd = node.findFirstExpression(Expressions.DataDefinition);
|
|
11
11
|
if (dd) {
|
|
12
|
-
|
|
12
|
+
const id = new data_definition_1.DataDefinition().runSyntax(dd, scope, filename);
|
|
13
|
+
if ((id === null || id === void 0 ? void 0 : id.getType().isGeneric()) === true
|
|
14
|
+
&& (id === null || id === void 0 ? void 0 : id.getType().containsVoid()) === false) {
|
|
15
|
+
throw new Error("DATA definition cannot be generic");
|
|
16
|
+
}
|
|
17
|
+
return id;
|
|
13
18
|
}
|
|
14
19
|
const name = node.findFirstExpression(Expressions.DefinitionName);
|
|
15
20
|
if (name) {
|
|
@@ -21,7 +21,8 @@ class DataReference extends _abstract_type_1.AbstractType {
|
|
|
21
21
|
return "REF TO " + this.type.toABAP();
|
|
22
22
|
}
|
|
23
23
|
isGeneric() {
|
|
24
|
-
|
|
24
|
+
// a DATA definition can be "REF TO data", so its not generic
|
|
25
|
+
return false;
|
|
25
26
|
}
|
|
26
27
|
containsVoid() {
|
|
27
28
|
return this.type.containsVoid();
|
|
@@ -7,7 +7,8 @@ class GenericObjectReferenceType extends _abstract_type_1.AbstractType {
|
|
|
7
7
|
return "```REF TO object```";
|
|
8
8
|
}
|
|
9
9
|
isGeneric() {
|
|
10
|
-
|
|
10
|
+
// a DATA definition can be "REF TO object", so its not generic
|
|
11
|
+
return false;
|
|
11
12
|
}
|
|
12
13
|
toABAP() {
|
|
13
14
|
return "REF TO object";
|
|
@@ -47,6 +47,11 @@ class TableType extends _abstract_type_1.AbstractType {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
isGeneric() {
|
|
50
|
+
var _a, _b;
|
|
51
|
+
if (((_a = this.options.primaryKey) === null || _a === void 0 ? void 0 : _a.type) !== TableAccessType.standard
|
|
52
|
+
&& ((_b = this.options.primaryKey) === null || _b === void 0 ? void 0 : _b.keyFields.length) === 0) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
50
55
|
return this.rowType.isGeneric();
|
|
51
56
|
}
|
|
52
57
|
containsVoid() {
|
package/build/src/registry.js
CHANGED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FullyTypeITabs = exports.FullyTypeITabsConf = void 0;
|
|
4
|
+
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
5
|
+
const _abap_rule_1 = require("./_abap_rule");
|
|
6
|
+
const issue_1 = require("../issue");
|
|
7
|
+
const Statements = require("../abap/2_statements/statements");
|
|
8
|
+
const Expressions = require("../abap/2_statements/expressions");
|
|
9
|
+
const _irule_1 = require("./_irule");
|
|
10
|
+
class FullyTypeITabsConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
11
|
+
}
|
|
12
|
+
exports.FullyTypeITabsConf = FullyTypeITabsConf;
|
|
13
|
+
class FullyTypeITabs extends _abap_rule_1.ABAPRule {
|
|
14
|
+
constructor() {
|
|
15
|
+
super(...arguments);
|
|
16
|
+
this.conf = new FullyTypeITabsConf();
|
|
17
|
+
}
|
|
18
|
+
getMetadata() {
|
|
19
|
+
return {
|
|
20
|
+
key: "fully_type_itabs",
|
|
21
|
+
title: "Fully type internal tables",
|
|
22
|
+
shortDescription: `No implict table types or table keys`,
|
|
23
|
+
badExample: `DATA lt_foo TYPE TABLE OF ty.
|
|
24
|
+
DATA lt_bar TYPE STANDARD TABLE OF ty.`,
|
|
25
|
+
goodExample: `DATA lt_foo TYPE STANDARD TABLE OF ty WITH EMPTY KEY.`,
|
|
26
|
+
tags: [_irule_1.RuleTag.SingleFile],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
getConfig() {
|
|
30
|
+
return this.conf;
|
|
31
|
+
}
|
|
32
|
+
setConfig(conf) {
|
|
33
|
+
this.conf = conf;
|
|
34
|
+
}
|
|
35
|
+
runParsed(file) {
|
|
36
|
+
const issues = [];
|
|
37
|
+
for (const statement of file.getStatements()) {
|
|
38
|
+
if (!(statement.get() instanceof Statements.Data)) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const tt = statement.findFirstExpression(Expressions.TypeTable);
|
|
42
|
+
if (tt === undefined) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const concat = tt.concatTokens().toUpperCase();
|
|
46
|
+
if (concat.includes("TYPE TABLE OF")) {
|
|
47
|
+
const message = "Specify table type";
|
|
48
|
+
issues.push(issue_1.Issue.atStatement(file, statement, message, this.getMetadata().key, this.conf.severity));
|
|
49
|
+
}
|
|
50
|
+
else if (concat.includes(" WITH ") === false) {
|
|
51
|
+
const message = "Specify table key";
|
|
52
|
+
issues.push(issue_1.Issue.atStatement(file, statement, message, this.getMetadata().key, this.conf.severity));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return issues;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.FullyTypeITabs = FullyTypeITabs;
|
|
59
|
+
//# sourceMappingURL=fully_type_itabs.js.map
|
package/build/src/rules/index.js
CHANGED
|
@@ -64,6 +64,7 @@ __exportStar(require("./forbidden_pseudo_and_pragma"), exports);
|
|
|
64
64
|
__exportStar(require("./forbidden_void_type"), exports);
|
|
65
65
|
__exportStar(require("./form_tables_obsolete"), exports);
|
|
66
66
|
__exportStar(require("./fully_type_constants"), exports);
|
|
67
|
+
__exportStar(require("./fully_type_itabs"), exports);
|
|
67
68
|
__exportStar(require("./function_module_recommendations"), exports);
|
|
68
69
|
__exportStar(require("./functional_writing"), exports);
|
|
69
70
|
__exportStar(require("./global_class"), exports);
|
|
@@ -91,7 +91,8 @@ If the target is a sorted/hashed table, no issue is reported`,
|
|
|
91
91
|
type = found;
|
|
92
92
|
}
|
|
93
93
|
if (type instanceof basic_1.TableType
|
|
94
|
-
&& ((type === null || type === void 0 ? void 0 : type.getAccessType()) === basic_1.TableAccessType.sorted
|
|
94
|
+
&& ((type === null || type === void 0 ? void 0 : type.getAccessType()) === basic_1.TableAccessType.sorted
|
|
95
|
+
|| (type === null || type === void 0 ? void 0 : type.getAccessType()) === basic_1.TableAccessType.hashed)) {
|
|
95
96
|
return true;
|
|
96
97
|
}
|
|
97
98
|
}
|