@abaplint/core 2.88.9 → 2.89.1

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
@@ -198,10 +198,18 @@ class Source {
198
198
  }
199
199
  return targetType;
200
200
  }
201
- if (typeName !== "#") {
201
+ if (typeName !== "#" && typeToken) {
202
202
  const found = basic.parseType(typeExpression);
203
- if (found === undefined && scope.getDDIC().inErrorNamespace(typeName) === false) {
204
- return new basic_1.VoidType(typeName);
203
+ if (found && found instanceof unknown_type_1.UnknownType) {
204
+ if (scope.getDDIC().inErrorNamespace(typeName) === false) {
205
+ scope.addReference(typeToken, undefined, _reference_1.ReferenceType.VoidType, filename);
206
+ return new basic_1.VoidType(typeName);
207
+ }
208
+ else {
209
+ const tid = new _typed_identifier_1.TypedIdentifier(typeToken, filename, found);
210
+ scope.addReference(typeToken, tid, _reference_1.ReferenceType.TypeReference, filename);
211
+ return found;
212
+ }
205
213
  }
206
214
  else if (found === undefined) {
207
215
  throw new Error("Type \"" + typeName + "\" not found in scope, VALUE");
@@ -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.9";
71
+ return "2.89.1";
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") {
@@ -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,78 @@
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
+ const version_1 = require("../version");
11
+ class NoInlineInOptionalBranchesConf extends _basic_rule_config_1.BasicRuleConfig {
12
+ }
13
+ exports.NoInlineInOptionalBranchesConf = NoInlineInOptionalBranchesConf;
14
+ class NoInlineInOptionalBranches extends _abap_rule_1.ABAPRule {
15
+ constructor() {
16
+ super(...arguments);
17
+ this.conf = new NoInlineInOptionalBranchesConf();
18
+ }
19
+ getMetadata() {
20
+ return {
21
+ key: "no_inline_in_optional_branches",
22
+ title: "Don't declare inline in optional branches",
23
+ shortDescription: `Don't declare inline in optional branches`,
24
+ extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#dont-declare-inline-in-optional-branches
25
+
26
+ Considered optional branches:
27
+ * inside IF/ELSEIF/ELSE
28
+ * inside LOOP
29
+ * inside WHILE
30
+ * inside CASE/WHEN, CASE TYPE OF
31
+ * inside DO
32
+ * inside SELECT loops
33
+
34
+ Not considered optional branches:
35
+ * TRY/CATCH/CLEANUP`,
36
+ tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.SingleFile],
37
+ };
38
+ }
39
+ getConfig() {
40
+ return this.conf;
41
+ }
42
+ setConfig(conf) {
43
+ this.conf = conf;
44
+ }
45
+ runParsed(file) {
46
+ const output = [];
47
+ const version = this.reg.getConfig().getVersion();
48
+ if (version === version_1.Version.v700
49
+ || version === version_1.Version.v702
50
+ || version === version_1.Version.OpenABAP) {
51
+ return [];
52
+ }
53
+ const struc = file.getStructure();
54
+ if (struc === undefined) {
55
+ return []; // syntax error
56
+ }
57
+ const candidates = [
58
+ ...struc.findAllStructures(Structures.If),
59
+ ...struc.findAllStructures(Structures.Loop),
60
+ ...struc.findAllStructures(Structures.While),
61
+ ...struc.findAllStructures(Structures.Case),
62
+ ...struc.findAllStructures(Structures.CaseType),
63
+ ...struc.findAllStructures(Structures.Do),
64
+ ...struc.findAllStructures(Structures.Select)
65
+ ];
66
+ for (const c of candidates) {
67
+ const inline = c.findFirstExpression(Expressions.InlineData);
68
+ if (inline) {
69
+ const message = "Don't declare inline in optional branches";
70
+ const issue = issue_1.Issue.atToken(file, c.getFirstToken(), message, this.getMetadata().key, this.getConfig().severity);
71
+ output.push(issue);
72
+ }
73
+ }
74
+ return output;
75
+ }
76
+ }
77
+ exports.NoInlineInOptionalBranches = NoInlineInOptionalBranches;
78
+ //# sourceMappingURL=no_inline_in_optional_branches.js.map
@@ -10,6 +10,7 @@ const _irule_1 = require("./_irule");
10
10
  const _typed_identifier_1 = require("../abap/types/_typed_identifier");
11
11
  const _scope_type_1 = require("../abap/5_syntax/_scope_type");
12
12
  const _reference_1 = require("../abap/5_syntax/_reference");
13
+ const basic_1 = require("../abap/types/basic");
13
14
  class UnknownTypesConf extends _basic_rule_config_1.BasicRuleConfig {
14
15
  }
15
16
  exports.UnknownTypesConf = UnknownTypesConf;
@@ -70,6 +71,12 @@ class UnknownTypes {
70
71
  const message = r.extra.ooName + " unknown";
71
72
  ret.push(issue_1.Issue.atIdentifier(r.position, message, this.getMetadata().key, this.conf.severity));
72
73
  }
74
+ if (r.referenceType === _reference_1.ReferenceType.TypeReference
75
+ && r.resolved instanceof _typed_identifier_1.TypedIdentifier
76
+ && r.resolved.getType() instanceof basic_1.UnknownType) {
77
+ const message = r.resolved.getType().getError();
78
+ ret.push(issue_1.Issue.atIdentifier(r.position, message, this.getMetadata().key, this.conf.severity));
79
+ }
73
80
  }
74
81
  if (node.getIdentifier().stype !== _scope_type_1.ScopeType.ClassImplementation) {
75
82
  const vars = nodeData.vars;
@@ -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.9",
3
+ "version": "2.89.1",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",
@@ -48,7 +48,7 @@
48
48
  "@microsoft/api-extractor": "^7.22.2",
49
49
  "@types/chai": "^4.3.1",
50
50
  "@types/mocha": "^9.1.0",
51
- "@types/node": "^17.0.24",
51
+ "@types/node": "^17.0.25",
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