@abaplint/core 2.112.21 → 2.113.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.
@@ -6053,7 +6053,7 @@ declare class StartOfSelection implements IStatement {
6053
6053
 
6054
6054
  export declare class StatementFlow {
6055
6055
  private counter;
6056
- build(stru: StructureNode): FlowGraph[];
6056
+ build(stru: StructureNode, obj: IObject): FlowGraph[];
6057
6057
  private runEvent;
6058
6058
  private run;
6059
6059
  private findBody;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DECLARATION_STUFF = exports.SELECTION_EVENTS = void 0;
4
+ const Statements = require("../2_statements/statements");
5
+ exports.SELECTION_EVENTS = [
6
+ Statements.StartOfSelection,
7
+ Statements.AtSelectionScreen,
8
+ Statements.AtLineSelection,
9
+ Statements.AtUserCommand,
10
+ Statements.EndOfSelection,
11
+ Statements.Initialization,
12
+ Statements.TopOfPage,
13
+ Statements.EndOfPage,
14
+ ];
15
+ exports.DECLARATION_STUFF = [
16
+ Statements.Data,
17
+ Statements.DataBegin,
18
+ Statements.Constant,
19
+ Statements.Parameter,
20
+ Statements.SelectionScreen,
21
+ Statements.ConstantBegin,
22
+ ];
23
+ //# sourceMappingURL=selection_events.js.map
@@ -6,35 +6,13 @@ const Structures = require("../3_structures/structures");
6
6
  const Statements = require("../2_statements/statements");
7
7
  const Expressions = require("../2_statements/expressions");
8
8
  const flow_graph_1 = require("./flow_graph");
9
- // Levels: top, FORM, METHOD, FUNCTION-MODULE, (MODULE, AT, END-OF-*, GET, START-OF-SELECTION, TOP-OF-PAGE)
10
- //
11
- // Loop branching: LOOP, DO, WHILE, SELECT(loop), WITH, PROVIDE
12
- //
13
- // Branching: IF, CASE, CASE TYPE OF, TRY, ON, CATCH SYSTEM-EXCEPTIONS, AT
14
- //
15
- // Conditional exits: CHECK, ASSERT
16
- //
17
- // Exits: RETURN, EXIT, RAISE(not RESUMABLE), MESSAGE(type E and A?), CONTINUE, REJECT, RESUME, STOP
18
- //
19
- // Not handled? INCLUDE + malplaced macro calls
20
- /////////////////////////////////////
21
- // TODO: handling static exceptions(only static), refactor some logic from UncaughtException to common file
22
- // TODO: RAISE
23
- const FLOW_EVENTS = [
24
- Statements.StartOfSelection,
25
- Statements.AtSelectionScreen,
26
- Statements.AtLineSelection,
27
- Statements.AtUserCommand,
28
- Statements.EndOfSelection,
29
- Statements.Initialization,
30
- Statements.TopOfPage,
31
- Statements.EndOfPage,
32
- ];
9
+ const objects_1 = require("../../objects");
10
+ const selection_events_1 = require("./selection_events");
33
11
  class StatementFlow {
34
12
  constructor() {
35
13
  this.counter = 0;
36
14
  }
37
- build(stru) {
15
+ build(stru, obj) {
38
16
  var _a, _b, _c, _d;
39
17
  const ret = [];
40
18
  let name = "";
@@ -60,34 +38,38 @@ class StatementFlow {
60
38
  throw new Error("StatementFlow, unknown structure");
61
39
  }
62
40
  }
63
- // find the top level events
64
- let inFlow = false;
65
- let collected = [];
66
- for (const s of stru.getChildren() || []) {
67
- if (FLOW_EVENTS.some(f => s.get() instanceof f)) {
68
- if (inFlow === true) {
69
- ret.push(this.runEvent(collected, name));
41
+ if (obj instanceof objects_1.Program) {
42
+ // find the top level events
43
+ let inEvent = false;
44
+ let collected = [];
45
+ for (const s of stru.getChildren() || []) {
46
+ if (selection_events_1.SELECTION_EVENTS.some(f => s.get() instanceof f)) {
47
+ if (inEvent === true) {
48
+ ret.push(this.runEvent(collected, name));
49
+ }
50
+ collected = [];
51
+ inEvent = true;
52
+ name = s.concatTokens();
53
+ }
54
+ else if (s.get() instanceof Structures.Normal) {
55
+ collected.push(s);
56
+ }
57
+ else {
58
+ if (inEvent === true) {
59
+ ret.push(this.runEvent(collected, name));
60
+ inEvent = false;
61
+ }
62
+ collected = [];
70
63
  }
71
- collected = [];
72
- inFlow = true;
73
- name = s.concatTokens();
74
64
  }
75
- else if (s.get() instanceof Structures.Normal) {
76
- collected.push(s);
65
+ if (inEvent === true) {
66
+ ret.push(this.runEvent(collected, name));
77
67
  }
78
- else {
79
- if (inFlow === true) {
80
- ret.push(this.runEvent(collected, name));
81
- inFlow = false;
82
- }
83
- collected = [];
68
+ else if (collected.length > 0) {
69
+ // implicit START-OF-SELECTION
70
+ ret.push(this.runEvent(collected, "START-OF-SELECTION."));
84
71
  }
85
72
  }
86
- if (inFlow === true) {
87
- ret.push(this.runEvent(collected, name));
88
- inFlow = false;
89
- collected = [];
90
- }
91
73
  return ret.map(f => f.reduce());
92
74
  }
93
75
  ////////////////////
@@ -132,11 +132,15 @@ class LanguageServer {
132
132
  if (file === undefined) {
133
133
  return "file not found";
134
134
  }
135
+ const obj = this.reg.findObjectForFile(file);
136
+ if (obj === undefined) {
137
+ return "obj not found";
138
+ }
135
139
  const stru = file.getStructure();
136
140
  if (stru === undefined) {
137
141
  return "empty structure";
138
142
  }
139
- const graphs = new statement_flow_1.StatementFlow().build(stru);
143
+ const graphs = new statement_flow_1.StatementFlow().build(stru, obj);
140
144
  const wiz = graphs.map(g => g.toDigraph());
141
145
  return JSON.stringify(wiz);
142
146
  }
@@ -67,7 +67,7 @@ class Registry {
67
67
  }
68
68
  static abaplintVersion() {
69
69
  // magic, see build script "version.sh"
70
- return "2.112.21";
70
+ return "2.113.0";
71
71
  }
72
72
  getDDICReferences() {
73
73
  return this.ddicReferences;
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AddTestAttributes = exports.AddTestAttributesConf = void 0;
4
+ const issue_1 = require("../issue");
5
+ const _abap_rule_1 = require("./_abap_rule");
6
+ const _basic_rule_config_1 = require("./_basic_rule_config");
7
+ const Statements = require("../abap/2_statements/statements");
8
+ const Structures = require("../abap/3_structures/structures");
9
+ const _irule_1 = require("./_irule");
10
+ class AddTestAttributesConf extends _basic_rule_config_1.BasicRuleConfig {
11
+ }
12
+ exports.AddTestAttributesConf = AddTestAttributesConf;
13
+ class AddTestAttributes extends _abap_rule_1.ABAPRule {
14
+ constructor() {
15
+ super(...arguments);
16
+ this.conf = new AddTestAttributesConf();
17
+ }
18
+ getMetadata() {
19
+ return {
20
+ key: "add_test_attributes",
21
+ title: "Add test attributes for tests classes with test methods",
22
+ shortDescription: `Add test attributes DURATION and RISK LEVEL for tests classes with test methods`,
23
+ tags: [_irule_1.RuleTag.SingleFile],
24
+ badExample: `CLASS ltcl_test DEFINITION FINAL FOR TESTING.
25
+ PUBLIC SECTION.
26
+ PROTECTED SECTION.
27
+ PRIVATE SECTION.
28
+ METHODS test FOR TESTING RAISING cx_static_check.
29
+ ENDCLASS.
30
+
31
+ CLASS ltcl_test IMPLEMENTATION.
32
+ METHOD test.
33
+ ENDMETHOD.
34
+ ENDCLASS.`,
35
+ goodExample: `CLASS ltcl_test DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
36
+ PUBLIC SECTION.
37
+ PROTECTED SECTION.
38
+ PRIVATE SECTION.
39
+ METHODS test FOR TESTING RAISING cx_static_check.
40
+ ENDCLASS.
41
+
42
+ CLASS ltcl_test IMPLEMENTATION.
43
+ METHOD test.
44
+ ENDMETHOD.
45
+ ENDCLASS.`,
46
+ };
47
+ }
48
+ getConfig() {
49
+ return this.conf;
50
+ }
51
+ setConfig(conf) {
52
+ this.conf = conf;
53
+ }
54
+ runParsed(file) {
55
+ const issues = [];
56
+ const stru = file.getStructure();
57
+ if (stru === undefined) {
58
+ return [];
59
+ }
60
+ for (const classStructure of stru.findAllStructures(Structures.ClassDefinition)) {
61
+ const cdef = classStructure.findFirstStatement(Statements.ClassDefinition);
62
+ if (cdef === undefined) {
63
+ continue;
64
+ }
65
+ const cdefConcat = cdef === null || cdef === void 0 ? void 0 : cdef.concatTokens().toUpperCase();
66
+ if ((cdefConcat === null || cdefConcat === void 0 ? void 0 : cdefConcat.includes(" FOR TESTING")) === false) {
67
+ continue;
68
+ }
69
+ const hasDuration = cdefConcat === null || cdefConcat === void 0 ? void 0 : cdefConcat.includes(" DURATION ");
70
+ const hasRiskLevel = cdefConcat === null || cdefConcat === void 0 ? void 0 : cdefConcat.includes(" RISK LEVEL ");
71
+ if (hasDuration === true && hasRiskLevel === true) {
72
+ continue;
73
+ }
74
+ let hasTestMethod = false;
75
+ for (const mdef of classStructure.findAllStatements(Statements.MethodDef)) {
76
+ const concat = mdef.concatTokens().toUpperCase();
77
+ if (concat.includes(" FOR TESTING")) {
78
+ hasTestMethod = true;
79
+ }
80
+ }
81
+ if (hasTestMethod === false) {
82
+ continue;
83
+ }
84
+ if (hasDuration === false) {
85
+ issues.push(issue_1.Issue.atStatement(file, cdef, "Add DURATION", this.getMetadata().key, this.getConfig().severity));
86
+ }
87
+ if (hasRiskLevel === false) {
88
+ issues.push(issue_1.Issue.atStatement(file, cdef, "Add RISK LEVEL", this.getMetadata().key, this.getConfig().severity));
89
+ }
90
+ }
91
+ return issues;
92
+ }
93
+ }
94
+ exports.AddTestAttributes = AddTestAttributes;
95
+ //# sourceMappingURL=add_test_attributes.js.map
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EmptyEvent = exports.EmptyEventConf = void 0;
4
+ const issue_1 = require("../issue");
5
+ const _abap_rule_1 = require("./_abap_rule");
6
+ const _basic_rule_config_1 = require("./_basic_rule_config");
7
+ const Structures = require("../abap/3_structures/structures");
8
+ const _irule_1 = require("./_irule");
9
+ const objects_1 = require("../objects");
10
+ const selection_events_1 = require("../abap/flow/selection_events");
11
+ class EmptyEventConf extends _basic_rule_config_1.BasicRuleConfig {
12
+ }
13
+ exports.EmptyEventConf = EmptyEventConf;
14
+ class EmptyEvent extends _abap_rule_1.ABAPRule {
15
+ constructor() {
16
+ super(...arguments);
17
+ this.conf = new EmptyEventConf();
18
+ }
19
+ getMetadata() {
20
+ return {
21
+ key: "empty_event",
22
+ title: "Empty selection screen or list processing event block",
23
+ shortDescription: `Empty selection screen or list processing event block`,
24
+ extendedInformation: ``,
25
+ tags: [_irule_1.RuleTag.SingleFile],
26
+ badExample: `REPORT zfoo.
27
+ START-OF-SELECTION.
28
+ PERFORM sdf.
29
+ COMMIT WORK.
30
+ END-OF-SELECTION.`,
31
+ goodExample: `REPORT zfoo.
32
+ START-OF-SELECTION.
33
+ PERFORM sdf.
34
+ COMMIT WORK.`,
35
+ };
36
+ }
37
+ getConfig() {
38
+ return this.conf;
39
+ }
40
+ setConfig(conf) {
41
+ this.conf = conf;
42
+ }
43
+ runParsed(file, obj) {
44
+ const issues = [];
45
+ if (!(obj instanceof objects_1.Program) || obj.isInclude()) {
46
+ return issues;
47
+ }
48
+ const stru = file.getStructure();
49
+ if (stru === undefined) {
50
+ return [];
51
+ }
52
+ let currentEvent = undefined;
53
+ let children = [];
54
+ for (const s of stru.getChildren() || []) {
55
+ if (selection_events_1.SELECTION_EVENTS.some(f => s.get() instanceof f)) {
56
+ children = [];
57
+ currentEvent = s;
58
+ }
59
+ else if (s.get() instanceof Structures.Normal) {
60
+ const stru = s;
61
+ // ignore declaration stuff
62
+ if (selection_events_1.DECLARATION_STUFF.some(d => { var _a; return ((_a = stru.getFirstStatement()) === null || _a === void 0 ? void 0 : _a.get()) instanceof d; })) {
63
+ continue;
64
+ }
65
+ children.push(s);
66
+ }
67
+ else {
68
+ children = [];
69
+ }
70
+ }
71
+ if (currentEvent !== undefined && children.length === 0) {
72
+ issues.push(issue_1.Issue.atStatement(file, currentEvent, "Empty event", this.getMetadata().key, this.getConfig().severity));
73
+ }
74
+ return issues;
75
+ }
76
+ }
77
+ exports.EmptyEvent = EmptyEvent;
78
+ //# sourceMappingURL=empty_event.js.map
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ImplicitStartOfSelection = exports.ImplicitStartOfSelectionConf = void 0;
4
+ const issue_1 = require("../issue");
5
+ const _abap_rule_1 = require("./_abap_rule");
6
+ const _basic_rule_config_1 = require("./_basic_rule_config");
7
+ const Structures = require("../abap/3_structures/structures");
8
+ const _irule_1 = require("./_irule");
9
+ const objects_1 = require("../objects");
10
+ const nodes_1 = require("../abap/nodes");
11
+ const selection_events_1 = require("../abap/flow/selection_events");
12
+ class ImplicitStartOfSelectionConf extends _basic_rule_config_1.BasicRuleConfig {
13
+ }
14
+ exports.ImplicitStartOfSelectionConf = ImplicitStartOfSelectionConf;
15
+ class ImplicitStartOfSelection extends _abap_rule_1.ABAPRule {
16
+ constructor() {
17
+ super(...arguments);
18
+ this.conf = new ImplicitStartOfSelectionConf();
19
+ }
20
+ getMetadata() {
21
+ return {
22
+ key: "implicit_start_of_selection",
23
+ title: "Implicit START-OF-SELECTION",
24
+ shortDescription: `Add explicit selection screen event handling`,
25
+ extendedInformation: `Only runs for executable programs
26
+
27
+ https://help.sap.com/doc/abapdocu_751_index_htm/7.51/en-us/abapstart-of-selection.htm`,
28
+ tags: [_irule_1.RuleTag.SingleFile],
29
+ badExample: `REPORT zfoo.
30
+ WRITE 'hello'.`,
31
+ goodExample: `REPORT zfoo.
32
+ START-OF-SELECTION.
33
+ WRITE 'hello'.`,
34
+ };
35
+ }
36
+ getConfig() {
37
+ return this.conf;
38
+ }
39
+ setConfig(conf) {
40
+ this.conf = conf;
41
+ }
42
+ runParsed(file, obj) {
43
+ const issues = [];
44
+ if (!(obj instanceof objects_1.Program) || obj.isInclude()) {
45
+ return issues;
46
+ }
47
+ const stru = file.getStructure();
48
+ if (stru === undefined) {
49
+ return [];
50
+ }
51
+ let inEvent = false;
52
+ let collected = [];
53
+ for (const s of stru.getChildren() || []) {
54
+ if (selection_events_1.SELECTION_EVENTS.some(f => s.get() instanceof f)) {
55
+ if (inEvent === false && collected.length > 0) {
56
+ // implicit START-OF-SELECTION
57
+ let first = collected[0];
58
+ if (first instanceof nodes_1.StructureNode) {
59
+ first = first.getFirstStatement();
60
+ }
61
+ issues.push(issue_1.Issue.atStatement(file, first, "Implicit START-OF-SELECTION", this.getMetadata().key, this.getConfig().severity));
62
+ }
63
+ collected = [];
64
+ inEvent = true;
65
+ }
66
+ else if (s.get() instanceof Structures.Normal) {
67
+ const stru = s;
68
+ // ignore declaration stuff
69
+ if (selection_events_1.DECLARATION_STUFF.some(d => { var _a; return ((_a = stru.getFirstStatement()) === null || _a === void 0 ? void 0 : _a.get()) instanceof d; })) {
70
+ continue;
71
+ }
72
+ collected.push(s);
73
+ }
74
+ else {
75
+ if (inEvent === true) {
76
+ inEvent = false;
77
+ }
78
+ collected = [];
79
+ }
80
+ }
81
+ if (inEvent === false && collected.length > 0) {
82
+ // implicit START-OF-SELECTION
83
+ let first = collected[0];
84
+ if (first instanceof nodes_1.StructureNode) {
85
+ first = first.getFirstStatement();
86
+ }
87
+ issues.push(issue_1.Issue.atStatement(file, first, "Implicit START-OF-SELECTION", this.getMetadata().key, this.getConfig().severity));
88
+ }
89
+ return issues;
90
+ }
91
+ }
92
+ exports.ImplicitStartOfSelection = ImplicitStartOfSelection;
93
+ //# sourceMappingURL=implicit_start_of_selection.js.map
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./7bit_ascii"), exports);
18
18
  __exportStar(require("./abapdoc"), exports);
19
+ __exportStar(require("./add_test_attributes"), exports);
19
20
  __exportStar(require("./align_parameters"), exports);
20
21
  __exportStar(require("./align_pseudo_comments"), exports);
21
22
  __exportStar(require("./align_type_expressions"), exports);
@@ -57,6 +58,7 @@ __exportStar(require("./double_space"), exports);
57
58
  __exportStar(require("./downport"), exports);
58
59
  __exportStar(require("./dynpro_checks"), exports);
59
60
  __exportStar(require("./easy_to_find_messages"), exports);
61
+ __exportStar(require("./empty_event"), exports);
60
62
  __exportStar(require("./empty_line_in_statement"), exports);
61
63
  __exportStar(require("./empty_statement"), exports);
62
64
  __exportStar(require("./empty_structure"), exports);
@@ -78,6 +80,7 @@ __exportStar(require("./identical_descriptions"), exports);
78
80
  __exportStar(require("./identical_form_names"), exports);
79
81
  __exportStar(require("./if_in_if"), exports);
80
82
  __exportStar(require("./implement_methods"), exports);
83
+ __exportStar(require("./implicit_start_of_selection"), exports);
81
84
  __exportStar(require("./in_statement_indentation"), exports);
82
85
  __exportStar(require("./indentation"), exports);
83
86
  __exportStar(require("./inline_data_old_versions"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.112.21",
3
+ "version": "2.113.0",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",