@abaplint/core 2.88.8 → 2.89.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.
@@ -741,6 +741,7 @@ declare class Class extends ABAPObject {
741
741
  getNameFromXML(): string | undefined;
742
742
  getCategory(): string | undefined;
743
743
  getLocalsImpFile(): ABAPFile | undefined;
744
+ getTestclassFile(): ABAPFile | undefined;
744
745
  private parseXML;
745
746
  }
746
747
 
@@ -1952,6 +1953,7 @@ declare namespace Expressions {
1952
1953
  TypeTableKey,
1953
1954
  TypeTable,
1954
1955
  Type_2 as Type,
1956
+ SQLUpTo,
1955
1957
  ValueBody,
1956
1958
  ValueBodyLines,
1957
1959
  Value,
@@ -2651,7 +2653,8 @@ export declare const enum IdentifierMeta {
2651
2653
  BuiltIn = "built-in",
2652
2654
  DDIC = "ddic",
2653
2655
  Static = "static",
2654
- Enum = "enum"
2656
+ Enum = "enum",
2657
+ SelectionScreenTab = "selection_screen_tab"
2655
2658
  }
2656
2659
 
2657
2660
  export declare interface IDependency {
@@ -4977,6 +4980,10 @@ declare class SQLTarget extends Expression {
4977
4980
  getRunnable(): IStatementRunnable;
4978
4981
  }
4979
4982
 
4983
+ declare class SQLUpTo extends Expression {
4984
+ getRunnable(): IStatementRunnable;
4985
+ }
4986
+
4980
4987
  declare class StartOfSelection implements IStatement {
4981
4988
  getMatcher(): IStatementRunnable;
4982
4989
  }
@@ -200,6 +200,7 @@ __exportStar(require("./type_param"), exports);
200
200
  __exportStar(require("./type_table_key"), exports);
201
201
  __exportStar(require("./type_table"), exports);
202
202
  __exportStar(require("./type"), exports);
203
+ __exportStar(require("./sql_up_to"), exports);
203
204
  __exportStar(require("./value_body"), exports);
204
205
  __exportStar(require("./value_body_lines"), exports);
205
206
  __exportStar(require("./value"), exports);
@@ -8,16 +8,16 @@ const sql_group_by_1 = require("./sql_group_by");
8
8
  const sql_into_structure_1 = require("./sql_into_structure");
9
9
  const tokens_1 = require("../../1_lexer/tokens");
10
10
  const sql_field_name_1 = require("./sql_field_name");
11
+ const sql_up_to_1 = require("./sql_up_to");
11
12
  class Select extends combi_1.Expression {
12
13
  getRunnable() {
13
14
  const into = (0, combi_1.altPrio)(_1.SQLIntoTable, sql_into_structure_1.SQLIntoStructure);
14
15
  const where = (0, combi_1.seq)("WHERE", _1.SQLCond);
15
- const up = (0, combi_1.seq)("UP TO", _1.SQLSource, "ROWS");
16
16
  const offset = (0, combi_1.ver)(version_1.Version.v751, (0, combi_1.seq)("OFFSET", _1.SQLSource));
17
17
  const client = (0, combi_1.str)("CLIENT SPECIFIED");
18
18
  const bypass = (0, combi_1.str)("BYPASSING BUFFER");
19
19
  const fields = (0, combi_1.seq)("FIELDS", _1.SQLFieldList);
20
- const perm = (0, combi_1.per)(_1.SQLFrom, into, _1.SQLForAllEntries, where, _1.SQLOrderBy, up, offset, client, _1.SQLHaving, bypass, sql_group_by_1.SQLGroupBy, fields, _1.DatabaseConnection);
20
+ const perm = (0, combi_1.per)(_1.SQLFrom, into, _1.SQLForAllEntries, where, _1.SQLOrderBy, sql_up_to_1.SQLUpTo, offset, client, _1.SQLHaving, bypass, sql_group_by_1.SQLGroupBy, fields, _1.DatabaseConnection);
21
21
  const paren = (0, combi_1.seq)((0, combi_1.tok)(tokens_1.WParenLeftW), sql_field_name_1.SQLFieldName, (0, combi_1.tok)(tokens_1.WParenRightW));
22
22
  const ret = (0, combi_1.seq)("SELECT", (0, combi_1.altPrio)("DISTINCT", (0, combi_1.optPrio)((0, combi_1.seq)("SINGLE", (0, combi_1.optPrio)("FOR UPDATE")))), (0, combi_1.optPrio)((0, combi_1.altPrio)(_1.SQLFieldList, paren)), perm, (0, combi_1.optPrio)(_1.SQLHints));
23
23
  return ret;
@@ -9,16 +9,16 @@ const sql_into_structure_1 = require("./sql_into_structure");
9
9
  const sql_field_list_1 = require("./sql_field_list");
10
10
  const sql_hints_1 = require("./sql_hints");
11
11
  const sql_field_list_loop_1 = require("./sql_field_list_loop");
12
+ const sql_up_to_1 = require("./sql_up_to");
12
13
  class SelectLoop extends combi_1.Expression {
13
14
  getRunnable() {
14
15
  const where = (0, combi_1.seq)("WHERE", _1.SQLCond);
15
16
  const client = "CLIENT SPECIFIED";
16
17
  const bypass = "BYPASSING BUFFER";
17
- const up = (0, combi_1.seq)("UP TO", _1.SQLSource, "ROWS");
18
18
  const pack = (0, combi_1.seq)("PACKAGE SIZE", _1.SQLSource);
19
19
  const tab = (0, combi_1.seq)(_1.SQLIntoTable, (0, combi_1.alt)(pack, (0, combi_1.seq)(_1.SQLFrom, pack), (0, combi_1.seq)(pack, _1.SQLFrom)));
20
- const perm = (0, combi_1.per)(_1.SQLFrom, where, up, sql_order_by_1.SQLOrderBy, sql_having_1.SQLHaving, client, bypass, _1.SQLGroupBy, _1.SQLForAllEntries, (0, combi_1.alt)(tab, sql_into_structure_1.SQLIntoStructure));
21
- const strict = (0, combi_1.seq)(_1.SQLFrom, "FIELDS", sql_field_list_1.SQLFieldList, where, sql_into_structure_1.SQLIntoStructure, up);
20
+ const perm = (0, combi_1.per)(_1.SQLFrom, where, sql_up_to_1.SQLUpTo, sql_order_by_1.SQLOrderBy, sql_having_1.SQLHaving, client, bypass, _1.SQLGroupBy, _1.SQLForAllEntries, (0, combi_1.alt)(tab, sql_into_structure_1.SQLIntoStructure));
21
+ const strict = (0, combi_1.seq)(_1.SQLFrom, "FIELDS", sql_field_list_1.SQLFieldList, where, sql_into_structure_1.SQLIntoStructure, sql_up_to_1.SQLUpTo);
22
22
  const ret = (0, combi_1.seq)("SELECT", (0, combi_1.altPrio)((0, combi_1.seq)((0, combi_1.optPrio)("DISTINCT"), sql_field_list_loop_1.SQLFieldListLoop, perm), strict), (0, combi_1.optPrio)(sql_hints_1.SQLHints));
23
23
  return ret;
24
24
  }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SQLUpTo = void 0;
4
+ const combi_1 = require("../combi");
5
+ const sql_source_1 = require("./sql_source");
6
+ class SQLUpTo extends combi_1.Expression {
7
+ getRunnable() {
8
+ const up = (0, combi_1.seq)("UP TO", sql_source_1.SQLSource, "ROWS");
9
+ return up;
10
+ }
11
+ }
12
+ exports.SQLUpTo = SQLUpTo;
13
+ //# sourceMappingURL=sql_up_to.js.map
@@ -5,8 +5,13 @@ const Expressions = require("../../2_statements/expressions");
5
5
  const _typed_identifier_1 = require("../../types/_typed_identifier");
6
6
  const data_definition_1 = require("../expressions/data_definition");
7
7
  const unknown_type_1 = require("../../types/basic/unknown_type");
8
+ const basic_types_1 = require("../basic_types");
8
9
  class Data {
9
10
  runSyntax(node, scope, filename) {
11
+ const val = node.findFirstExpression(Expressions.Value);
12
+ if (val) {
13
+ new basic_types_1.BasicTypes(filename, scope).findValue(node);
14
+ }
10
15
  const dd = node.findFirstExpression(Expressions.DataDefinition);
11
16
  if (dd) {
12
17
  return new data_definition_1.DataDefinition().runSyntax(dd, scope, filename);
@@ -18,7 +18,10 @@ class SelectionScreen {
18
18
  { name: "DYNNR", type: new basic_1.CharacterType(4) },
19
19
  { name: "ACTIVETAB", type: new basic_1.CharacterType(132) },
20
20
  ]);
21
- scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(name, filename, type));
21
+ scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(name, filename, type, ["selection_screen_tab" /* SelectionScreenTab */]));
22
+ }
23
+ else if (concat.startsWith("SELECTION-SCREEN TAB")) {
24
+ scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(name, filename, new basic_1.CharacterType(83), ["selection_screen_tab" /* SelectionScreenTab */]));
22
25
  }
23
26
  else {
24
27
  scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(name, filename, new basic_1.CharacterType(83)));
@@ -78,6 +78,14 @@ class Class extends _abap_object_1.ABAPObject {
78
78
  }
79
79
  return undefined;
80
80
  }
81
+ getTestclassFile() {
82
+ for (const file of this.getABAPFiles()) {
83
+ if (file.getFilename().endsWith(".clas.testclasses.abap")) {
84
+ return file;
85
+ }
86
+ }
87
+ return undefined;
88
+ }
81
89
  /////////////////////////
82
90
  parseXML() {
83
91
  if (this.parsedXML !== undefined) {
@@ -68,7 +68,7 @@ class Registry {
68
68
  }
69
69
  static abaplintVersion() {
70
70
  // magic, see build script "version.sh"
71
- return "2.88.8";
71
+ return "2.89.0";
72
72
  }
73
73
  getDDICReferences() {
74
74
  return this.references;
@@ -40,13 +40,15 @@ class CheckTransformationExists extends _abap_rule_1.ABAPRule {
40
40
  }
41
41
  for (const s of file.getStatements()) {
42
42
  if (s.get() instanceof statements_1.CallTransformation) {
43
- const name = s.findFirstExpression(expressions_1.NamespaceSimpleName);
44
- if (name === undefined) {
43
+ const nameExpression = s.findFirstExpression(expressions_1.NamespaceSimpleName);
44
+ if (nameExpression === undefined) {
45
45
  continue;
46
46
  }
47
- const tok = name.getFirstToken();
48
- if (this.reg.getObject("XSLT", tok.getStr()) === undefined) {
49
- const issue = issue_1.Issue.atToken(file, tok, this.getDescription(tok.getStr()), this.getMetadata().key);
47
+ const tok = nameExpression.getFirstToken();
48
+ const name = tok.getStr();
49
+ if (this.reg.inErrorNamespace(name) === true
50
+ && this.reg.getObject("XSLT", name) === undefined) {
51
+ const issue = issue_1.Issue.atToken(file, tok, this.getDescription(name), this.getMetadata().key);
50
52
  output.push(issue);
51
53
  }
52
54
  }
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ClassicExceptionsOverlap = exports.ClassicExceptionsOverlapConf = 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 Expressions = require("../abap/2_statements/expressions");
8
+ const _irule_1 = require("./_irule");
9
+ class ClassicExceptionsOverlapConf extends _basic_rule_config_1.BasicRuleConfig {
10
+ }
11
+ exports.ClassicExceptionsOverlapConf = ClassicExceptionsOverlapConf;
12
+ class ClassicExceptionsOverlap extends _abap_rule_1.ABAPRule {
13
+ constructor() {
14
+ super(...arguments);
15
+ this.conf = new ClassicExceptionsOverlapConf();
16
+ }
17
+ getMetadata() {
18
+ return {
19
+ key: "classic_exceptions_overlap",
20
+ title: "Classic exceptions overlap when catching",
21
+ shortDescription: `Find overlapping classic exceptions`,
22
+ extendedInformation: `When debugging its typically good to know exactly which exception is caught`,
23
+ tags: [_irule_1.RuleTag.SingleFile],
24
+ badExample: ` EXCEPTIONS
25
+ system_failure = 1 MESSAGE lv_message
26
+ communication_failure = 1 MESSAGE lv_message
27
+ resource_failure = 1
28
+ OTHERS = 1.`,
29
+ goodExample: ` EXCEPTIONS
30
+ system_failure = 1 MESSAGE lv_message
31
+ communication_failure = 2 MESSAGE lv_message
32
+ resource_failure = 3
33
+ OTHERS = 4.`,
34
+ };
35
+ }
36
+ getConfig() {
37
+ return this.conf;
38
+ }
39
+ setConfig(conf) {
40
+ this.conf = conf;
41
+ }
42
+ runParsed(file) {
43
+ var _a;
44
+ const output = [];
45
+ const struc = file.getStructure();
46
+ if (struc === undefined) {
47
+ return []; // syntax error
48
+ }
49
+ for (const p of struc.findAllExpressions(Expressions.ParameterListExceptions)) {
50
+ const set = new Set();
51
+ for (const e of p.findAllExpressions(Expressions.ParameterException)) {
52
+ const text = (_a = e.findDirectExpression(Expressions.SimpleName)) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase();
53
+ if (text === undefined) {
54
+ continue;
55
+ }
56
+ if (set.has(text)) {
57
+ const message = "Exception overlap, " + text;
58
+ const issue = issue_1.Issue.atToken(file, e.getFirstToken(), message, this.getMetadata().key, this.getConfig().severity);
59
+ output.push(issue);
60
+ break;
61
+ }
62
+ set.add(text);
63
+ }
64
+ }
65
+ return output;
66
+ }
67
+ }
68
+ exports.ClassicExceptionsOverlap = ClassicExceptionsOverlap;
69
+ //# sourceMappingURL=classic_exceptions_overlap.js.map
@@ -122,7 +122,8 @@ class DefinitionsTop extends _abap_rule_1.ABAPRule {
122
122
  return undefined;
123
123
  }
124
124
  buildFix(file, statement, start) {
125
- const concat = statement.concatTokens();
125
+ let concat = statement.concatTokens();
126
+ concat = concat.replace(/,$/, ".");
126
127
  const fix1 = edit_helper_1.EditHelper.deleteStatement(file, statement);
127
128
  const indentation = " ".repeat(statement.getFirstToken().getCol() - 1);
128
129
  const fix2 = edit_helper_1.EditHelper.insertAt(file, start.getEnd(), "\n" + indentation + concat);
@@ -145,6 +145,7 @@ class DoubleSpace extends _abap_rule_1.ABAPRule {
145
145
  const upper = prev.get().getStr().toUpperCase();
146
146
  if (prev instanceof nodes_1.TokenNodeRegex
147
147
  || upper === "("
148
+ || upper === ")"
148
149
  || upper === "CHANGING"
149
150
  || upper === "EXPORTING"
150
151
  || upper === "OTHERS") {
@@ -502,14 +502,15 @@ ${indentation}${uniqueName} = ${source.concatTokens()}.\n${indentation}`);
502
502
  const tabixBackup = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
503
503
  const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
504
504
  const firstToken = node.getFirstToken();
505
+ // note that the tabix restore should be done before throwing the exception
505
506
  const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${uniqueName} LIKE LINE OF ${pre}.
506
507
  ${indentation}DATA ${tabixBackup} LIKE sy-tabix.
507
508
  ${indentation}${tabixBackup} = sy-tabix.
508
509
  ${indentation}READ TABLE ${pre} ${condition}INTO ${uniqueName}.
510
+ ${indentation}sy-tabix = ${tabixBackup}.
509
511
  ${indentation}IF sy-subrc <> 0.
510
512
  ${indentation} RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
511
513
  ${indentation}ENDIF.
512
- ${indentation}sy-tabix = ${tabixBackup}.
513
514
  ${indentation}`);
514
515
  const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, startToken.getStart(), tableExpression.getLastToken().getEnd(), uniqueName);
515
516
  const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
@@ -760,14 +761,15 @@ ${indentation}RAISE EXCEPTION ${uniqueName2}.`;
760
761
  const condition = this.tableCondition(tableExpression);
761
762
  const tabixBackup = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
762
763
  const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
764
+ // restore tabix before exeption
763
765
  const code = `FIELD-SYMBOLS ${uniqueName} LIKE LINE OF ${tName}.
764
766
  ${indentation}DATA ${tabixBackup} LIKE sy-tabix.
765
767
  ${indentation}${tabixBackup} = sy-tabix.
766
768
  ${indentation}READ TABLE ${tName} ${condition}ASSIGNING ${uniqueName}.
769
+ ${indentation}sy-tabix = ${tabixBackup}.
767
770
  ${indentation}IF sy-subrc <> 0.
768
771
  ${indentation} RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
769
772
  ${indentation}ENDIF.
770
- ${indentation}sy-tabix = ${tabixBackup}.
771
773
  ${indentation}${uniqueName}`;
772
774
  const start = target.getFirstToken().getStart();
773
775
  const end = (_a = tableExpression.findDirectTokenByText("]")) === null || _a === void 0 ? void 0 : _a.getEnd();
@@ -8,6 +8,7 @@ const _abap_object_1 = require("../objects/_abap_object");
8
8
  class IdenticalFormNamesConf extends _basic_rule_config_1.BasicRuleConfig {
9
9
  }
10
10
  exports.IdenticalFormNamesConf = IdenticalFormNamesConf;
11
+ // todo: deprecation candidate? this is/should be handled by the syntax check?
11
12
  class IdenticalFormNames {
12
13
  constructor() {
13
14
  this.conf = new IdenticalFormNamesConf();
@@ -30,9 +30,9 @@ __exportStar(require("./check_abstract"), exports);
30
30
  __exportStar(require("./check_comments"), exports);
31
31
  __exportStar(require("./check_ddic"), exports);
32
32
  __exportStar(require("./check_include"), exports);
33
- __exportStar(require("./unnecessary_pragma"), exports);
34
33
  __exportStar(require("./check_subrc"), exports);
35
34
  __exportStar(require("./check_syntax"), exports);
35
+ __exportStar(require("./classic_exceptions_overlap"), exports);
36
36
  __exportStar(require("./check_text_elements"), exports);
37
37
  __exportStar(require("./check_transformation_exists"), exports);
38
38
  __exportStar(require("./class_attribute_names"), exports);
@@ -80,7 +80,7 @@ __exportStar(require("./line_break_style"), exports);
80
80
  __exportStar(require("./line_length"), exports);
81
81
  __exportStar(require("./line_only_punc"), exports);
82
82
  __exportStar(require("./local_class_naming"), exports);
83
- __exportStar(require("./local_testclass_location"), exports);
83
+ __exportStar(require("./local_testclass_consistency"), exports);
84
84
  __exportStar(require("./local_variable_names"), exports);
85
85
  __exportStar(require("./main_file_contents"), exports);
86
86
  __exportStar(require("./many_parentheses"), exports);
@@ -99,6 +99,7 @@ __exportStar(require("./nesting"), exports);
99
99
  __exportStar(require("./newline_between_methods"), exports);
100
100
  __exportStar(require("./no_aliases"), exports);
101
101
  __exportStar(require("./no_chained_assignment"), exports);
102
+ __exportStar(require("./no_inline_in_optional_branches"), exports);
102
103
  __exportStar(require("./no_public_attributes"), exports);
103
104
  __exportStar(require("./no_yoda_conditions"), exports);
104
105
  __exportStar(require("./nrob_consistency"), exports);
@@ -144,6 +145,7 @@ __exportStar(require("./types_naming"), exports);
144
145
  __exportStar(require("./uncaught_exception"), exports);
145
146
  __exportStar(require("./unknown_types"), exports);
146
147
  __exportStar(require("./unnecessary_chaining"), exports);
148
+ __exportStar(require("./unnecessary_pragma"), exports);
147
149
  __exportStar(require("./unreachable_code"), exports);
148
150
  __exportStar(require("./unsecure_fae"), exports);
149
151
  __exportStar(require("./unused_ddic"), exports);
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LocalTestclassConsistency = exports.LocalTestclassConsistencyConf = 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 objects_1 = require("../objects");
8
+ const _irule_1 = require("./_irule");
9
+ const version_1 = require("../version");
10
+ class LocalTestclassConsistencyConf extends _basic_rule_config_1.BasicRuleConfig {
11
+ }
12
+ exports.LocalTestclassConsistencyConf = LocalTestclassConsistencyConf;
13
+ class LocalTestclassConsistency extends _abap_rule_1.ABAPRule {
14
+ constructor() {
15
+ super(...arguments);
16
+ this.conf = new LocalTestclassConsistencyConf();
17
+ }
18
+ getMetadata() {
19
+ return {
20
+ key: "local_testclass_consistency",
21
+ title: "Local testclass consistency",
22
+ shortDescription: `Checks that local test classes are placed in the test include, and class unit test flag is set`,
23
+ tags: [_irule_1.RuleTag.Syntax],
24
+ };
25
+ }
26
+ getConfig() {
27
+ return this.conf;
28
+ }
29
+ setConfig(conf) {
30
+ this.conf = conf;
31
+ }
32
+ runParsed(file, obj) {
33
+ var _a;
34
+ const issues = [];
35
+ if (this.reg.getConfig().getVersion() === version_1.Version.v700) {
36
+ // 700 does not have testclass includes
37
+ return [];
38
+ }
39
+ if (!(obj instanceof objects_1.Class)) {
40
+ return [];
41
+ }
42
+ for (const c of file.getInfo().listClassDefinitions()) {
43
+ if (c.isLocal && c.isForTesting && !file.getFilename().includes(".testclasses.abap")) {
44
+ const message = "Place local testclass \"" + c.name + "\" in the testclass include";
45
+ const issue = issue_1.Issue.atIdentifier(c.identifier, message, this.getMetadata().key, this.conf.severity);
46
+ issues.push(issue);
47
+ }
48
+ }
49
+ if (file.getFilename().includes(".testclasses.") === true
50
+ && obj.getTestclassFile() !== undefined
51
+ && ((_a = obj.getXML()) === null || _a === void 0 ? void 0 : _a.includes("<WITH_UNIT_TESTS>X</WITH_UNIT_TESTS>")) === false) {
52
+ const id = obj.getIdentifier();
53
+ if (id) {
54
+ const message = "Has testclass, but XML does not set <WITH_UNIT_TESTS>";
55
+ const issue = issue_1.Issue.atIdentifier(id, message, this.getMetadata().key, this.conf.severity);
56
+ issues.push(issue);
57
+ }
58
+ }
59
+ return issues;
60
+ }
61
+ }
62
+ exports.LocalTestclassConsistency = LocalTestclassConsistency;
63
+ //# sourceMappingURL=local_testclass_consistency.js.map
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NoInlineInOptionalBranches = exports.NoInlineInOptionalBranchesConf = 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 Expressions = require("../abap/2_statements/expressions");
9
+ const _irule_1 = require("./_irule");
10
+ class NoInlineInOptionalBranchesConf extends _basic_rule_config_1.BasicRuleConfig {
11
+ }
12
+ exports.NoInlineInOptionalBranchesConf = NoInlineInOptionalBranchesConf;
13
+ class NoInlineInOptionalBranches extends _abap_rule_1.ABAPRule {
14
+ constructor() {
15
+ super(...arguments);
16
+ this.conf = new NoInlineInOptionalBranchesConf();
17
+ }
18
+ getMetadata() {
19
+ return {
20
+ key: "no_inline_in_optional_branches",
21
+ title: "Don't declare inline in optional branches",
22
+ shortDescription: `Don't declare inline in optional branches`,
23
+ extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#dont-declare-inline-in-optional-branches
24
+
25
+ Considered optional branches:
26
+ * inside IF/ELSEIF/ELSE
27
+ * inside LOOP
28
+ * inside WHILE
29
+ * inside CASE/WHEN, CASE TYPE OF
30
+ * inside DO
31
+ * inside SELECT loops
32
+
33
+ Not considered optional branches:
34
+ * TRY/CATCH/CLEANUP`,
35
+ tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.SingleFile],
36
+ };
37
+ }
38
+ getConfig() {
39
+ return this.conf;
40
+ }
41
+ setConfig(conf) {
42
+ this.conf = conf;
43
+ }
44
+ runParsed(file) {
45
+ const output = [];
46
+ const struc = file.getStructure();
47
+ if (struc === undefined) {
48
+ return []; // syntax error
49
+ }
50
+ const candidates = [
51
+ ...struc.findAllStructures(Structures.If),
52
+ ...struc.findAllStructures(Structures.Loop),
53
+ ...struc.findAllStructures(Structures.While),
54
+ ...struc.findAllStructures(Structures.Case),
55
+ ...struc.findAllStructures(Structures.CaseType),
56
+ ...struc.findAllStructures(Structures.Do),
57
+ ...struc.findAllStructures(Structures.Select)
58
+ ];
59
+ for (const c of candidates) {
60
+ const inline = c.findFirstExpression(Expressions.InlineData);
61
+ if (inline) {
62
+ const message = "Don't declare inline in optional branches";
63
+ const issue = issue_1.Issue.atToken(file, c.getFirstToken(), message, this.getMetadata().key, this.getConfig().severity);
64
+ output.push(issue);
65
+ }
66
+ }
67
+ return output;
68
+ }
69
+ }
70
+ exports.NoInlineInOptionalBranches = NoInlineInOptionalBranches;
71
+ //# sourceMappingURL=no_inline_in_optional_branches.js.map
@@ -156,6 +156,7 @@ Unused variables are not reported if the object contains syntax errors. Errors f
156
156
  }
157
157
  else if (name === "ME"
158
158
  || name === "SUPER"
159
+ || meta.includes("selection_screen_tab" /* SelectionScreenTab */)
159
160
  || meta.includes("event_parameter" /* EventParameter */)) {
160
161
  // todo, workaround for "me" and "super", these should somehow be typed to built-in
161
162
  continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.88.8",
3
+ "version": "2.89.0",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",
@@ -45,10 +45,10 @@
45
45
  },
46
46
  "homepage": "https://abaplint.org",
47
47
  "devDependencies": {
48
- "@microsoft/api-extractor": "^7.22.0",
49
- "@types/chai": "^4.3.0",
48
+ "@microsoft/api-extractor": "^7.22.2",
49
+ "@types/chai": "^4.3.1",
50
50
  "@types/mocha": "^9.1.0",
51
- "@types/node": "^17.0.23",
51
+ "@types/node": "^17.0.24",
52
52
  "chai": "^4.3.6",
53
53
  "eslint": "^8.13.0",
54
54
  "mocha": "^9.2.2",
@@ -1,54 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LocalTestclassLocation = exports.LocalTestclassLocationConf = 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 objects_1 = require("../objects");
8
- const _irule_1 = require("./_irule");
9
- const version_1 = require("../version");
10
- class LocalTestclassLocationConf extends _basic_rule_config_1.BasicRuleConfig {
11
- }
12
- exports.LocalTestclassLocationConf = LocalTestclassLocationConf;
13
- class LocalTestclassLocation extends _abap_rule_1.ABAPRule {
14
- constructor() {
15
- super(...arguments);
16
- this.conf = new LocalTestclassLocationConf();
17
- }
18
- getMetadata() {
19
- return {
20
- key: "local_testclass_location",
21
- title: "Local testclass location",
22
- shortDescription: `Checks that local test classes are placed in the test include.`,
23
- tags: [_irule_1.RuleTag.SingleFile],
24
- };
25
- }
26
- getDescription(className) {
27
- return "Place local testclass \"" + className + "\" in the testclass include";
28
- }
29
- getConfig() {
30
- return this.conf;
31
- }
32
- setConfig(conf) {
33
- this.conf = conf;
34
- }
35
- runParsed(file, obj) {
36
- const issues = [];
37
- if (this.reg.getConfig().getVersion() === version_1.Version.v700) {
38
- // 700 does not have testclass includes
39
- return [];
40
- }
41
- if (!(obj instanceof objects_1.Class)) {
42
- return [];
43
- }
44
- for (const c of file.getInfo().listClassDefinitions()) {
45
- if (c.isLocal && c.isForTesting && !file.getFilename().includes(".testclasses.abap")) {
46
- const issue = issue_1.Issue.atIdentifier(c.identifier, this.getDescription(c.name), this.getMetadata().key, this.conf.severity);
47
- issues.push(issue);
48
- }
49
- }
50
- return issues;
51
- }
52
- }
53
- exports.LocalTestclassLocation = LocalTestclassLocation;
54
- //# sourceMappingURL=local_testclass_location.js.map