@abaplint/core 2.118.4 → 2.118.5

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.
@@ -383,6 +383,7 @@ declare class Attributes implements IAttributes {
383
383
  private readonly tlist;
384
384
  private readonly filename;
385
385
  private readonly aliases;
386
+ private readonly declaredInterfaces;
386
387
  constructor(node: StructureNode, input: SyntaxInput);
387
388
  getTypes(): TypeDefinitions;
388
389
  getStatic(): ClassAttribute[];
@@ -1189,6 +1190,7 @@ declare class ClassDefinition_3 extends Identifier implements IClassDefinition {
1189
1190
  private readonly globalValue;
1190
1191
  private readonly sharedMemory;
1191
1192
  private readonly aliases;
1193
+ private readonly createVisibilityValue;
1192
1194
  constructor(node: StructureNode, input: SyntaxInput);
1193
1195
  getFriends(): string[];
1194
1196
  getEvents(): IEventDefinition[];
@@ -1203,6 +1205,7 @@ declare class ClassDefinition_3 extends Identifier implements IClassDefinition {
1203
1205
  isForTesting(): boolean;
1204
1206
  isAbstract(): boolean;
1205
1207
  isSharedMemory(): boolean;
1208
+ getCreateVisibility(): Visibility;
1206
1209
  private findSuper;
1207
1210
  private checkMethodNameLength;
1208
1211
  private checkMethodsFromSuperClasses;
@@ -1533,6 +1536,7 @@ export declare class CurrentScope {
1533
1536
  protected current: SpaghettiScopeNode | undefined;
1534
1537
  protected allowHeaderUse: string | undefined;
1535
1538
  protected parentObj: IObject;
1539
+ private readonly localFriends;
1536
1540
  static buildDefault(reg: IRegistry, obj: IObject): CurrentScope;
1537
1541
  private static addBuiltIn;
1538
1542
  private constructor();
@@ -1581,6 +1585,9 @@ export declare class CurrentScope {
1581
1585
  push(stype: ScopeType, sname: string, start: Position, filename: string): void;
1582
1586
  isOO(): boolean;
1583
1587
  isAnyOO(): boolean;
1588
+ addLocalFriend(className: string, friendName: string): void;
1589
+ isLocalFriend(className: string, friendName: string): boolean;
1590
+ getEnclosingClassName(): string | undefined;
1584
1591
  isGlobalOO(): boolean;
1585
1592
  isTypePool(): boolean;
1586
1593
  setAllowHeaderUse(name: string): void;
@@ -3277,6 +3284,7 @@ export declare interface IClassDefinition extends IInterfaceDefinition {
3277
3284
  isAbstract(): boolean;
3278
3285
  isSharedMemory(): boolean;
3279
3286
  getFriends(): string[];
3287
+ getCreateVisibility(): Visibility;
3280
3288
  }
3281
3289
 
3282
3290
  declare interface IClassImplementation extends Identifier {
@@ -13,7 +13,9 @@ class ReadTable {
13
13
  const key = (0, combi_1.seq)((0, combi_1.altPrio)("WITH KEY", "WITH TABLE KEY"), (0, combi_1.alt)(expressions_1.ComponentCompareSimple, components, (0, combi_1.seq)((0, combi_1.optPrio)("="), expressions_1.Source)));
14
14
  const using = (0, combi_1.seq)("USING KEY", (0, combi_1.alt)(expressions_1.Field, expressions_1.Dynamic));
15
15
  const from = (0, combi_1.seq)("FROM", expressions_1.Source);
16
- const perm = (0, combi_1.per)((0, combi_1.alt)(index, key, from), expressions_1.ReadTableTarget, using, comparing, "CASTING", (0, combi_1.seq)("TRANSPORTING", (0, combi_1.altPrio)("ALL FIELDS", "NO FIELDS", transporting_fields_1.TransportingFields)), "BINARY SEARCH");
16
+ const transporting = (0, combi_1.seq)("TRANSPORTING", (0, combi_1.altPrio)("ALL FIELDS", "NO FIELDS", transporting_fields_1.TransportingFields));
17
+ const common = [expressions_1.ReadTableTarget, comparing, "CASTING", transporting, "BINARY SEARCH"];
18
+ const perm = (0, combi_1.alt)((0, combi_1.per)((0, combi_1.alt)(index, from), using, ...common), (0, combi_1.per)(key, ...common), (0, combi_1.per)(...common));
17
19
  return (0, combi_1.seq)("READ TABLE", (0, combi_1.alt)(expressions_1.SimpleSource2, (0, combi_1.ver)(version_1.Version.v740sp02, expressions_1.Source, version_1.Version.OpenABAP)), (0, combi_1.opt)(perm));
18
20
  }
19
21
  }
@@ -504,7 +504,7 @@ BuiltIn.methods = {
504
504
  "CONCAT_LINES_OF": {
505
505
  counter: BuiltIn.counter++,
506
506
  mandatory: {
507
- "table": new basic_1.TableType(basic_1.AnyType.get(), { withHeader: false, keyType: basic_1.TableKeyType.default }),
507
+ "table": new basic_1.TableType(basic_1.AnyType.get(), { withHeader: false, keyType: basic_1.TableKeyType.user }),
508
508
  },
509
509
  optional: {
510
510
  "sep": basic_1.CLikeType.get(),
@@ -802,7 +802,7 @@ BuiltIn.methods = {
802
802
  "LINES": {
803
803
  counter: BuiltIn.counter++,
804
804
  mandatory: {
805
- "val": new basic_1.TableType(basic_1.AnyType.get(), { withHeader: false, keyType: basic_1.TableKeyType.default }),
805
+ "val": new basic_1.TableType(basic_1.AnyType.get(), { withHeader: false, keyType: basic_1.TableKeyType.user }),
806
806
  },
807
807
  return: basic_1.IntegerType.get(),
808
808
  },
@@ -29,6 +29,7 @@ class CurrentScope {
29
29
  }
30
30
  }
31
31
  constructor(reg, obj) {
32
+ this.localFriends = new Map();
32
33
  this.current = undefined;
33
34
  this.parentObj = obj;
34
35
  this.reg = reg;
@@ -452,6 +453,27 @@ class CurrentScope {
452
453
  }
453
454
  return false;
454
455
  }
456
+ addLocalFriend(className, friendName) {
457
+ var _a;
458
+ const key = className.toUpperCase();
459
+ const list = (_a = this.localFriends.get(key)) !== null && _a !== void 0 ? _a : [];
460
+ list.push(friendName.toUpperCase());
461
+ this.localFriends.set(key, list);
462
+ }
463
+ isLocalFriend(className, friendName) {
464
+ var _a;
465
+ return ((_a = this.localFriends.get(className.toUpperCase())) === null || _a === void 0 ? void 0 : _a.includes(friendName.toUpperCase())) === true;
466
+ }
467
+ getEnclosingClassName() {
468
+ let curr = this.current;
469
+ while (curr !== undefined) {
470
+ if (curr.getIdentifier().stype === _scope_type_1.ScopeType.ClassImplementation) {
471
+ return curr.getIdentifier().sname;
472
+ }
473
+ curr = curr.getParent();
474
+ }
475
+ return undefined;
476
+ }
455
477
  isGlobalOO() {
456
478
  return this.parentObj.getType() === "INTF" || this.parentObj.getType() === "CLAS";
457
479
  }
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TypeUtils = void 0;
4
4
  const types_1 = require("../types");
5
5
  const basic_1 = require("../types/basic");
6
+ const table_type_1 = require("../types/basic/table_type");
6
7
  const enum_type_1 = require("../types/basic/enum_type");
7
8
  const cgeneric_type_1 = require("../types/basic/cgeneric_type");
8
9
  const Expressions = require("../2_statements/expressions");
@@ -431,6 +432,13 @@ class TypeUtils {
431
432
  }
432
433
  else if (source instanceof basic_1.TableType) {
433
434
  if (target instanceof basic_1.TableType) {
435
+ const sourceKeyType = source.getOptions().keyType;
436
+ const targetKeyType = target.getOptions().keyType;
437
+ if (sourceKeyType !== targetKeyType
438
+ && sourceKeyType !== table_type_1.TableKeyType.user
439
+ && targetKeyType !== table_type_1.TableKeyType.user) {
440
+ return false;
441
+ }
434
442
  return this.isAssignableStrict(source.getRowType(), target.getRowType());
435
443
  }
436
444
  else if (target instanceof basic_1.UnknownType
@@ -488,6 +496,13 @@ class TypeUtils {
488
496
  return false;
489
497
  }
490
498
  }
499
+ const sourceKeyType = source.getOptions().keyType;
500
+ const targetKeyType = target.getOptions().keyType;
501
+ if (sourceKeyType !== targetKeyType
502
+ && sourceKeyType !== table_type_1.TableKeyType.user
503
+ && targetKeyType !== table_type_1.TableKeyType.user) {
504
+ return false;
505
+ }
491
506
  return true;
492
507
  }
493
508
  return false;
@@ -527,7 +527,7 @@ class BasicTypes {
527
527
  || text === "TYPE HASHED TABLE"
528
528
  || text === "TYPE INDEX TABLE"
529
529
  || text === "TYPE ANY TABLE") {
530
- return new Types.TableType(Types.AnyType.get(), { withHeader: node.concatTokens().toUpperCase().includes("WITH HEADER LINE"), keyType: Types.TableKeyType.default });
530
+ return new Types.TableType(Types.AnyType.get(), { withHeader: node.concatTokens().toUpperCase().includes("WITH HEADER LINE"), keyType: Types.TableKeyType.user });
531
531
  }
532
532
  else if (text.startsWith("LIKE ")) {
533
533
  let sub = node.findFirstExpression(Expressions.Type);
@@ -12,6 +12,7 @@ const _type_utils_1 = require("../_type_utils");
12
12
  const _syntax_input_1 = require("../_syntax_input");
13
13
  const assert_error_1 = require("../assert_error");
14
14
  const _typed_identifier_1 = require("../../types/_typed_identifier");
15
+ const create_object_1 = require("../statements/create_object");
15
16
  class NewObject {
16
17
  static runSyntax(node, input, targetType) {
17
18
  let ret = undefined;
@@ -45,6 +46,13 @@ class NewObject {
45
46
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
46
47
  return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
47
48
  }
49
+ if (clas) {
50
+ const err = create_object_1.CreateObject.checkInstantiationAllowed(clas, input);
51
+ if (err) {
52
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), err));
53
+ return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
54
+ }
55
+ }
48
56
  }
49
57
  else if (typeName === "#" && targetType) {
50
58
  ret = targetType;
@@ -66,6 +74,13 @@ class NewObject {
66
74
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
67
75
  return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
68
76
  }
77
+ if (clas) {
78
+ const err = create_object_1.CreateObject.checkInstantiationAllowed(clas, input);
79
+ if (err) {
80
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), err));
81
+ return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
82
+ }
83
+ }
69
84
  ret = objref;
70
85
  }
71
86
  }
@@ -121,6 +121,11 @@ class Source {
121
121
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
122
122
  return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
123
123
  }
124
+ else if (foundType === null || foundType === void 0 ? void 0 : foundType.isGeneric()) {
125
+ const message = "Cannot CONV to generic type";
126
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
127
+ return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
128
+ }
124
129
  this.addIfInferred(node, input, foundType);
125
130
  return foundType;
126
131
  }
@@ -6,6 +6,7 @@ const _reference_1 = require("../_reference");
6
6
  const _syntax_input_1 = require("../_syntax_input");
7
7
  class ClassLocalFriends {
8
8
  runSyntax(node, input) {
9
+ var _a;
9
10
  const classNames = node.findAllExpressions(Expressions.ClassName);
10
11
  const found = classNames[0];
11
12
  if (found) {
@@ -36,6 +37,12 @@ class ClassLocalFriends {
36
37
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
37
38
  return;
38
39
  }
40
+ else {
41
+ const befriendedName = (_a = classNames[0]) === null || _a === void 0 ? void 0 : _a.getFirstToken().getStr();
42
+ if (befriendedName) {
43
+ input.scope.addLocalFriend(befriendedName, className);
44
+ }
45
+ }
39
46
  }
40
47
  }
41
48
  }
@@ -11,6 +11,7 @@ const types_1 = require("../../types");
11
11
  const _object_oriented_1 = require("../_object_oriented");
12
12
  const _type_utils_1 = require("../_type_utils");
13
13
  const _syntax_input_1 = require("../_syntax_input");
14
+ const visibility_1 = require("../../4_file_information/visibility");
14
15
  class CreateObject {
15
16
  runSyntax(node, input) {
16
17
  var _a;
@@ -107,8 +108,46 @@ class CreateObject {
107
108
  ooName = found.getVoided();
108
109
  }
109
110
  input.scope.addReference(t === null || t === void 0 ? void 0 : t.getFirstToken(), cdef, _reference_1.ReferenceType.ConstructorReference, input.filename, { ooName: ooName });
111
+ if (cdef !== undefined) {
112
+ const err = CreateObject.checkInstantiationAllowed(cdef, input);
113
+ if (err) {
114
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), err));
115
+ return;
116
+ }
117
+ }
110
118
  this.validateParameters(cdef, node, input);
111
119
  }
120
+ static checkInstantiationAllowed(cdef, input) {
121
+ var _a, _b;
122
+ const createVis = cdef.getCreateVisibility();
123
+ if (createVis === visibility_1.Visibility.Public) {
124
+ return undefined;
125
+ }
126
+ const enclosingClass = input.scope.getEnclosingClassName();
127
+ if (enclosingClass === undefined) {
128
+ return cdef.getName() + " cannot be instantiated, class is defined as " +
129
+ (createVis === visibility_1.Visibility.Private ? "private" : "protected");
130
+ }
131
+ if (enclosingClass.toUpperCase() === cdef.getName().toUpperCase()) {
132
+ return undefined;
133
+ }
134
+ if (cdef.getFriends().some(f => f.toUpperCase() === enclosingClass.toUpperCase()) ||
135
+ input.scope.isLocalFriend(cdef.getName(), enclosingClass)) {
136
+ return undefined;
137
+ }
138
+ if (createVis === visibility_1.Visibility.Protected) {
139
+ // subclasses are also allowed
140
+ let sup = (_a = input.scope.findClassDefinition(enclosingClass)) === null || _a === void 0 ? void 0 : _a.getSuperClass();
141
+ while (sup !== undefined) {
142
+ if (sup.toUpperCase() === cdef.getName().toUpperCase()) {
143
+ return undefined;
144
+ }
145
+ sup = (_b = input.scope.findClassDefinition(sup)) === null || _b === void 0 ? void 0 : _b.getSuperClass();
146
+ }
147
+ }
148
+ return cdef.getName() + " cannot be instantiated, class is defined as " +
149
+ (createVis === visibility_1.Visibility.Private ? "private" : "protected");
150
+ }
112
151
  validateParameters(cdef, node, input) {
113
152
  var _a, _b, _c, _d;
114
153
  if (cdef === undefined) {
@@ -11,7 +11,7 @@ const _syntax_input_1 = require("../_syntax_input");
11
11
  class Split {
12
12
  runSyntax(node, input) {
13
13
  const intoTable = node.findTokenSequencePosition("INTO", "TABLE") !== undefined;
14
- const type = intoTable ? new basic_1.TableType(basic_1.StringType.get(), { withHeader: false, keyType: basic_1.TableKeyType.default }) : basic_1.StringType.get();
14
+ const type = intoTable ? new basic_1.TableType(basic_1.StringType.get(), { withHeader: false, keyType: basic_1.TableKeyType.user }) : basic_1.StringType.get();
15
15
  for (const target of node.findAllExpressions(Expressions.Target)) {
16
16
  const inline = target.findDirectExpression(Expressions.InlineData);
17
17
  if (inline) {
@@ -26,6 +26,7 @@ class Attributes {
26
26
  this.instance = [];
27
27
  this.constants = [];
28
28
  this.aliases = [];
29
+ this.declaredInterfaces = [];
29
30
  this.tlist = [];
30
31
  this.filename = input.filename;
31
32
  this.parse(node, input);
@@ -101,8 +102,15 @@ class Attributes {
101
102
  }
102
103
  /////////////////////////////
103
104
  parse(node, input) {
105
+ var _a, _b;
104
106
  const cdef = node.findDirectStructure(Structures.ClassDefinition);
105
107
  if (cdef) {
108
+ for (const i of cdef.findAllStatements(Statements.InterfaceDef)) {
109
+ const name = (_a = i.findFirstExpression(Expressions.InterfaceName)) === null || _a === void 0 ? void 0 : _a.getFirstToken().getStr();
110
+ if (name) {
111
+ this.declaredInterfaces.push(name.toUpperCase());
112
+ }
113
+ }
106
114
  this.parseSection(cdef.findDirectStructure(Structures.PublicSection), visibility_1.Visibility.Public, input);
107
115
  this.parseSection(cdef.findDirectStructure(Structures.ProtectedSection), visibility_1.Visibility.Protected, input);
108
116
  this.parseSection(cdef.findDirectStructure(Structures.PrivateSection), visibility_1.Visibility.Private, input);
@@ -110,6 +118,12 @@ class Attributes {
110
118
  }
111
119
  const idef = node.findDirectStructure(Structures.Interface);
112
120
  if (idef) {
121
+ for (const i of idef.findAllStatements(Statements.InterfaceDef)) {
122
+ const name = (_b = i.findFirstExpression(Expressions.InterfaceName)) === null || _b === void 0 ? void 0 : _b.getFirstToken().getStr();
123
+ if (name) {
124
+ this.declaredInterfaces.push(name.toUpperCase());
125
+ }
126
+ }
113
127
  this.parseSection(idef.findDirectStructure(Structures.SectionContents), visibility_1.Visibility.Public, input);
114
128
  return;
115
129
  }
@@ -218,6 +232,12 @@ class Attributes {
218
232
  input.scope.addNamedIdentifier(aliasName.getStr(), foundAttribute);
219
233
  }
220
234
  }
235
+ else if (this.declaredInterfaces.includes(name.toUpperCase()) || input.scope.getDDIC().inErrorNamespace(name) === false) {
236
+ input.scope.addReference(compToken, undefined, _reference_1.ReferenceType.ObjectOrientedVoidReference, input.filename);
237
+ }
238
+ else {
239
+ throw new Error("Interface " + name + " not found");
240
+ }
221
241
  }
222
242
  }
223
243
  parseAttribute(node, visibility, input) {
@@ -13,6 +13,7 @@ const event_definition_1 = require("./event_definition");
13
13
  const visibility_1 = require("../4_file_information/visibility");
14
14
  const _object_oriented_1 = require("../5_syntax/_object_oriented");
15
15
  const _reference_1 = require("../5_syntax/_reference");
16
+ const _syntax_input_1 = require("../5_syntax/_syntax_input");
16
17
  class ClassDefinition extends _identifier_1.Identifier {
17
18
  constructor(node, input) {
18
19
  var _a;
@@ -50,6 +51,15 @@ class ClassDefinition extends _identifier_1.Identifier {
50
51
  this.testing = concat.includes(" FOR TESTING");
51
52
  this.sharedMemory = concat.includes(" SHARED MEMORY ENABLED");
52
53
  this.abstract = (def === null || def === void 0 ? void 0 : def.findDirectTokenByText("ABSTRACT")) !== undefined;
54
+ if (concat.includes(" CREATE PRIVATE")) {
55
+ this.createVisibilityValue = visibility_1.Visibility.Private;
56
+ }
57
+ else if (concat.includes(" CREATE PROTECTED")) {
58
+ this.createVisibilityValue = visibility_1.Visibility.Protected;
59
+ }
60
+ else {
61
+ this.createVisibilityValue = visibility_1.Visibility.Public;
62
+ }
53
63
  // perform checks after everything has been initialized
54
64
  this.checkMethodsFromSuperClasses(input.scope);
55
65
  this.checkMethodNameLength();
@@ -93,6 +103,9 @@ class ClassDefinition extends _identifier_1.Identifier {
93
103
  isSharedMemory() {
94
104
  return this.sharedMemory;
95
105
  }
106
+ getCreateVisibility() {
107
+ return this.createVisibilityValue;
108
+ }
96
109
  /*
97
110
  public getEvents() {
98
111
  }
@@ -148,8 +161,20 @@ class ClassDefinition extends _identifier_1.Identifier {
148
161
  const result = [];
149
162
  for (const n of ((_a = def === null || def === void 0 ? void 0 : def.findDirectExpression(Expressions.ClassFriends)) === null || _a === void 0 ? void 0 : _a.findDirectExpressions(Expressions.ClassName)) || []) {
150
163
  const token = n.getFirstToken();
151
- this.addReference(token, input);
152
164
  const name = token.getStr();
165
+ const s = input.scope.findClassDefinition(name);
166
+ if (s) {
167
+ input.scope.addReference(token, s, _reference_1.ReferenceType.ObjectOrientedReference, input.filename, { ooName: name.toUpperCase(), ooType: "CLAS" });
168
+ }
169
+ else if (input.scope.existsObject(name) !== undefined) {
170
+ // DEFINITION DEFERRED friend
171
+ }
172
+ else if (input.scope.getDDIC().inErrorNamespace(name) === false) {
173
+ input.scope.addReference(token, undefined, _reference_1.ReferenceType.ObjectOrientedVoidReference, input.filename);
174
+ }
175
+ else {
176
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, token, name.toUpperCase() + " does not exist"));
177
+ }
153
178
  result.push(name);
154
179
  }
155
180
  return result;
@@ -74,7 +74,7 @@ class Registry {
74
74
  }
75
75
  static abaplintVersion() {
76
76
  // magic, see build script "version.sh"
77
- return "2.118.4";
77
+ return "2.118.5";
78
78
  }
79
79
  getDDICReferences() {
80
80
  return this.ddicReferences;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CatchAndRaise = exports.CatchAndRaiseConf = 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 _irule_1 = require("./_irule");
8
+ const Structures = require("../abap/3_structures/structures");
9
+ const Statements = require("../abap/2_statements/statements");
10
+ const Expressions = require("../abap/2_statements/expressions");
11
+ class CatchAndRaiseConf extends _basic_rule_config_1.BasicRuleConfig {
12
+ }
13
+ exports.CatchAndRaiseConf = CatchAndRaiseConf;
14
+ class CatchAndRaise extends _abap_rule_1.ABAPRule {
15
+ constructor() {
16
+ super(...arguments);
17
+ this.conf = new CatchAndRaiseConf();
18
+ }
19
+ getMetadata() {
20
+ return {
21
+ key: "catch_and_raise",
22
+ title: "Catch and re-raise same exception",
23
+ shortDescription: `Reports CATCH blocks that only re-raise the caught exception without any handling`,
24
+ badExample: `TRY.\n something( ).\nCATCH zcx_something INTO DATA(lv_exc).\n RAISE EXCEPTION lv_exc.\nENDTRY.`,
25
+ goodExample: `TRY.\n something( ).\nCATCH zcx_something.\n " handle exception\nENDTRY.`,
26
+ tags: [_irule_1.RuleTag.SingleFile],
27
+ };
28
+ }
29
+ getConfig() {
30
+ return this.conf;
31
+ }
32
+ setConfig(conf) {
33
+ this.conf = conf;
34
+ }
35
+ runParsed(file) {
36
+ const issues = [];
37
+ const stru = file.getStructure();
38
+ if (stru === undefined) {
39
+ return [];
40
+ }
41
+ for (const catchStruct of stru.findAllStructures(Structures.Catch)) {
42
+ const catchStatement = catchStruct.findDirectStatement(Statements.Catch);
43
+ if (catchStatement === undefined) {
44
+ continue;
45
+ }
46
+ const target = catchStatement.findFirstExpression(Expressions.Target);
47
+ if (target === undefined) {
48
+ continue;
49
+ }
50
+ const targetField = target.findFirstExpression(Expressions.TargetField);
51
+ if (targetField === undefined) {
52
+ continue;
53
+ }
54
+ const caughtVar = targetField.getFirstToken().getStr().toUpperCase();
55
+ const allStatements = catchStruct.findAllStatementNodes();
56
+ if (allStatements.length !== 2) {
57
+ continue;
58
+ }
59
+ if (!(allStatements[1].get() instanceof Statements.Raise)) {
60
+ continue;
61
+ }
62
+ const raiseStatement = allStatements[1];
63
+ const raiseConcat = raiseStatement.concatTokens().toUpperCase().replace(/\.$/, "").trim();
64
+ if (!raiseConcat.startsWith("RAISE EXCEPTION ")) {
65
+ continue;
66
+ }
67
+ const parts = raiseConcat.split(/\s+/);
68
+ if (parts.length !== 3) {
69
+ continue;
70
+ }
71
+ if (parts[2] === caughtVar) {
72
+ issues.push(issue_1.Issue.atStatement(file, catchStatement, this.getMessage(), this.getMetadata().key, this.conf.severity));
73
+ }
74
+ }
75
+ return issues;
76
+ }
77
+ getMessage() {
78
+ return "Caught exception is immediately re-raised, CATCH block has no effect";
79
+ }
80
+ }
81
+ exports.CatchAndRaise = CatchAndRaise;
82
+ //# sourceMappingURL=catch_and_raise.js.map
@@ -28,6 +28,7 @@ __exportStar(require("./avoid_use"), exports);
28
28
  __exportStar(require("./begin_end_names"), exports);
29
29
  __exportStar(require("./begin_single_include"), exports);
30
30
  __exportStar(require("./call_transaction_authority_check"), exports);
31
+ __exportStar(require("./catch_and_raise"), exports);
31
32
  __exportStar(require("./cds_association_name"), exports);
32
33
  __exportStar(require("./cds_comment_style"), exports);
33
34
  __exportStar(require("./cds_field_order"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.118.4",
3
+ "version": "2.118.5",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",