@abaplint/core 2.79.35 → 2.80.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.
Files changed (83) hide show
  1. package/README.md +6 -6
  2. package/build/abaplint.d.ts +18 -6
  3. package/build/src/abap/2_statements/expressions/function_exporting.js +2 -6
  4. package/build/src/abap/2_statements/expressions/function_exporting_parameter.js +17 -0
  5. package/build/src/abap/2_statements/expressions/index.js +2 -1
  6. package/build/src/abap/3_structures/structures/cleanup.js +14 -0
  7. package/build/src/abap/3_structures/structures/index.js +3 -2
  8. package/build/src/abap/3_structures/structures/try.js +2 -2
  9. package/build/src/abap/flow/statement_flow.js +126 -11
  10. package/build/src/abap/nodes/structure_node.js +12 -0
  11. package/build/src/lsp/help.js +7 -7
  12. package/build/src/lsp/language_server.js +12 -0
  13. package/build/src/registry.js +1 -1
  14. package/build/src/rules/abapdoc.js +1 -1
  15. package/build/src/rules/align_parameters.js +131 -0
  16. package/build/src/rules/ambiguous_statement.js +5 -5
  17. package/build/src/rules/avoid_use.js +6 -6
  18. package/build/src/rules/begin_end_names.js +4 -4
  19. package/build/src/rules/begin_single_include.js +12 -12
  20. package/build/src/rules/call_transaction_authority_check.js +3 -3
  21. package/build/src/rules/chain_mainly_declarations.js +4 -4
  22. package/build/src/rules/check_abstract.js +2 -2
  23. package/build/src/rules/check_comments.js +3 -3
  24. package/build/src/rules/check_include.js +3 -3
  25. package/build/src/rules/check_no_handler_pragma.js +8 -8
  26. package/build/src/rules/check_subrc.js +8 -8
  27. package/build/src/rules/commented_code.js +1 -1
  28. package/build/src/rules/constructor_visibility_public.js +4 -4
  29. package/build/src/rules/contains_tab.js +2 -2
  30. package/build/src/rules/dangerous_statement.js +1 -1
  31. package/build/src/rules/downport.js +35 -35
  32. package/build/src/rules/exit_or_check.js +3 -3
  33. package/build/src/rules/exporting.js +1 -1
  34. package/build/src/rules/forbidden_identifier.js +1 -1
  35. package/build/src/rules/forbidden_void_type.js +2 -2
  36. package/build/src/rules/functional_writing.js +17 -17
  37. package/build/src/rules/global_class.js +10 -10
  38. package/build/src/rules/identical_conditions.js +2 -2
  39. package/build/src/rules/identical_contents.js +15 -15
  40. package/build/src/rules/identical_descriptions.js +4 -4
  41. package/build/src/rules/if_in_if.js +7 -7
  42. package/build/src/rules/implement_methods.js +3 -3
  43. package/build/src/rules/in_statement_indentation.js +11 -11
  44. package/build/src/rules/index.js +2 -1
  45. package/build/src/rules/intf_referencing_clas.js +3 -3
  46. package/build/src/rules/line_break_style.js +2 -2
  47. package/build/src/rules/line_length.js +1 -1
  48. package/build/src/rules/line_only_punc.js +1 -1
  49. package/build/src/rules/local_variable_names.js +2 -2
  50. package/build/src/rules/many_parentheses.js +10 -10
  51. package/build/src/rules/max_one_method_parameter_per_line.js +7 -7
  52. package/build/src/rules/max_one_statement.js +3 -3
  53. package/build/src/rules/nesting.js +1 -1
  54. package/build/src/rules/no_public_attributes.js +1 -1
  55. package/build/src/rules/no_yoda_conditions.js +4 -4
  56. package/build/src/rules/obsolete_statement.js +36 -36
  57. package/build/src/rules/omit_parameter_name.js +3 -3
  58. package/build/src/rules/omit_receiving.js +13 -13
  59. package/build/src/rules/parser_702_chaining.js +2 -2
  60. package/build/src/rules/parser_error.js +2 -2
  61. package/build/src/rules/parser_missing_space.js +1 -1
  62. package/build/src/rules/prefer_inline.js +16 -16
  63. package/build/src/rules/prefer_is_not.js +7 -7
  64. package/build/src/rules/prefer_raise_exception_new.js +3 -3
  65. package/build/src/rules/prefer_returning_to_exporting.js +1 -1
  66. package/build/src/rules/prefer_xsdbool.js +2 -2
  67. package/build/src/rules/remove_descriptions.js +4 -4
  68. package/build/src/rules/rfc_error_handling.js +9 -9
  69. package/build/src/rules/select_add_order_by.js +5 -5
  70. package/build/src/rules/select_performance.js +2 -2
  71. package/build/src/rules/sicf_consistency.js +4 -4
  72. package/build/src/rules/space_before_dot.js +2 -2
  73. package/build/src/rules/start_at_tab.js +1 -1
  74. package/build/src/rules/sy_modification.js +2 -2
  75. package/build/src/rules/tabl_enhancement_category.js +2 -2
  76. package/build/src/rules/try_without_catch.js +1 -2
  77. package/build/src/rules/unused_methods.js +9 -9
  78. package/build/src/rules/unused_variables.js +6 -6
  79. package/build/src/rules/use_bool_expression.js +8 -8
  80. package/build/src/rules/use_line_exists.js +6 -6
  81. package/build/src/rules/use_new.js +2 -2
  82. package/build/src/rules/when_others_last.js +6 -6
  83. package/package.json +76 -76
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
- # @abaplint/core
2
-
3
- [abaplint](https://abaplint.org/) core library
4
-
5
- Exposes functionallity like the parser and rules, which can be used in other projects.
6
-
1
+ # @abaplint/core
2
+
3
+ [abaplint](https://abaplint.org/) core library
4
+
5
+ Exposes functionallity like the parser and rules, which can be used in other projects.
6
+
7
7
  For more information see https://github.com/abaplint/abaplint
@@ -756,7 +756,11 @@ declare class ClassName extends Expression {
756
756
  getRunnable(): IStatementRunnable;
757
757
  }
758
758
 
759
- declare class Cleanup implements IStatement {
759
+ declare class Cleanup implements IStructure {
760
+ getMatcher(): IStructureRunnable;
761
+ }
762
+
763
+ declare class Cleanup_2 implements IStatement {
760
764
  getMatcher(): IStatementRunnable;
761
765
  }
762
766
 
@@ -1655,7 +1659,6 @@ declare namespace Expressions {
1655
1659
  ClassGlobal_2 as ClassGlobal,
1656
1660
  ClassName,
1657
1661
  Color,
1658
- FindType,
1659
1662
  CompareOperator,
1660
1663
  Compare,
1661
1664
  ComponentChainSimple,
@@ -1701,6 +1704,7 @@ declare namespace Expressions {
1701
1704
  Field,
1702
1705
  FilterBody,
1703
1706
  FinalMethods,
1707
+ FindType,
1704
1708
  For,
1705
1709
  FormChanging,
1706
1710
  FormName,
@@ -1711,6 +1715,7 @@ declare namespace Expressions {
1711
1715
  FormTables,
1712
1716
  FormUsing,
1713
1717
  FSTarget,
1718
+ FunctionExportingParameter,
1714
1719
  FunctionExporting,
1715
1720
  FunctionName,
1716
1721
  FunctionParameters,
@@ -2046,6 +2051,10 @@ declare class FunctionExporting extends Expression {
2046
2051
  getRunnable(): IStatementRunnable;
2047
2052
  }
2048
2053
 
2054
+ declare class FunctionExportingParameter extends Expression {
2055
+ getRunnable(): IStatementRunnable;
2056
+ }
2057
+
2049
2058
  declare class FunctionGroup extends ABAPObject {
2050
2059
  private includes;
2051
2060
  private modules;
@@ -3240,6 +3249,7 @@ export declare class LanguageServer {
3240
3249
  listDefinitionPositions(textDocument: LServer.TextDocumentIdentifier): LServer.Range[];
3241
3250
  listReadPositions(textDocument: LServer.TextDocumentIdentifier): LServer.Range[];
3242
3251
  listWritePositions(textDocument: LServer.TextDocumentIdentifier): LServer.Range[];
3252
+ dumpStatementFlows(textDocument: LServer.TextDocumentIdentifier): string;
3243
3253
  }
3244
3254
 
3245
3255
  declare namespace LanguageServerTypes {
@@ -5026,7 +5036,7 @@ declare namespace Statements {
5026
5036
  TypeBegin,
5027
5037
  TypeEnd,
5028
5038
  RaiseEvent,
5029
- Cleanup,
5039
+ Cleanup_2 as Cleanup,
5030
5040
  CreateOLE,
5031
5041
  CallOLE,
5032
5042
  SetProperty,
@@ -5121,6 +5131,7 @@ declare class StructureNode extends AbstractNode<StructureNode | StatementNode>
5121
5131
  getFirstToken(): Token;
5122
5132
  getLastToken(): Token;
5123
5133
  findAllExpressions(type: new () => IStatementRunnable): ExpressionNode[];
5134
+ findAllExpressionsRecursive(type: new () => IStatementRunnable): ExpressionNode[];
5124
5135
  findAllExpressionsMulti(type: (new () => IStatementRunnable)[]): ExpressionNode[];
5125
5136
  findAllStatements(type: new () => IStatement): StatementNode[];
5126
5137
  findAllStatementNodes(): StatementNode[];
@@ -5143,7 +5154,7 @@ declare namespace Structures {
5143
5154
  ClassDefinition,
5144
5155
  ClassGlobal,
5145
5156
  ClassImplementation,
5146
- SectionContents,
5157
+ Cleanup,
5147
5158
  Constants,
5148
5159
  Data,
5149
5160
  Define,
@@ -5167,6 +5178,7 @@ declare namespace Structures {
5167
5178
  ProtectedSection,
5168
5179
  Provide,
5169
5180
  PublicSection,
5181
+ SectionContents,
5170
5182
  Select,
5171
5183
  Statics,
5172
5184
  TestInjection,
@@ -5176,8 +5188,8 @@ declare namespace Structures {
5176
5188
  Types_2 as Types,
5177
5189
  WhenType,
5178
5190
  When,
5179
- With,
5180
- While
5191
+ While,
5192
+ With
5181
5193
  }
5182
5194
  }
5183
5195
  export { Structures }
@@ -2,14 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FunctionExporting = void 0;
4
4
  const combi_1 = require("../combi");
5
- const parameter_name_1 = require("./parameter_name");
6
- const source_1 = require("./source");
7
- const version_1 = require("../../../version");
8
- const simple_source3_1 = require("./simple_source3");
5
+ const _1 = require(".");
9
6
  class FunctionExporting extends combi_1.Expression {
10
7
  getRunnable() {
11
- const s = (0, combi_1.altPrio)((0, combi_1.ver)(version_1.Version.v740sp02, source_1.Source), simple_source3_1.SimpleSource3);
12
- const exp = (0, combi_1.plusPrio)((0, combi_1.seq)(parameter_name_1.ParameterName, "=", s));
8
+ const exp = (0, combi_1.plusPrio)(_1.FunctionExportingParameter);
13
9
  return exp;
14
10
  }
15
11
  }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FunctionExportingParameter = void 0;
4
+ const combi_1 = require("../combi");
5
+ const parameter_name_1 = require("./parameter_name");
6
+ const source_1 = require("./source");
7
+ const version_1 = require("../../../version");
8
+ const simple_source3_1 = require("./simple_source3");
9
+ class FunctionExportingParameter extends combi_1.Expression {
10
+ getRunnable() {
11
+ const s = (0, combi_1.altPrio)((0, combi_1.ver)(version_1.Version.v740sp02, source_1.Source), simple_source3_1.SimpleSource3);
12
+ const exp = (0, combi_1.seq)(parameter_name_1.ParameterName, "=", s);
13
+ return exp;
14
+ }
15
+ }
16
+ exports.FunctionExportingParameter = FunctionExportingParameter;
17
+ //# sourceMappingURL=function_exporting_parameter.js.map
@@ -27,7 +27,6 @@ __exportStar(require("./class_friends"), exports);
27
27
  __exportStar(require("./class_global"), exports);
28
28
  __exportStar(require("./class_name"), exports);
29
29
  __exportStar(require("./color"), exports);
30
- __exportStar(require("./find_type"), exports);
31
30
  __exportStar(require("./compare_operator"), exports);
32
31
  __exportStar(require("./compare"), exports);
33
32
  __exportStar(require("./component_chain_simple"), exports);
@@ -73,6 +72,7 @@ __exportStar(require("./field_symbol"), exports);
73
72
  __exportStar(require("./field"), exports);
74
73
  __exportStar(require("./filter_body"), exports);
75
74
  __exportStar(require("./final_methods"), exports);
75
+ __exportStar(require("./find_type"), exports);
76
76
  __exportStar(require("./for"), exports);
77
77
  __exportStar(require("./form_changing"), exports);
78
78
  __exportStar(require("./form_name"), exports);
@@ -83,6 +83,7 @@ __exportStar(require("./form_raising"), exports);
83
83
  __exportStar(require("./form_tables"), exports);
84
84
  __exportStar(require("./form_using"), exports);
85
85
  __exportStar(require("./fstarget"), exports);
86
+ __exportStar(require("./function_exporting_parameter"), exports);
86
87
  __exportStar(require("./function_exporting"), exports);
87
88
  __exportStar(require("./function_name"), exports);
88
89
  __exportStar(require("./function_parameters"), exports);
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Cleanup = void 0;
4
+ const Statements = require("../../2_statements/statements");
5
+ const _combi_1 = require("./_combi");
6
+ const body_1 = require("./body");
7
+ class Cleanup {
8
+ getMatcher() {
9
+ const cleanup = (0, _combi_1.seq)((0, _combi_1.sta)(Statements.Cleanup), (0, _combi_1.opt)((0, _combi_1.sub)(body_1.Body)));
10
+ return cleanup;
11
+ }
12
+ }
13
+ exports.Cleanup = Cleanup;
14
+ //# sourceMappingURL=cleanup.js.map
@@ -21,7 +21,7 @@ __exportStar(require("./class_data"), exports);
21
21
  __exportStar(require("./class_definition"), exports);
22
22
  __exportStar(require("./class_global"), exports);
23
23
  __exportStar(require("./class_implementation"), exports);
24
- __exportStar(require("./section_section"), exports);
24
+ __exportStar(require("./cleanup"), exports);
25
25
  __exportStar(require("./constants"), exports);
26
26
  __exportStar(require("./data"), exports);
27
27
  __exportStar(require("./define"), exports);
@@ -45,6 +45,7 @@ __exportStar(require("./private_section"), exports);
45
45
  __exportStar(require("./protected_section"), exports);
46
46
  __exportStar(require("./provide"), exports);
47
47
  __exportStar(require("./public_section"), exports);
48
+ __exportStar(require("./section_section"), exports);
48
49
  __exportStar(require("./select"), exports);
49
50
  __exportStar(require("./statics"), exports);
50
51
  __exportStar(require("./test_injection"), exports);
@@ -54,6 +55,6 @@ __exportStar(require("./type_enum"), exports);
54
55
  __exportStar(require("./types"), exports);
55
56
  __exportStar(require("./when_type"), exports);
56
57
  __exportStar(require("./when"), exports);
57
- __exportStar(require("./with"), exports);
58
58
  __exportStar(require("./while"), exports);
59
+ __exportStar(require("./with"), exports);
59
60
  //# sourceMappingURL=index.js.map
@@ -5,10 +5,10 @@ const Statements = require("../../2_statements/statements");
5
5
  const _combi_1 = require("./_combi");
6
6
  const catch_1 = require("./catch");
7
7
  const body_1 = require("./body");
8
+ const cleanup_1 = require("./cleanup");
8
9
  class Try {
9
10
  getMatcher() {
10
- const cleanup = (0, _combi_1.seq)((0, _combi_1.sta)(Statements.Cleanup), (0, _combi_1.opt)((0, _combi_1.sub)(body_1.Body)));
11
- const block = (0, _combi_1.seq)((0, _combi_1.opt)((0, _combi_1.sub)(body_1.Body)), (0, _combi_1.star)((0, _combi_1.sub)(catch_1.Catch)), (0, _combi_1.opt)(cleanup));
11
+ const block = (0, _combi_1.seq)((0, _combi_1.opt)((0, _combi_1.sub)(body_1.Body)), (0, _combi_1.star)((0, _combi_1.sub)(catch_1.Catch)), (0, _combi_1.opt)((0, _combi_1.sub)(cleanup_1.Cleanup)));
12
12
  return (0, _combi_1.beginEnd)((0, _combi_1.sta)(Statements.Try), block, (0, _combi_1.sta)(Statements.EndTry));
13
13
  }
14
14
  }
@@ -1,15 +1,55 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StatementFlow = void 0;
3
+ exports.StatementFlow = exports.dumpFlow = void 0;
4
4
  const nodes_1 = require("../nodes");
5
5
  const Structures = require("../3_structures/structures");
6
6
  const Statements = require("../2_statements/statements");
7
+ function dumpFlow(flows) {
8
+ const ret = "[" + flows.map(f => "[" + f.statements.map(b => b === null || b === void 0 ? void 0 : b.get().constructor.name).join(",") + "]").join(",");
9
+ return ret + "]";
10
+ }
11
+ exports.dumpFlow = dumpFlow;
7
12
  function findBody(f) {
8
13
  var _a;
9
14
  return ((_a = f.findDirectStructure(Structures.Body)) === null || _a === void 0 ? void 0 : _a.getChildren()) || [];
10
- //function findBody(f: StructureNode): StructureNode | undefined {
11
- // return f.findDirectStructure(Structures.Body);
12
15
  }
16
+ function removeDuplicates(flows) {
17
+ const result = [];
18
+ for (const f of flows) {
19
+ let duplicate = false;
20
+ for (const r of result) {
21
+ if (f.statements.length !== r.statements.length) {
22
+ continue;
23
+ }
24
+ duplicate = true;
25
+ for (let index = 0; index < f.statements.length; index++) {
26
+ if (f.statements[index] !== r.statements[index]) {
27
+ duplicate = false;
28
+ break;
29
+ }
30
+ }
31
+ }
32
+ if (duplicate === false) {
33
+ result.push(f);
34
+ }
35
+ }
36
+ return result;
37
+ }
38
+ function pruneByStatement(flows, type) {
39
+ const result = [];
40
+ for (const f of flows) {
41
+ const nodes = [];
42
+ for (const n of f.statements) {
43
+ nodes.push(n);
44
+ if (n.get() instanceof type) {
45
+ break;
46
+ }
47
+ }
48
+ result.push({ statements: nodes });
49
+ }
50
+ return removeDuplicates(result);
51
+ }
52
+ ////////////////////////////////////////////////////////////////
13
53
  class StatementFlow {
14
54
  build(stru) {
15
55
  const ret = [];
@@ -17,6 +57,10 @@ class StatementFlow {
17
57
  for (const f of forms) {
18
58
  ret.push(...this.traverseBody(findBody(f)));
19
59
  }
60
+ const methods = stru.findAllStructures(Structures.Method);
61
+ for (const f of methods) {
62
+ ret.push(...this.traverseBody(findBody(f)));
63
+ }
20
64
  return ret;
21
65
  }
22
66
  traverseBody(children) {
@@ -33,8 +77,8 @@ class StatementFlow {
33
77
  flows.forEach(f => f.statements.push(firstChild));
34
78
  // current.push(firstChild);
35
79
  // console.dir("push: " + firstChild.constructor.name);
36
- if (firstChild.get() instanceof Statements.Check) {
37
- // todo
80
+ if (firstChild.get() instanceof Statements.Check
81
+ || firstChild.get() instanceof Statements.Assert) {
38
82
  const after = children.slice(i + 1, children.length);
39
83
  for (const b of this.traverseBody(after)) {
40
84
  for (const f of [...flows]) {
@@ -43,6 +87,9 @@ class StatementFlow {
43
87
  }
44
88
  break;
45
89
  }
90
+ else if (firstChild.get() instanceof Statements.Exit) {
91
+ break;
92
+ }
46
93
  else if (firstChild.get() instanceof Statements.Return) {
47
94
  break;
48
95
  }
@@ -60,14 +107,13 @@ class StatementFlow {
60
107
  }
61
108
  // console.dir(dump(n));
62
109
  flows = n;
63
- // found.forEach(fo => flows.forEach(f => f.statements.push(...fo.statements)));
64
110
  }
65
111
  }
66
112
  }
67
113
  return flows;
68
114
  }
69
115
  traverseStructure(n) {
70
- const flows = [];
116
+ let flows = [];
71
117
  if (n === undefined) {
72
118
  return flows;
73
119
  }
@@ -80,7 +126,6 @@ class StatementFlow {
80
126
  flows.push(...bodyFlows);
81
127
  }
82
128
  else if (type instanceof Structures.Any) {
83
- // TODO TODO
84
129
  for (const c of n.getChildren()) {
85
130
  // console.dir("yep");
86
131
  if (c instanceof nodes_1.StructureNode && c.get() instanceof Structures.Form) {
@@ -94,6 +139,29 @@ class StatementFlow {
94
139
  }
95
140
  }
96
141
  }
142
+ else if (type instanceof Structures.Try) {
143
+ // TODO: this does not take exceptions into account
144
+ const firstTry = n.getFirstStatement();
145
+ let allPossibleBody = this.traverseBody(findBody(n));
146
+ allPossibleBody = allPossibleBody.map(b => { return { statements: [firstTry, ...b.statements] }; });
147
+ if (allPossibleBody.length === 0) {
148
+ allPossibleBody.push({ statements: [firstTry] });
149
+ }
150
+ flows.push(...allPossibleBody);
151
+ for (const c of n.findDirectStructures(Structures.Catch)) {
152
+ const firstCatch = c.getFirstStatement();
153
+ const catchBodies = this.traverseBody(findBody(c));
154
+ for (const bodyFlow of allPossibleBody) {
155
+ for (const catchFlow of catchBodies) {
156
+ flows.push({ statements: [...bodyFlow.statements, firstCatch, ...catchFlow.statements] });
157
+ }
158
+ if (catchBodies.length === 0) {
159
+ flows.push({ statements: [...bodyFlow.statements, firstCatch] });
160
+ }
161
+ }
162
+ }
163
+ // TODO, handle CLEANUP
164
+ }
97
165
  else if (type instanceof Structures.If) {
98
166
  const collect = [n.findDirectStatement(Statements.If)];
99
167
  let bodyFlows = this.traverseBody(findBody(n));
@@ -120,18 +188,65 @@ class StatementFlow {
120
188
  flows.push({ statements: [...collect] });
121
189
  }
122
190
  }
123
- else if (type instanceof Structures.Loop) {
124
- const loop = n.findDirectStatement(Statements.Loop);
191
+ else if (type instanceof Structures.Case) {
192
+ const cas = n.getFirstStatement();
193
+ let othersFound = false;
194
+ for (const w of n.findDirectStructures(Structures.When)) {
195
+ const first = w.getFirstStatement();
196
+ if (first === undefined) {
197
+ continue;
198
+ }
199
+ if (first.get() instanceof Statements.WhenOthers) {
200
+ othersFound = true;
201
+ }
202
+ let bodyFlows = this.traverseBody(findBody(w));
203
+ bodyFlows = bodyFlows.map(b => { return { statements: [cas, first, ...b.statements] }; });
204
+ flows.push(...bodyFlows);
205
+ }
206
+ if (othersFound === false) {
207
+ flows.push({ statements: [cas] });
208
+ }
209
+ }
210
+ else if (type instanceof Structures.CaseType) {
211
+ const cas = n.getFirstStatement();
212
+ let othersFound = false;
213
+ for (const w of n.findDirectStructures(Structures.WhenType)) {
214
+ const first = w.getFirstStatement();
215
+ if (first === undefined) {
216
+ continue;
217
+ }
218
+ if (first.get() instanceof Statements.WhenOthers) {
219
+ othersFound = true;
220
+ }
221
+ let bodyFlows = this.traverseBody(findBody(w));
222
+ bodyFlows = bodyFlows.map(b => { return { statements: [cas, first, ...b.statements] }; });
223
+ flows.push(...bodyFlows);
224
+ }
225
+ if (othersFound === false) {
226
+ flows.push({ statements: [cas] });
227
+ }
228
+ }
229
+ else if (type instanceof Structures.Loop
230
+ || type instanceof Structures.While
231
+ || type instanceof Structures.With
232
+ || type instanceof Structures.Provide
233
+ || type instanceof Structures.Select
234
+ || type instanceof Structures.Do) {
235
+ const loop = n.getFirstStatement();
125
236
  const bodyFlows = this.traverseBody(findBody(n));
126
237
  for (const b of bodyFlows) {
127
238
  flows.push({ statements: [loop, ...b.statements] });
128
239
  }
129
240
  for (const b1 of bodyFlows) {
130
241
  for (const b2 of bodyFlows) {
131
- flows.push({ statements: [loop, ...b1.statements, ...b2.statements] });
242
+ const add = [loop, ...b1.statements, ...b2.statements];
243
+ flows.push({ statements: add });
132
244
  }
133
245
  }
134
246
  flows.push({ statements: [loop] });
247
+ flows = pruneByStatement(flows, Statements.Exit);
248
+ flows = pruneByStatement(flows, Statements.Continue);
249
+ flows = pruneByStatement(flows, Statements.Return);
135
250
  }
136
251
  else {
137
252
  console.dir("todo, " + n.get().constructor.name);
@@ -118,6 +118,18 @@ class StructureNode extends _abstract_node_1.AbstractNode {
118
118
  }
119
119
  return ret;
120
120
  }
121
+ findAllExpressionsRecursive(type) {
122
+ const ret = [];
123
+ for (const child of this.getChildren()) {
124
+ if (child instanceof statement_node_1.StatementNode) {
125
+ ret.push(...child.findAllExpressionsRecursive(type));
126
+ }
127
+ else {
128
+ ret.push(...child.findAllExpressionsRecursive(type));
129
+ }
130
+ }
131
+ return ret;
132
+ }
121
133
  findAllExpressionsMulti(type) {
122
134
  const ret = [];
123
135
  for (const child of this.getChildren()) {
@@ -9,13 +9,13 @@ const dump_scope_1 = require("./dump_scope");
9
9
  class Help {
10
10
  static find(reg, textDocument, position) {
11
11
  let content = "";
12
- content = `
13
- <a href="#_tokens" rel="no-refresh">Tokens</a> |
14
- <a href="#_statements" rel="no-refresh">Statements</a> |
15
- <a href="#_structure" rel="no-refresh">Structure</a> |
16
- <a href="#_files" rel="no-refresh">Files</a> |
17
- <a href="#_info" rel="no-refresh">Info Dump</a>
18
- <hr>
12
+ content = `
13
+ <a href="#_tokens" rel="no-refresh">Tokens</a> |
14
+ <a href="#_statements" rel="no-refresh">Statements</a> |
15
+ <a href="#_structure" rel="no-refresh">Structure</a> |
16
+ <a href="#_files" rel="no-refresh">Files</a> |
17
+ <a href="#_info" rel="no-refresh">Info Dump</a>
18
+ <hr>
19
19
  ` +
20
20
  "<tt>" + textDocument.uri + " (" +
21
21
  (position.line + 1) + ", " +
@@ -15,6 +15,7 @@ const code_actions_1 = require("./code_actions");
15
15
  const references_1 = require("./references");
16
16
  const implementation_1 = require("./implementation");
17
17
  const semantic_1 = require("./semantic");
18
+ const statement_flow_1 = require("../abap/flow/statement_flow");
18
19
  // note Ranges are zero based in LSP,
19
20
  // https://github.com/microsoft/language-server-protocol/blob/main/versions/protocol-2-x.md#range
20
21
  // but 1 based in abaplint
@@ -111,6 +112,17 @@ class LanguageServer {
111
112
  listWritePositions(textDocument) {
112
113
  return new highlight_1.Highlight(this.reg).listWritePositions(textDocument);
113
114
  }
115
+ dumpStatementFlows(textDocument) {
116
+ const file = _lsp_utils_1.LSPUtils.getABAPFile(this.reg, textDocument.uri);
117
+ if (file === undefined) {
118
+ return "file not found";
119
+ }
120
+ const stru = file.getStructure();
121
+ if (stru === undefined) {
122
+ return "empty structure";
123
+ }
124
+ return (0, statement_flow_1.dumpFlow)(new statement_flow_1.StatementFlow().build(stru)).replace(/\],\[/, "],\n[");
125
+ }
114
126
  }
115
127
  exports.LanguageServer = LanguageServer;
116
128
  //# sourceMappingURL=language_server.js.map
@@ -68,7 +68,7 @@ class Registry {
68
68
  }
69
69
  static abaplintVersion() {
70
70
  // magic, see build script "version.sh"
71
- return "2.79.35";
71
+ return "2.80.0";
72
72
  }
73
73
  getDDICReferences() {
74
74
  return this.references;
@@ -23,7 +23,7 @@ class Abapdoc extends _abap_rule_1.ABAPRule {
23
23
  return {
24
24
  key: "abapdoc",
25
25
  title: "Check abapdoc",
26
- shortDescription: `Various checks regarding abapdoc.
26
+ shortDescription: `Various checks regarding abapdoc.
27
27
  Base rule checks for existence of abapdoc for public class methods and all interface methods.`,
28
28
  tags: [_irule_1.RuleTag.SingleFile],
29
29
  };
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AlignParameters = exports.AlignParametersConf = void 0;
4
+ const issue_1 = require("../issue");
5
+ const Expressions = require("../abap/2_statements/expressions");
6
+ const _abap_rule_1 = require("./_abap_rule");
7
+ const _basic_rule_config_1 = require("./_basic_rule_config");
8
+ const _irule_1 = require("./_irule");
9
+ class AlignParametersConf extends _basic_rule_config_1.BasicRuleConfig {
10
+ }
11
+ exports.AlignParametersConf = AlignParametersConf;
12
+ class AlignParameters extends _abap_rule_1.ABAPRule {
13
+ constructor() {
14
+ super(...arguments);
15
+ this.conf = new AlignParametersConf();
16
+ }
17
+ getMetadata() {
18
+ return {
19
+ key: "align_parameters",
20
+ title: "Align Parameters",
21
+ shortDescription: `Checks for aligned parameters in function module calls.`,
22
+ extendedInformation: `https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#align-parameters`,
23
+ tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Styleguide],
24
+ badExample: `CALL FUNCTION 'FOOBAR'
25
+ EXPORTING
26
+ foo = 2
27
+ parameter = 3.`,
28
+ goodExample: `CALL FUNCTION 'FOOBAR'
29
+ EXPORTING
30
+ foo = 2
31
+ parameter = 3.`,
32
+ };
33
+ }
34
+ getConfig() {
35
+ return this.conf;
36
+ }
37
+ setConfig(conf) {
38
+ this.conf = conf;
39
+ }
40
+ runParsed(file) {
41
+ const issues = [];
42
+ const stru = file.getStructure();
43
+ if (stru === undefined) {
44
+ return issues; // parser error
45
+ }
46
+ const candidates = [];
47
+ candidates.push(...this.functionParameterCandidates(stru));
48
+ /* TODO,
49
+ stru.findAllExpressionsRecursive(Expressions.MethodCallParam);
50
+ stru.findAllExpressionsRecursive(Expressions.MethodParameters);
51
+ stru.findAllExpressionsRecursive(Expressions.ValueBody);
52
+ */
53
+ for (const c of candidates) {
54
+ const i = this.checkCandidate(c, file);
55
+ if (i) {
56
+ issues.push(i);
57
+ }
58
+ }
59
+ return issues;
60
+ }
61
+ checkCandidate(candidate, file) {
62
+ if (candidate.parameters.length === 0) {
63
+ return undefined;
64
+ }
65
+ let expectedEqualsColumn = 0;
66
+ for (const p of candidate.parameters) {
67
+ const currentCol = p.left.getLastToken().getCol() + p.left.getLastToken().getStr().length + 1;
68
+ if (currentCol > expectedEqualsColumn) {
69
+ expectedEqualsColumn = currentCol;
70
+ }
71
+ }
72
+ for (const p of candidate.parameters) {
73
+ if (p.eq.getCol() !== expectedEqualsColumn) {
74
+ const pos = candidate.parameters[0].eq;
75
+ const message = "Align parameters to column " + expectedEqualsColumn;
76
+ return issue_1.Issue.atPosition(file, pos, message, this.getMetadata().key);
77
+ }
78
+ }
79
+ return undefined;
80
+ }
81
+ functionParameterCandidates(stru) {
82
+ const candidates = [];
83
+ for (const fp of stru.findAllExpressionsRecursive(Expressions.FunctionParameters)) {
84
+ const parameters = [];
85
+ for (const p of fp.findAllExpressions(Expressions.FunctionExportingParameter)) {
86
+ const children = p.getChildren();
87
+ if (children.length < 3) {
88
+ continue; // unexpected
89
+ }
90
+ parameters.push({
91
+ left: children[0],
92
+ eq: children[1].getFirstToken().getStart(),
93
+ right: children[2],
94
+ });
95
+ }
96
+ for (const list of fp.findDirectExpressions(Expressions.ParameterListT)) {
97
+ for (const pt of list.findDirectExpressions(Expressions.ParameterT)) {
98
+ const children = pt.getChildren();
99
+ if (children.length < 3) {
100
+ continue; // unexpected
101
+ }
102
+ parameters.push({
103
+ left: children[0],
104
+ eq: children[1].getFirstToken().getStart(),
105
+ right: children[2],
106
+ });
107
+ }
108
+ }
109
+ const list = fp.findDirectExpression(Expressions.ParameterListExceptions);
110
+ if (list) {
111
+ for (const pt of list.findDirectExpressions(Expressions.ParameterException)) {
112
+ const children = pt.getChildren();
113
+ if (children.length < 3) {
114
+ continue; // unexpected
115
+ }
116
+ parameters.push({
117
+ left: children[0],
118
+ eq: children[1].getFirstToken().getStart(),
119
+ right: children[2],
120
+ });
121
+ }
122
+ }
123
+ if (parameters.length > 0) {
124
+ candidates.push({ parameters });
125
+ }
126
+ }
127
+ return candidates;
128
+ }
129
+ }
130
+ exports.AlignParameters = AlignParameters;
131
+ //# sourceMappingURL=align_parameters.js.map