@abaplint/core 2.79.32 → 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 (88) hide show
  1. package/README.md +6 -6
  2. package/build/abaplint.d.ts +22 -5
  3. package/build/src/abap/2_statements/expressions/find_type.js +12 -0
  4. package/build/src/abap/2_statements/expressions/function_exporting.js +2 -6
  5. package/build/src/abap/2_statements/expressions/function_exporting_parameter.js +17 -0
  6. package/build/src/abap/2_statements/expressions/index.js +2 -0
  7. package/build/src/abap/2_statements/statements/find.js +1 -2
  8. package/build/src/abap/2_statements/statements/replace.js +1 -2
  9. package/build/src/abap/3_structures/structures/cleanup.js +14 -0
  10. package/build/src/abap/3_structures/structures/index.js +3 -2
  11. package/build/src/abap/3_structures/structures/try.js +2 -2
  12. package/build/src/abap/5_syntax/basic_types.js +14 -7
  13. package/build/src/abap/flow/statement_flow.js +126 -11
  14. package/build/src/abap/nodes/structure_node.js +12 -0
  15. package/build/src/lsp/help.js +7 -7
  16. package/build/src/lsp/language_server.js +12 -0
  17. package/build/src/registry.js +1 -1
  18. package/build/src/rules/abapdoc.js +1 -1
  19. package/build/src/rules/align_parameters.js +131 -0
  20. package/build/src/rules/allowed_object_naming.js +1 -1
  21. package/build/src/rules/ambiguous_statement.js +5 -5
  22. package/build/src/rules/avoid_use.js +6 -6
  23. package/build/src/rules/begin_end_names.js +4 -4
  24. package/build/src/rules/begin_single_include.js +12 -12
  25. package/build/src/rules/call_transaction_authority_check.js +3 -3
  26. package/build/src/rules/chain_mainly_declarations.js +4 -4
  27. package/build/src/rules/check_abstract.js +2 -2
  28. package/build/src/rules/check_comments.js +3 -3
  29. package/build/src/rules/check_include.js +3 -3
  30. package/build/src/rules/check_no_handler_pragma.js +8 -8
  31. package/build/src/rules/check_subrc.js +8 -8
  32. package/build/src/rules/commented_code.js +1 -1
  33. package/build/src/rules/constructor_visibility_public.js +4 -4
  34. package/build/src/rules/contains_tab.js +2 -2
  35. package/build/src/rules/dangerous_statement.js +25 -0
  36. package/build/src/rules/downport.js +35 -35
  37. package/build/src/rules/exit_or_check.js +3 -3
  38. package/build/src/rules/exporting.js +1 -1
  39. package/build/src/rules/forbidden_identifier.js +1 -1
  40. package/build/src/rules/forbidden_void_type.js +2 -2
  41. package/build/src/rules/functional_writing.js +17 -17
  42. package/build/src/rules/global_class.js +10 -10
  43. package/build/src/rules/identical_conditions.js +2 -2
  44. package/build/src/rules/identical_contents.js +15 -15
  45. package/build/src/rules/identical_descriptions.js +4 -4
  46. package/build/src/rules/if_in_if.js +7 -7
  47. package/build/src/rules/implement_methods.js +3 -3
  48. package/build/src/rules/in_statement_indentation.js +11 -11
  49. package/build/src/rules/index.js +2 -1
  50. package/build/src/rules/intf_referencing_clas.js +3 -3
  51. package/build/src/rules/line_break_style.js +2 -2
  52. package/build/src/rules/line_length.js +1 -1
  53. package/build/src/rules/line_only_punc.js +1 -1
  54. package/build/src/rules/local_variable_names.js +2 -2
  55. package/build/src/rules/many_parentheses.js +10 -10
  56. package/build/src/rules/max_one_method_parameter_per_line.js +7 -7
  57. package/build/src/rules/max_one_statement.js +3 -3
  58. package/build/src/rules/nesting.js +1 -1
  59. package/build/src/rules/no_public_attributes.js +1 -1
  60. package/build/src/rules/no_yoda_conditions.js +4 -4
  61. package/build/src/rules/obsolete_statement.js +38 -39
  62. package/build/src/rules/omit_parameter_name.js +3 -3
  63. package/build/src/rules/omit_receiving.js +13 -13
  64. package/build/src/rules/parser_702_chaining.js +2 -2
  65. package/build/src/rules/parser_error.js +2 -2
  66. package/build/src/rules/parser_missing_space.js +1 -1
  67. package/build/src/rules/prefer_inline.js +16 -16
  68. package/build/src/rules/prefer_is_not.js +7 -7
  69. package/build/src/rules/prefer_raise_exception_new.js +3 -3
  70. package/build/src/rules/prefer_returning_to_exporting.js +1 -1
  71. package/build/src/rules/prefer_xsdbool.js +2 -2
  72. package/build/src/rules/remove_descriptions.js +4 -4
  73. package/build/src/rules/rfc_error_handling.js +9 -9
  74. package/build/src/rules/select_add_order_by.js +5 -5
  75. package/build/src/rules/select_performance.js +2 -2
  76. package/build/src/rules/sicf_consistency.js +4 -4
  77. package/build/src/rules/space_before_dot.js +2 -2
  78. package/build/src/rules/start_at_tab.js +1 -1
  79. package/build/src/rules/sy_modification.js +2 -2
  80. package/build/src/rules/tabl_enhancement_category.js +2 -2
  81. package/build/src/rules/try_without_catch.js +1 -2
  82. package/build/src/rules/unused_methods.js +9 -9
  83. package/build/src/rules/unused_variables.js +6 -6
  84. package/build/src/rules/use_bool_expression.js +8 -8
  85. package/build/src/rules/use_line_exists.js +6 -6
  86. package/build/src/rules/use_new.js +2 -2
  87. package/build/src/rules/when_others_last.js +6 -6
  88. 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
 
@@ -1700,6 +1704,7 @@ declare namespace Expressions {
1700
1704
  Field,
1701
1705
  FilterBody,
1702
1706
  FinalMethods,
1707
+ FindType,
1703
1708
  For,
1704
1709
  FormChanging,
1705
1710
  FormName,
@@ -1710,6 +1715,7 @@ declare namespace Expressions {
1710
1715
  FormTables,
1711
1716
  FormUsing,
1712
1717
  FSTarget,
1718
+ FunctionExportingParameter,
1713
1719
  FunctionExporting,
1714
1720
  FunctionName,
1715
1721
  FunctionParameters,
@@ -1915,6 +1921,10 @@ declare class Find implements IStatement {
1915
1921
  getMatcher(): IStatementRunnable;
1916
1922
  }
1917
1923
 
1924
+ declare class FindType extends Expression {
1925
+ getRunnable(): IStatementRunnable;
1926
+ }
1927
+
1918
1928
  declare class FloatingPointType extends AbstractType {
1919
1929
  private readonly length;
1920
1930
  constructor(length: number, qualifiedName?: string);
@@ -2041,6 +2051,10 @@ declare class FunctionExporting extends Expression {
2041
2051
  getRunnable(): IStatementRunnable;
2042
2052
  }
2043
2053
 
2054
+ declare class FunctionExportingParameter extends Expression {
2055
+ getRunnable(): IStatementRunnable;
2056
+ }
2057
+
2044
2058
  declare class FunctionGroup extends ABAPObject {
2045
2059
  private includes;
2046
2060
  private modules;
@@ -3235,6 +3249,7 @@ export declare class LanguageServer {
3235
3249
  listDefinitionPositions(textDocument: LServer.TextDocumentIdentifier): LServer.Range[];
3236
3250
  listReadPositions(textDocument: LServer.TextDocumentIdentifier): LServer.Range[];
3237
3251
  listWritePositions(textDocument: LServer.TextDocumentIdentifier): LServer.Range[];
3252
+ dumpStatementFlows(textDocument: LServer.TextDocumentIdentifier): string;
3238
3253
  }
3239
3254
 
3240
3255
  declare namespace LanguageServerTypes {
@@ -5021,7 +5036,7 @@ declare namespace Statements {
5021
5036
  TypeBegin,
5022
5037
  TypeEnd,
5023
5038
  RaiseEvent,
5024
- Cleanup,
5039
+ Cleanup_2 as Cleanup,
5025
5040
  CreateOLE,
5026
5041
  CallOLE,
5027
5042
  SetProperty,
@@ -5116,6 +5131,7 @@ declare class StructureNode extends AbstractNode<StructureNode | StatementNode>
5116
5131
  getFirstToken(): Token;
5117
5132
  getLastToken(): Token;
5118
5133
  findAllExpressions(type: new () => IStatementRunnable): ExpressionNode[];
5134
+ findAllExpressionsRecursive(type: new () => IStatementRunnable): ExpressionNode[];
5119
5135
  findAllExpressionsMulti(type: (new () => IStatementRunnable)[]): ExpressionNode[];
5120
5136
  findAllStatements(type: new () => IStatement): StatementNode[];
5121
5137
  findAllStatementNodes(): StatementNode[];
@@ -5138,7 +5154,7 @@ declare namespace Structures {
5138
5154
  ClassDefinition,
5139
5155
  ClassGlobal,
5140
5156
  ClassImplementation,
5141
- SectionContents,
5157
+ Cleanup,
5142
5158
  Constants,
5143
5159
  Data,
5144
5160
  Define,
@@ -5162,6 +5178,7 @@ declare namespace Structures {
5162
5178
  ProtectedSection,
5163
5179
  Provide,
5164
5180
  PublicSection,
5181
+ SectionContents,
5165
5182
  Select,
5166
5183
  Statics,
5167
5184
  TestInjection,
@@ -5171,8 +5188,8 @@ declare namespace Structures {
5171
5188
  Types_2 as Types,
5172
5189
  WhenType,
5173
5190
  When,
5174
- With,
5175
- While
5191
+ While,
5192
+ With
5176
5193
  }
5177
5194
  }
5178
5195
  export { Structures }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FindType = void 0;
4
+ const version_1 = require("../../../version");
5
+ const combi_1 = require("../combi");
6
+ class FindType extends combi_1.Expression {
7
+ getRunnable() {
8
+ return (0, combi_1.opt)((0, combi_1.alt)("REGEX", "SUBSTRING", (0, combi_1.ver)(version_1.Version.v755, "PCRE")));
9
+ }
10
+ }
11
+ exports.FindType = FindType;
12
+ //# sourceMappingURL=find_type.js.map
@@ -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
@@ -72,6 +72,7 @@ __exportStar(require("./field_symbol"), exports);
72
72
  __exportStar(require("./field"), exports);
73
73
  __exportStar(require("./filter_body"), exports);
74
74
  __exportStar(require("./final_methods"), exports);
75
+ __exportStar(require("./find_type"), exports);
75
76
  __exportStar(require("./for"), exports);
76
77
  __exportStar(require("./form_changing"), exports);
77
78
  __exportStar(require("./form_name"), exports);
@@ -82,6 +83,7 @@ __exportStar(require("./form_raising"), exports);
82
83
  __exportStar(require("./form_tables"), exports);
83
84
  __exportStar(require("./form_using"), exports);
84
85
  __exportStar(require("./fstarget"), exports);
86
+ __exportStar(require("./function_exporting_parameter"), exports);
85
87
  __exportStar(require("./function_exporting"), exports);
86
88
  __exportStar(require("./function_name"), exports);
87
89
  __exportStar(require("./function_parameters"), exports);
@@ -3,14 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Find = 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 Find {
8
7
  getMatcher() {
9
8
  // SUBMATCHES handling is a workaround
10
9
  const options = (0, combi_1.per)("IGNORING CASE", "RESPECTING CASE", "IN BYTE MODE", "IN CHARACTER MODE", (0, combi_1.seq)("OF", expressions_1.Source), (0, combi_1.seq)("FROM", expressions_1.Source), (0, combi_1.seq)("TO", expressions_1.Source), (0, combi_1.seq)("MATCH OFFSET", expressions_1.Target), (0, combi_1.seq)("MATCH LINE", expressions_1.Target), (0, combi_1.seq)("MATCH COUNT", expressions_1.Target), (0, combi_1.seq)("MATCH LENGTH", expressions_1.Target), (0, combi_1.seq)("LENGTH", expressions_1.Source), (0, combi_1.seq)("RESULTS", expressions_1.Target), (0, combi_1.seq)("SUBMATCHES", expressions_1.Target), (0, combi_1.seq)("SUBMATCHES", expressions_1.Target, expressions_1.Target), (0, combi_1.seq)("SUBMATCHES", (0, combi_1.plus)(expressions_1.Target)));
11
10
  const sectionLength = (0, combi_1.seq)("SECTION LENGTH", expressions_1.Source, "OF");
12
11
  const before = (0, combi_1.seq)((0, combi_1.optPrio)((0, combi_1.alt)("TABLE", "SECTION OFFSET", sectionLength)), expressions_1.Source);
13
- const ret = (0, combi_1.seq)("FIND", (0, combi_1.opt)((0, combi_1.alt)("FIRST OCCURRENCE OF", "ALL OCCURRENCES OF")), (0, combi_1.opt)((0, combi_1.alt)("REGEX", "SUBSTRING", (0, combi_1.ver)(version_1.Version.v755, "PCRE"))), expressions_1.Source, "IN", before, (0, combi_1.opt)(options));
12
+ const ret = (0, combi_1.seq)("FIND", (0, combi_1.opt)((0, combi_1.alt)("FIRST OCCURRENCE OF", "ALL OCCURRENCES OF")), expressions_1.FindType, expressions_1.Source, "IN", before, (0, combi_1.opt)(options));
14
13
  return ret;
15
14
  }
16
15
  }
@@ -3,13 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Replace = 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 Replace {
8
7
  getMatcher() {
9
8
  const length = (0, combi_1.seq)("LENGTH", expressions_1.Source);
10
9
  const offset = (0, combi_1.seq)("OFFSET", expressions_1.Source);
11
10
  const section = (0, combi_1.seq)((0, combi_1.opt)("IN"), "SECTION", (0, combi_1.per)(offset, length), "OF", expressions_1.Source);
12
- const source = (0, combi_1.seq)((0, combi_1.opt)("OF"), (0, combi_1.opt)((0, combi_1.alt)("REGEX", "SUBSTRING", (0, combi_1.ver)(version_1.Version.v755, "PCRE"))), expressions_1.Source);
11
+ const source = (0, combi_1.seq)((0, combi_1.opt)("OF"), expressions_1.FindType, expressions_1.Source);
13
12
  const cas = (0, combi_1.alt)("IGNORING CASE", "RESPECTING CASE");
14
13
  const repl = (0, combi_1.seq)("REPLACEMENT COUNT", expressions_1.Target);
15
14
  const replo = (0, combi_1.seq)("REPLACEMENT OFFSET", expressions_1.Target);
@@ -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
  }
@@ -164,7 +164,7 @@ class BasicTypes {
164
164
  }
165
165
  const type = this.scope.findTypePoolType(chainText);
166
166
  if (type) {
167
- this.scope.addReference(typeName.getFirstToken(), typ, _reference_1.ReferenceType.TypeReference, this.filename);
167
+ // this.scope.addReference(typeName.getFirstToken(), type, ReferenceType.TypeReference, this.filename);
168
168
  return type;
169
169
  }
170
170
  const ddic = this.scope.getDDIC().lookup(chainText);
@@ -474,13 +474,20 @@ class BasicTypes {
474
474
  const found = this.scope.findType(subs[0]);
475
475
  foundType = found === null || found === void 0 ? void 0 : found.getType();
476
476
  if (foundType === undefined) {
477
- const f = this.scope.getDDIC().lookupTableOrView(subs[0]);
478
- this.scope.getDDICReferences().addUsing(this.scope.getParentObj(), { object: f.object, filename: this.filename, token: expr.getFirstToken() });
479
- if (f.type instanceof _typed_identifier_1.TypedIdentifier) {
480
- foundType = f.type.getType();
477
+ const typePoolType = this.scope.findTypePoolType(subs[0]);
478
+ if (typePoolType) {
479
+ // this.scope.addReference(typeName.getFirstToken(), typePoolType, ReferenceType.TypeReference, this.filename);
480
+ foundType = typePoolType;
481
481
  }
482
- else {
483
- foundType = f.type;
482
+ if (foundType === undefined) {
483
+ const f = this.scope.getDDIC().lookupTableOrView(subs[0]);
484
+ this.scope.getDDICReferences().addUsing(this.scope.getParentObj(), { object: f.object, filename: this.filename, token: expr.getFirstToken() });
485
+ if (f.type instanceof _typed_identifier_1.TypedIdentifier) {
486
+ foundType = f.type.getType();
487
+ }
488
+ else {
489
+ foundType = f.type;
490
+ }
484
491
  }
485
492
  }
486
493
  else {
@@ -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.32";
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
  };