@abaplint/core 2.120.74 → 2.120.76

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.
Files changed (53) hide show
  1. package/build/abaplint.d.ts +5 -1
  2. package/build/src/abap/2_statements/combi.js +143 -51
  3. package/build/src/abap/5_syntax/_builtin.js +8 -0
  4. package/build/src/abap/5_syntax/_loop_table_change.js +126 -0
  5. package/build/src/abap/5_syntax/expressions/_substring.js +83 -0
  6. package/build/src/abap/5_syntax/expressions/attribute_chain.js +3 -16
  7. package/build/src/abap/5_syntax/expressions/compare.js +33 -8
  8. package/build/src/abap/5_syntax/expressions/field_chain.js +5 -14
  9. package/build/src/abap/5_syntax/expressions/method_call_chain.js +16 -1
  10. package/build/src/abap/5_syntax/expressions/method_call_param.js +3 -0
  11. package/build/src/abap/5_syntax/expressions/target.js +14 -2
  12. package/build/src/abap/5_syntax/statements/append.js +6 -0
  13. package/build/src/abap/5_syntax/statements/read_table.js +39 -0
  14. package/build/src/abap/5_syntax/structures/cleanup.js +105 -0
  15. package/build/src/abap/5_syntax/syntax.js +13 -0
  16. package/build/src/ddic.js +1 -1
  17. package/build/src/objects/domain.js +4 -1
  18. package/build/src/registry.js +1 -1
  19. package/build/src/rules/abapdoc_html_tag.js +123 -0
  20. package/build/src/rules/abapdoc_leading_at.js +117 -0
  21. package/build/src/rules/abapdoc_parameter_names.js +149 -0
  22. package/build/src/rules/cds_check_syntax.js +4 -4
  23. package/build/src/rules/change_if_to_case.js +3 -2
  24. package/build/src/rules/changing_sorted_line.js +235 -0
  25. package/build/src/rules/class_attribute_names.js +15 -6
  26. package/build/src/rules/delete_index_in_loop.js +163 -0
  27. package/build/src/rules/final_newline.js +78 -0
  28. package/build/src/rules/forbidden_identifier.js +4 -3
  29. package/build/src/rules/forbidden_void_type.js +4 -9
  30. package/build/src/rules/index.js +11 -0
  31. package/build/src/rules/inline_packed_computation.js +220 -0
  32. package/build/src/rules/intf_referencing_clas.js +3 -1
  33. package/build/src/rules/line_only_punc.js +1 -1
  34. package/build/src/rules/local_class_naming.js +15 -2
  35. package/build/src/rules/local_variable_names.js +18 -9
  36. package/build/src/rules/macro_naming.js +3 -2
  37. package/build/src/rules/method_parameter_names.js +17 -7
  38. package/build/src/rules/modify_only_own_db_tables.js +3 -2
  39. package/build/src/rules/no_prefixes.js +25 -12
  40. package/build/src/rules/object_naming.js +18 -3
  41. package/build/src/rules/prefer_inline_cast.js +276 -0
  42. package/build/src/rules/range_row_values.js +200 -0
  43. package/build/src/rules/redundant_conversion.js +3 -0
  44. package/build/src/rules/selection_screen_naming.js +21 -2
  45. package/build/src/rules/sicf_consistency.js +1 -2
  46. package/build/src/rules/sort_empty_key.js +188 -0
  47. package/build/src/rules/subrc_after_assign.js +220 -0
  48. package/build/src/rules/types_naming.js +3 -2
  49. package/build/src/rules/use_message_class.js +64 -1
  50. package/build/src/rules/wrong_abapdoc_position.js +58 -11
  51. package/build/src/rules/xml_consistency.js +6 -2
  52. package/build/src/utils/name_validator.js +7 -3
  53. package/package.json +1 -1
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DeleteIndexInLoop = exports.DeleteIndexInLoopConf = void 0;
37
+ const Statements = __importStar(require("../abap/2_statements/statements"));
38
+ const Expressions = __importStar(require("../abap/2_statements/expressions"));
39
+ const issue_1 = require("../issue");
40
+ const _basic_rule_config_1 = require("./_basic_rule_config");
41
+ const _abap_rule_1 = require("./_abap_rule");
42
+ const _irule_1 = require("./_irule");
43
+ const token_node_1 = require("../abap/nodes/token_node");
44
+ const _statement_1 = require("../abap/2_statements/statements/_statement");
45
+ class DeleteIndexInLoopConf extends _basic_rule_config_1.BasicRuleConfig {
46
+ }
47
+ exports.DeleteIndexInLoopConf = DeleteIndexInLoopConf;
48
+ class DeleteIndexInLoop extends _abap_rule_1.ABAPRule {
49
+ constructor() {
50
+ super(...arguments);
51
+ this.conf = new DeleteIndexInLoopConf();
52
+ }
53
+ getMetadata() {
54
+ return {
55
+ key: "delete_index_in_loop",
56
+ title: "DELETE INDEX sy-tabix inside a LOOP over the same table",
57
+ shortDescription: `Reports DELETE itab INDEX sy-tabix inside a LOOP AT the same table`,
58
+ extendedInformation: `sy-tabix is the index of the loop's current row only until another statement writes it.
59
+ READ TABLE, APPEND, INSERT, COLLECT, a nested LOOP and any method called in the loop body
60
+ all set sy-tabix. After that the DELETE removes a different row, and if sy-tabix is 0 it
61
+ raises the runtime error TABLE_INVALID_INDEX.
62
+
63
+ Use DELETE itab WHERE ..., or collect the rows to keep in a second table.
64
+
65
+ Not reported: DELETE itab INDEX sy-tabix directly after READ TABLE itab, where sy-tabix
66
+ is the index the READ just set.`,
67
+ tags: [_irule_1.RuleTag.SingleFile],
68
+ badExample: `LOOP AT tab INTO row.
69
+ IF row-flag = abap_true.
70
+ DELETE tab INDEX sy-tabix.
71
+ ENDIF.
72
+ ENDLOOP.`,
73
+ goodExample: `DELETE tab WHERE flag = abap_true.`,
74
+ };
75
+ }
76
+ getConfig() {
77
+ return this.conf;
78
+ }
79
+ setConfig(conf) {
80
+ this.conf = conf;
81
+ }
82
+ runParsed(file) {
83
+ const issues = [];
84
+ const statements = file.getStatements();
85
+ for (let i = 0; i < statements.length; i++) {
86
+ const statement = statements[i];
87
+ if (!(statement.get() instanceof Statements.DeleteInternal) || this.byTabix(statement) === false) {
88
+ continue;
89
+ }
90
+ // DELETE TABLE and DELETE ADJACENT DUPLICATES have a keyword before the target
91
+ const target = statement.findDirectExpression(Expressions.Target);
92
+ if (target === undefined || statement.getChildren()[1] !== target) {
93
+ continue;
94
+ }
95
+ const table = target.concatTokens().toUpperCase();
96
+ if (this.previousReadsTable(i, statements, table) === true
97
+ || this.enclosingLoopTables(i, statements).includes(table) === false) {
98
+ continue;
99
+ }
100
+ const message = `DELETE ${target.concatTokens()} INDEX sy-tabix inside LOOP AT the same table,`
101
+ + ` sy-tabix might not be the loop's current row`;
102
+ issues.push(issue_1.Issue.atStatement(file, statement, message, this.getMetadata().key, this.conf.severity));
103
+ }
104
+ return issues;
105
+ }
106
+ ////////////////
107
+ byTabix(statement) {
108
+ const children = statement.getChildren();
109
+ for (let i = 0; i < children.length - 1; i++) {
110
+ const child = children[i];
111
+ if (child instanceof token_node_1.TokenNode && child.getFirstToken().getStr().toUpperCase() === "INDEX") {
112
+ return children[i + 1].concatTokens().toUpperCase() === "SY-TABIX";
113
+ }
114
+ }
115
+ return false;
116
+ }
117
+ previousReadsTable(index, statements, table) {
118
+ var _a;
119
+ for (let i = index - 1; i >= 0; i--) {
120
+ const statement = statements[i];
121
+ if (statement.get() instanceof _statement_1.Comment) {
122
+ continue;
123
+ }
124
+ if (!(statement.get() instanceof Statements.ReadTable)) {
125
+ return false;
126
+ }
127
+ const read = (_a = statement.findDirectExpression(Expressions.SimpleSource2)) !== null && _a !== void 0 ? _a : statement.findDirectExpression(Expressions.Source);
128
+ return (read === null || read === void 0 ? void 0 : read.concatTokens().toUpperCase()) === table;
129
+ }
130
+ return false;
131
+ }
132
+ enclosingLoopTables(index, statements) {
133
+ const tables = [];
134
+ let depth = 0;
135
+ for (let i = index - 1; i >= 0; i--) {
136
+ const statement = statements[i];
137
+ const s = statement.get();
138
+ if (s instanceof Statements.EndLoop) {
139
+ depth++;
140
+ }
141
+ else if (s instanceof Statements.Loop) {
142
+ if (depth === 0) {
143
+ const source = statement.findDirectExpression(Expressions.LoopSource);
144
+ if (source !== undefined) {
145
+ tables.push(source.concatTokens().toUpperCase());
146
+ }
147
+ }
148
+ else {
149
+ depth--;
150
+ }
151
+ }
152
+ else if (s instanceof Statements.MethodImplementation
153
+ || s instanceof Statements.Form
154
+ || s instanceof Statements.FunctionModule
155
+ || s instanceof Statements.Module) {
156
+ break;
157
+ }
158
+ }
159
+ return tables;
160
+ }
161
+ }
162
+ exports.DeleteIndexInLoop = DeleteIndexInLoop;
163
+ //# sourceMappingURL=delete_index_in_loop.js.map
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FinalNewline = exports.FinalNewlineConf = void 0;
4
+ const issue_1 = require("../issue");
5
+ const position_1 = require("../position");
6
+ const _basic_rule_config_1 = require("./_basic_rule_config");
7
+ const edit_helper_1 = require("../edit_helper");
8
+ const _irule_1 = require("./_irule");
9
+ const objects_1 = require("../objects");
10
+ class FinalNewlineConf extends _basic_rule_config_1.BasicRuleConfig {
11
+ }
12
+ exports.FinalNewlineConf = FinalNewlineConf;
13
+ class FinalNewline {
14
+ constructor() {
15
+ this.conf = new FinalNewlineConf();
16
+ }
17
+ getMetadata() {
18
+ return {
19
+ key: "final_newline",
20
+ title: "Final newline",
21
+ shortDescription: `Checks that ABAP and XML files end with exactly one newline`,
22
+ extendedInformation: `abapGit serializes every file with exactly one newline at the end. A file without it,
23
+ or with empty lines at the end, is changed again on the next pull and shows up in every diff.
24
+
25
+ Empty files and files containing only line breaks are not checked. A carriage return before the
26
+ newline is ignored, see rule line_break_style. SMIM and W3MI files and XSLT sources are not checked.`,
27
+ tags: [_irule_1.RuleTag.Whitespace, _irule_1.RuleTag.Quickfix, _irule_1.RuleTag.SingleFile],
28
+ badExample: `WRITE 'hello'.`,
29
+ goodExample: `WRITE 'hello'.\n`,
30
+ };
31
+ }
32
+ getConfig() {
33
+ return this.conf;
34
+ }
35
+ setConfig(conf) {
36
+ this.conf = conf;
37
+ }
38
+ initialize(_reg) {
39
+ return this;
40
+ }
41
+ run(obj) {
42
+ const issues = [];
43
+ if (obj instanceof objects_1.MIMEObject || obj instanceof objects_1.WebMIME) {
44
+ return issues;
45
+ }
46
+ for (const file of obj.getFiles()) {
47
+ const filename = file.getFilename();
48
+ if ((filename.endsWith(".abap") || filename.endsWith(".xml")) && !filename.endsWith(".xslt.source.xml")) {
49
+ const issue = this.checkFile(file);
50
+ if (issue) {
51
+ issues.push(issue);
52
+ }
53
+ }
54
+ }
55
+ return issues;
56
+ }
57
+ checkFile(file) {
58
+ const rows = file.getRawRows();
59
+ const last = rows[rows.length - 1];
60
+ if (last !== "") {
61
+ const end = new position_1.Position(rows.length, last.length + 1);
62
+ const fix = edit_helper_1.EditHelper.insertAt(file, end, "\n");
63
+ return issue_1.Issue.atPosition(file, end, "Add newline at end of file", this.getMetadata().key, this.conf.severity, fix);
64
+ }
65
+ let row = rows.length - 2;
66
+ while (row >= 0 && (rows[row] === "" || rows[row] === "\r")) {
67
+ row--;
68
+ }
69
+ if (row < 0 || row === rows.length - 2) {
70
+ return undefined;
71
+ }
72
+ const start = new position_1.Position(row + 2, 1);
73
+ const fix = edit_helper_1.EditHelper.deleteRange(file, start, new position_1.Position(rows.length, 1));
74
+ return issue_1.Issue.atPosition(file, start, "Remove empty lines at end of file", this.getMetadata().key, this.conf.severity, fix);
75
+ }
76
+ }
77
+ exports.FinalNewline = FinalNewline;
78
+ //# sourceMappingURL=final_newline.js.map
@@ -20,6 +20,7 @@ class ForbiddenIdentifier extends _abap_rule_1.ABAPRule {
20
20
  constructor() {
21
21
  super(...arguments);
22
22
  this.conf = new ForbiddenIdentifierConf();
23
+ this.checks = [];
23
24
  }
24
25
  getMetadata() {
25
26
  return {
@@ -39,9 +40,10 @@ https://github.com/abaplint/transpiler/blob/bda94b8b56e2b7f2f87be2168f12361aa530
39
40
  if (this.conf.check === undefined) {
40
41
  this.conf.check = [];
41
42
  }
43
+ this.checks = this.conf.check.map(c => new RegExp(c, "i"));
42
44
  }
43
45
  runParsed(file) {
44
- if (this.conf.check.length === 0) {
46
+ if (this.checks.length === 0) {
45
47
  return [];
46
48
  }
47
49
  let ret = [];
@@ -68,8 +70,7 @@ https://github.com/abaplint/transpiler/blob/bda94b8b56e2b7f2f87be2168f12361aa530
68
70
  check(token, file) {
69
71
  const str = token.getStr();
70
72
  const ret = [];
71
- for (const c of this.conf.check) {
72
- const reg = new RegExp(c, "i");
73
+ for (const reg of this.checks) {
73
74
  if (reg.exec(str)) {
74
75
  const message = "Identifer \"" + str + "\" not allowed";
75
76
  ret.push(issue_1.Issue.atToken(file, token, message, this.getMetadata().key, this.conf.severity));
@@ -22,6 +22,7 @@ exports.ForbiddenVoidTypeConf = ForbiddenVoidTypeConf;
22
22
  class ForbiddenVoidType {
23
23
  constructor() {
24
24
  this.conf = new ForbiddenVoidTypeConf();
25
+ this.checks = [];
25
26
  }
26
27
  getMetadata() {
27
28
  return {
@@ -41,13 +42,14 @@ DATS, TIMS, DATUM, FLAG, INT4, NUMC3, NUMC4, SAP_BOOL, TEXT25, TEXT80, X255, XFE
41
42
  if (this.conf.check === undefined) {
42
43
  this.conf.check = [];
43
44
  }
45
+ this.checks = this.conf.check.map(c => new RegExp(c, "i"));
44
46
  }
45
47
  initialize(reg) {
46
48
  this.reg = reg;
47
49
  return this;
48
50
  }
49
51
  run(obj) {
50
- if (!(obj instanceof _abap_object_1.ABAPObject) || this.conf.check.length === 0) {
52
+ if (!(obj instanceof _abap_object_1.ABAPObject) || this.checks.length === 0) {
51
53
  return [];
52
54
  }
53
55
  return this.traverse(new syntax_1.SyntaxLogic(this.reg, obj).run().spaghetti.getTop());
@@ -90,14 +92,7 @@ DATS, TIMS, DATUM, FLAG, INT4, NUMC3, NUMC4, SAP_BOOL, TEXT25, TEXT80, X255, XFE
90
92
  if (name === undefined) {
91
93
  return false;
92
94
  }
93
- for (const c of this.conf.check) {
94
- const reg = new RegExp(c, "i");
95
- const match = reg.test(name);
96
- if (match === true) {
97
- return true;
98
- }
99
- }
100
- return false;
95
+ return this.checks.some(reg => reg.test(name));
101
96
  }
102
97
  }
103
98
  exports.ForbiddenVoidType = ForbiddenVoidType;
@@ -16,6 +16,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./7bit_ascii"), exports);
18
18
  __exportStar(require("./abapdoc"), exports);
19
+ __exportStar(require("./abapdoc_html_tag"), exports);
20
+ __exportStar(require("./abapdoc_leading_at"), exports);
21
+ __exportStar(require("./abapdoc_parameter_names"), exports);
19
22
  __exportStar(require("./add_test_attributes"), exports);
20
23
  __exportStar(require("./aff_and_xml"), exports);
21
24
  __exportStar(require("./align_parameters"), exports);
@@ -38,6 +41,7 @@ __exportStar(require("./cds_naming"), exports);
38
41
  __exportStar(require("./cds_parser_error"), exports);
39
42
  __exportStar(require("./chain_mainly_declarations"), exports);
40
43
  __exportStar(require("./change_if_to_case"), exports);
44
+ __exportStar(require("./changing_sorted_line"), exports);
41
45
  __exportStar(require("./check_abstract"), exports);
42
46
  __exportStar(require("./check_comments"), exports);
43
47
  __exportStar(require("./check_ddic"), exports);
@@ -60,6 +64,7 @@ __exportStar(require("./cyclomatic_complexity"), exports);
60
64
  __exportStar(require("./dangerous_statement"), exports);
61
65
  __exportStar(require("./db_operation_in_loop"), exports);
62
66
  __exportStar(require("./definitions_top"), exports);
67
+ __exportStar(require("./delete_index_in_loop"), exports);
63
68
  __exportStar(require("./description_empty"), exports);
64
69
  __exportStar(require("./double_space"), exports);
65
70
  __exportStar(require("./downport"), exports);
@@ -73,6 +78,7 @@ __exportStar(require("./else_after_all_returns"), exports);
73
78
  __exportStar(require("./exit_or_check"), exports);
74
79
  __exportStar(require("./expand_macros"), exports);
75
80
  __exportStar(require("./exporting"), exports);
81
+ __exportStar(require("./final_newline"), exports);
76
82
  __exportStar(require("./fm_global_parameters_obsolete"), exports);
77
83
  __exportStar(require("./forbidden_identifier"), exports);
78
84
  __exportStar(require("./forbidden_pseudo_and_pragma"), exports);
@@ -96,6 +102,7 @@ __exportStar(require("./in_statement_indentation"), exports);
96
102
  __exportStar(require("./indentation"), exports);
97
103
  __exportStar(require("./index_completely_contained"), exports);
98
104
  __exportStar(require("./inline_data_old_versions"), exports);
105
+ __exportStar(require("./inline_packed_computation"), exports);
99
106
  __exportStar(require("./intf_referencing_clas"), exports);
100
107
  __exportStar(require("./invalid_table_index"), exports);
101
108
  __exportStar(require("./keep_single_parameter_on_one_line"), exports);
@@ -147,6 +154,7 @@ __exportStar(require("./parser_missing_space"), exports);
147
154
  __exportStar(require("./pragma_style"), exports);
148
155
  __exportStar(require("./prefer_corresponding"), exports);
149
156
  __exportStar(require("./prefer_inline"), exports);
157
+ __exportStar(require("./prefer_inline_cast"), exports);
150
158
  __exportStar(require("./prefer_insert_into_table"), exports);
151
159
  __exportStar(require("./prefer_is_not"), exports);
152
160
  __exportStar(require("./prefer_pragmas"), exports);
@@ -159,6 +167,7 @@ __exportStar(require("./prefer_xsdbool"), exports);
159
167
  __exportStar(require("./preferred_compare_operator"), exports);
160
168
  __exportStar(require("./preferred_parameter_ignored"), exports);
161
169
  __exportStar(require("./prefix_is_current_class"), exports);
170
+ __exportStar(require("./range_row_values"), exports);
162
171
  __exportStar(require("./reduce_procedural_code"), exports);
163
172
  __exportStar(require("./reduce_string_templates"), exports);
164
173
  __exportStar(require("./redundant_conversion"), exports);
@@ -175,6 +184,7 @@ __exportStar(require("./short_case"), exports);
175
184
  __exportStar(require("./sicf_consistency"), exports);
176
185
  __exportStar(require("./slow_parameter_passing"), exports);
177
186
  __exportStar(require("./smim_consistency"), exports);
187
+ __exportStar(require("./sort_empty_key"), exports);
178
188
  __exportStar(require("./space_before_colon"), exports);
179
189
  __exportStar(require("./space_before_dot"), exports);
180
190
  __exportStar(require("./sql_escape_host_variables"), exports);
@@ -182,6 +192,7 @@ __exportStar(require("./sql_value_conversion"), exports);
182
192
  __exportStar(require("./start_at_tab"), exports);
183
193
  __exportStar(require("./static_call_via_instance"), exports);
184
194
  __exportStar(require("./strict_sql"), exports);
195
+ __exportStar(require("./subrc_after_assign"), exports);
185
196
  __exportStar(require("./superclass_final"), exports);
186
197
  __exportStar(require("./superfluous_value"), exports);
187
198
  __exportStar(require("./sy_modification"), exports);
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.InlinePackedComputation = exports.InlinePackedComputationConf = void 0;
37
+ const Expressions = __importStar(require("../abap/2_statements/expressions"));
38
+ const Statements = __importStar(require("../abap/2_statements/statements"));
39
+ const _reference_1 = require("../abap/5_syntax/_reference");
40
+ const constant_1 = require("../abap/5_syntax/expressions/constant");
41
+ const syntax_1 = require("../abap/5_syntax/syntax");
42
+ const nodes_1 = require("../abap/nodes");
43
+ const types_1 = require("../abap/types");
44
+ const _typed_identifier_1 = require("../abap/types/_typed_identifier");
45
+ const basic_1 = require("../abap/types/basic");
46
+ const issue_1 = require("../issue");
47
+ const _abap_object_1 = require("../objects/_abap_object");
48
+ const _basic_rule_config_1 = require("./_basic_rule_config");
49
+ class InlinePackedComputationConf extends _basic_rule_config_1.BasicRuleConfig {
50
+ }
51
+ exports.InlinePackedComputationConf = InlinePackedComputationConf;
52
+ class InlinePackedComputation {
53
+ constructor() {
54
+ this.conf = new InlinePackedComputationConf();
55
+ }
56
+ getMetadata() {
57
+ return {
58
+ key: "inline_packed_computation",
59
+ title: "Inline declaration from a packed computation",
60
+ shortDescription: `Finds inline declarations whose value is an arithmetic expression with calculation type p`,
61
+ extendedInformation: `The result of a computation with calculation type p has no length and number of decimals
62
+ that a declaration could take over, so DATA( ) or FINAL( ) gets the type p LENGTH 8 DECIMALS 0 and the
63
+ syntax check warns "For the result of a computation with type P, the type P(8,0) is used here implicitly".
64
+ Decimals of the operands are lost, and so are digits beyond the length.
65
+
66
+ Reported when at least one operand is packed and all other operands are of type i, int8 or p. Operands
67
+ of other types, generic or unknown types, and the operator ** are not reported.
68
+
69
+ Declare the variable with the operands' type, or name the type with CONV.`,
70
+ tags: [],
71
+ badExample: `DATA a TYPE p LENGTH 8 DECIMALS 2.
72
+ DATA b TYPE p LENGTH 8 DECIMALS 2.
73
+ DATA(diff) = a - b.`,
74
+ goodExample: `DATA a TYPE p LENGTH 8 DECIMALS 2.
75
+ DATA b TYPE p LENGTH 8 DECIMALS 2.
76
+ DATA diff LIKE a.
77
+ diff = a - b.`,
78
+ };
79
+ }
80
+ getConfig() {
81
+ return this.conf;
82
+ }
83
+ setConfig(conf) {
84
+ this.conf = conf;
85
+ }
86
+ initialize(reg) {
87
+ this.reg = reg;
88
+ return this;
89
+ }
90
+ run(obj) {
91
+ var _a, _b;
92
+ if (!(obj instanceof _abap_object_1.ABAPObject)) {
93
+ return [];
94
+ }
95
+ const syntax = new syntax_1.SyntaxLogic(this.reg, obj).run();
96
+ if (syntax.issues.length > 0) {
97
+ return [];
98
+ }
99
+ const issues = [];
100
+ for (const file of obj.getABAPFiles()) {
101
+ for (const statement of file.getStatements()) {
102
+ if (!(statement.get() instanceof Statements.Move)) {
103
+ continue;
104
+ }
105
+ const inline = (_a = statement.findDirectExpression(Expressions.Target)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.InlineData);
106
+ const name = (_b = inline === null || inline === void 0 ? void 0 : inline.findDirectExpression(Expressions.TargetField)) === null || _b === void 0 ? void 0 : _b.getFirstToken();
107
+ const source = statement.findDirectExpression(Expressions.Source);
108
+ if (name === undefined
109
+ || source === undefined
110
+ || source.findDirectExpression(Expressions.ArithOperator) === undefined) {
111
+ continue;
112
+ }
113
+ const scope = syntax.spaghetti.lookupPosition(name.getStart(), file.getFilename());
114
+ if (scope === undefined) {
115
+ continue;
116
+ }
117
+ const operands = this.operandTypes(source, scope);
118
+ if (operands === undefined || operands.some(t => t instanceof basic_1.PackedType) === false) {
119
+ continue;
120
+ }
121
+ const message = `"${name.getStr()}" gets type p LENGTH 8 DECIMALS 0 from this packed computation, ` +
122
+ `declare it with the operands' type or use CONV`;
123
+ issues.push(issue_1.Issue.atToken(file, name, message, this.getMetadata().key, this.conf.severity));
124
+ }
125
+ }
126
+ return issues;
127
+ }
128
+ /** The types of the operands of an arithmetic expression, undefined when an operand is not of type
129
+ * i, int8 or p, or is not known */
130
+ operandTypes(source, scope) {
131
+ const ret = [];
132
+ for (const child of source.getChildren()) {
133
+ let found = undefined;
134
+ if (child instanceof nodes_1.TokenNode) {
135
+ // parentheses and a sign, anything else is a constructor expression or a string operator
136
+ if (["(", ")", "+", "-"].includes(child.getFirstToken().getStr()) === false) {
137
+ return undefined;
138
+ }
139
+ continue;
140
+ }
141
+ else if (child.get() instanceof Expressions.ArithOperator) {
142
+ if (["+", "-", "*", "/", "DIV", "MOD"].includes(child.concatTokens().toUpperCase()) === false) {
143
+ return undefined;
144
+ }
145
+ continue;
146
+ }
147
+ else if (child.get() instanceof Expressions.Source) {
148
+ const nested = this.operandTypes(child, scope);
149
+ if (nested === undefined) {
150
+ return undefined;
151
+ }
152
+ ret.push(...nested);
153
+ continue;
154
+ }
155
+ else if (child.get() instanceof Expressions.FieldChain) {
156
+ found = this.fieldChainType(child, scope);
157
+ }
158
+ else if (child.get() instanceof Expressions.MethodCallChain) {
159
+ found = this.methodCallType(child, scope);
160
+ }
161
+ else if (child.get() instanceof Expressions.Constant) {
162
+ found = constant_1.Constant.runSyntax(child);
163
+ }
164
+ if (found === undefined
165
+ || found.isGeneric()
166
+ || !(found instanceof basic_1.PackedType || found instanceof basic_1.IntegerType || found instanceof basic_1.Integer8Type)) {
167
+ return undefined;
168
+ }
169
+ ret.push(found);
170
+ }
171
+ return ret;
172
+ }
173
+ methodCallType(chain, scope) {
174
+ var _a, _b, _c;
175
+ const last = chain.getLastChild();
176
+ if (!(last instanceof nodes_1.ExpressionNode) || !(last.get() instanceof Expressions.MethodCall)) {
177
+ return undefined;
178
+ }
179
+ const name = (_a = last.findDirectExpression(Expressions.MethodName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
180
+ if (name === undefined) {
181
+ return undefined;
182
+ }
183
+ const method = (_b = scope.getData().references.find(reference => reference.referenceType === _reference_1.ReferenceType.MethodReference
184
+ && reference.position.getStart().equals(name.getStart()))) === null || _b === void 0 ? void 0 : _b.resolved;
185
+ if (!(method instanceof types_1.MethodDefinition)) {
186
+ return undefined;
187
+ }
188
+ return (_c = method.getParameters().getReturning()) === null || _c === void 0 ? void 0 : _c.getType();
189
+ }
190
+ fieldChainType(fieldChain, scope) {
191
+ var _a;
192
+ const operand = (_a = scope.getData().references.find(reference => reference.referenceType === _reference_1.ReferenceType.DataReadReference
193
+ && reference.position.getStart().equals(fieldChain.getFirstToken().getStart()))) === null || _a === void 0 ? void 0 : _a.resolved;
194
+ if (!(operand instanceof _typed_identifier_1.TypedIdentifier)) {
195
+ return undefined;
196
+ }
197
+ let type = operand.getType();
198
+ for (const child of fieldChain.getChildren()) {
199
+ if (!(child instanceof nodes_1.ExpressionNode)
200
+ || child.get() instanceof Expressions.SourceField) {
201
+ continue;
202
+ }
203
+ else if (child.get() instanceof Expressions.ComponentName) {
204
+ if (type instanceof basic_1.TableType) {
205
+ type = type.getRowType();
206
+ }
207
+ if (!(type instanceof basic_1.StructureType)) {
208
+ return undefined;
209
+ }
210
+ type = type.getComponentByName(child.concatTokens());
211
+ }
212
+ else {
213
+ return undefined;
214
+ }
215
+ }
216
+ return type;
217
+ }
218
+ }
219
+ exports.InlinePackedComputation = InlinePackedComputation;
220
+ //# sourceMappingURL=inline_packed_computation.js.map
@@ -20,6 +20,7 @@ exports.IntfReferencingClasConf = IntfReferencingClasConf;
20
20
  class IntfReferencingClas {
21
21
  constructor() {
22
22
  this.conf = new IntfReferencingClasConf();
23
+ this.allow = [];
23
24
  }
24
25
  getMetadata() {
25
26
  return {
@@ -40,6 +41,7 @@ class IntfReferencingClas {
40
41
  }
41
42
  setConfig(conf) {
42
43
  this.conf = conf;
44
+ this.allow = (this.conf.allow || []).map(reg => new RegExp(reg, "i"));
43
45
  }
44
46
  initialize(reg) {
45
47
  this.reg = reg;
@@ -65,7 +67,7 @@ class IntfReferencingClas {
65
67
  if (found && ddic.isException(found.getClassDefinition(), found)) {
66
68
  continue;
67
69
  }
68
- else if (this.getConfig().allow.some(reg => new RegExp(reg, "i").test(r.extra.ooName))) {
70
+ else if (this.allow.some(reg => reg.test(r.extra.ooName))) {
69
71
  continue;
70
72
  }
71
73
  ret.push(issue_1.Issue.atIdentifier(r.position, message + r.extra.ooName, this.getMetadata().key, this.conf.severity));
@@ -57,7 +57,7 @@ https://docs.abapopenchecks.org/checks/16/`,
57
57
  }
58
58
  }
59
59
  const rows = file.getRawRows();
60
- const reg = new RegExp("^\\)?\\. *(\\\".*)?$");
60
+ const reg = /^\)?\. *(".*)?$/;
61
61
  for (let i = 0; i < rows.length; i++) {
62
62
  if (reg.exec(rows[i].trim())) {
63
63
  const column = rows[i].indexOf(")") >= 0 ? rows[i].indexOf(")") + 1 : rows[i].indexOf(".") + 1;