@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.
- package/README.md +6 -6
- package/build/abaplint.d.ts +18 -6
- package/build/src/abap/2_statements/expressions/function_exporting.js +2 -6
- package/build/src/abap/2_statements/expressions/function_exporting_parameter.js +17 -0
- package/build/src/abap/2_statements/expressions/index.js +2 -1
- package/build/src/abap/3_structures/structures/cleanup.js +14 -0
- package/build/src/abap/3_structures/structures/index.js +3 -2
- package/build/src/abap/3_structures/structures/try.js +2 -2
- package/build/src/abap/flow/statement_flow.js +126 -11
- package/build/src/abap/nodes/structure_node.js +12 -0
- package/build/src/lsp/help.js +7 -7
- package/build/src/lsp/language_server.js +12 -0
- package/build/src/registry.js +1 -1
- package/build/src/rules/abapdoc.js +1 -1
- package/build/src/rules/align_parameters.js +131 -0
- package/build/src/rules/ambiguous_statement.js +5 -5
- package/build/src/rules/avoid_use.js +6 -6
- package/build/src/rules/begin_end_names.js +4 -4
- package/build/src/rules/begin_single_include.js +12 -12
- package/build/src/rules/call_transaction_authority_check.js +3 -3
- package/build/src/rules/chain_mainly_declarations.js +4 -4
- package/build/src/rules/check_abstract.js +2 -2
- package/build/src/rules/check_comments.js +3 -3
- package/build/src/rules/check_include.js +3 -3
- package/build/src/rules/check_no_handler_pragma.js +8 -8
- package/build/src/rules/check_subrc.js +8 -8
- package/build/src/rules/commented_code.js +1 -1
- package/build/src/rules/constructor_visibility_public.js +4 -4
- package/build/src/rules/contains_tab.js +2 -2
- package/build/src/rules/dangerous_statement.js +1 -1
- package/build/src/rules/downport.js +35 -35
- package/build/src/rules/exit_or_check.js +3 -3
- package/build/src/rules/exporting.js +1 -1
- package/build/src/rules/forbidden_identifier.js +1 -1
- package/build/src/rules/forbidden_void_type.js +2 -2
- package/build/src/rules/functional_writing.js +17 -17
- package/build/src/rules/global_class.js +10 -10
- package/build/src/rules/identical_conditions.js +2 -2
- package/build/src/rules/identical_contents.js +15 -15
- package/build/src/rules/identical_descriptions.js +4 -4
- package/build/src/rules/if_in_if.js +7 -7
- package/build/src/rules/implement_methods.js +3 -3
- package/build/src/rules/in_statement_indentation.js +11 -11
- package/build/src/rules/index.js +2 -1
- package/build/src/rules/intf_referencing_clas.js +3 -3
- package/build/src/rules/line_break_style.js +2 -2
- package/build/src/rules/line_length.js +1 -1
- package/build/src/rules/line_only_punc.js +1 -1
- package/build/src/rules/local_variable_names.js +2 -2
- package/build/src/rules/many_parentheses.js +10 -10
- package/build/src/rules/max_one_method_parameter_per_line.js +7 -7
- package/build/src/rules/max_one_statement.js +3 -3
- package/build/src/rules/nesting.js +1 -1
- package/build/src/rules/no_public_attributes.js +1 -1
- package/build/src/rules/no_yoda_conditions.js +4 -4
- package/build/src/rules/obsolete_statement.js +36 -36
- package/build/src/rules/omit_parameter_name.js +3 -3
- package/build/src/rules/omit_receiving.js +13 -13
- package/build/src/rules/parser_702_chaining.js +2 -2
- package/build/src/rules/parser_error.js +2 -2
- package/build/src/rules/parser_missing_space.js +1 -1
- package/build/src/rules/prefer_inline.js +16 -16
- package/build/src/rules/prefer_is_not.js +7 -7
- package/build/src/rules/prefer_raise_exception_new.js +3 -3
- package/build/src/rules/prefer_returning_to_exporting.js +1 -1
- package/build/src/rules/prefer_xsdbool.js +2 -2
- package/build/src/rules/remove_descriptions.js +4 -4
- package/build/src/rules/rfc_error_handling.js +9 -9
- package/build/src/rules/select_add_order_by.js +5 -5
- package/build/src/rules/select_performance.js +2 -2
- package/build/src/rules/sicf_consistency.js +4 -4
- package/build/src/rules/space_before_dot.js +2 -2
- package/build/src/rules/start_at_tab.js +1 -1
- package/build/src/rules/sy_modification.js +2 -2
- package/build/src/rules/tabl_enhancement_category.js +2 -2
- package/build/src/rules/try_without_catch.js +1 -2
- package/build/src/rules/unused_methods.js +9 -9
- package/build/src/rules/unused_variables.js +6 -6
- package/build/src/rules/use_bool_expression.js +8 -8
- package/build/src/rules/use_line_exists.js +6 -6
- package/build/src/rules/use_new.js +2 -2
- package/build/src/rules/when_others_last.js +6 -6
- 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
|
package/build/abaplint.d.ts
CHANGED
|
@@ -756,7 +756,11 @@ declare class ClassName extends Expression {
|
|
|
756
756
|
getRunnable(): IStatementRunnable;
|
|
757
757
|
}
|
|
758
758
|
|
|
759
|
-
declare class Cleanup implements
|
|
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
|
-
|
|
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
|
-
|
|
5180
|
-
|
|
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
|
|
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
|
|
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("./
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
124
|
-
const
|
|
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
|
-
|
|
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()) {
|
package/build/src/lsp/help.js
CHANGED
|
@@ -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
|
package/build/src/registry.js
CHANGED
|
@@ -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
|