@abaplint/core 2.105.16 → 2.105.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/abaplint.d.ts +12 -3
- package/build/src/abap/2_statements/expressions/raise_with.js +1 -1
- package/build/src/abap/5_syntax/_current_scope.js +22 -3
- package/build/src/abap/5_syntax/expressions/raise_with.js +1 -1
- package/build/src/abap/5_syntax/expressions/source.js +11 -0
- package/build/src/abap/5_syntax/spaghetti_scope.js +4 -1
- package/build/src/abap/5_syntax/statements/class_deferred.js +1 -1
- package/build/src/abap/5_syntax/statements/interface_deferred.js +1 -1
- package/build/src/abap/5_syntax/statements/modify_internal.js +22 -2
- package/build/src/abap/5_syntax/statements/parameter.js +3 -0
- package/build/src/abap/nodes/expression_node.js +26 -0
- package/build/src/registry.js +1 -1
- package/build/src/rules/avoid_use.js +14 -3
- package/build/src/rules/downport.js +3 -3
- package/build/src/rules/method_length.js +7 -0
- package/build/src/rules/unnecessary_chaining.js +1 -1
- package/package.json +4 -4
package/build/abaplint.d.ts
CHANGED
|
@@ -1378,7 +1378,7 @@ export declare class CurrentScope {
|
|
|
1378
1378
|
addInterfaceDefinition(i: IInterfaceDefinition): void;
|
|
1379
1379
|
addNamedIdentifier(name: string, identifier: TypedIdentifier): void;
|
|
1380
1380
|
addIdentifier(identifier: TypedIdentifier | undefined): void;
|
|
1381
|
-
addDeferred(token: Token | undefined): void;
|
|
1381
|
+
addDeferred(token: Token | undefined, type: "CLAS" | "INTF"): void;
|
|
1382
1382
|
addListPrefix(identifiers: readonly TypedIdentifier[], prefix: string): void;
|
|
1383
1383
|
addList(identifiers: readonly TypedIdentifier[]): void;
|
|
1384
1384
|
addReference(usage: Token | undefined, referencing: Identifier | undefined, type: ReferenceType | ReferenceType[] | undefined, filename: string, extra?: IReferenceExtras): void;
|
|
@@ -1631,6 +1631,11 @@ declare class Default extends Expression {
|
|
|
1631
1631
|
getRunnable(): IStatementRunnable;
|
|
1632
1632
|
}
|
|
1633
1633
|
|
|
1634
|
+
declare type DeferredInformation = {
|
|
1635
|
+
token: Token;
|
|
1636
|
+
ooType: "CLAS" | "INTF";
|
|
1637
|
+
};
|
|
1638
|
+
|
|
1634
1639
|
declare class Define implements IStructure {
|
|
1635
1640
|
getMatcher(): IStructureRunnable;
|
|
1636
1641
|
}
|
|
@@ -2055,6 +2060,7 @@ declare class ExpressionNode extends AbstractNode<ExpressionNode | TokenNode> {
|
|
|
2055
2060
|
get(): IStatementRunnable;
|
|
2056
2061
|
countTokens(): number;
|
|
2057
2062
|
getFirstToken(): Token;
|
|
2063
|
+
concatTokensWithLinebreaks(): string;
|
|
2058
2064
|
concatTokens(): string;
|
|
2059
2065
|
concatTokensWithoutStringsAndComments(): string;
|
|
2060
2066
|
getTokens(): readonly Token[];
|
|
@@ -3704,7 +3710,7 @@ declare interface IScopeData {
|
|
|
3704
3710
|
[name: string]: TypedIdentifier;
|
|
3705
3711
|
};
|
|
3706
3712
|
deferred: {
|
|
3707
|
-
[name: string]:
|
|
3713
|
+
[name: string]: DeferredInformation;
|
|
3708
3714
|
};
|
|
3709
3715
|
cdefs: {
|
|
3710
3716
|
[name: string]: IClassDefinition;
|
|
@@ -5701,7 +5707,10 @@ export declare class SpaghettiScopeNode extends ScopeData implements ISpaghettiS
|
|
|
5701
5707
|
end: Position;
|
|
5702
5708
|
};
|
|
5703
5709
|
setEnd(end: Position): void;
|
|
5704
|
-
findDeferred(name: string):
|
|
5710
|
+
findDeferred(name: string): {
|
|
5711
|
+
id: Identifier | undefined;
|
|
5712
|
+
ooType: "CLAS" | "INTF";
|
|
5713
|
+
} | undefined;
|
|
5705
5714
|
findClassDefinition(name: string): IClassDefinition | undefined;
|
|
5706
5715
|
listClassDefinitions(): IClassDefinition[];
|
|
5707
5716
|
listInterfaceDefinitions(): IInterfaceDefinition[];
|
|
@@ -5,7 +5,7 @@ const combi_1 = require("../combi");
|
|
|
5
5
|
const _1 = require(".");
|
|
6
6
|
class RaiseWith extends combi_1.Expression {
|
|
7
7
|
getRunnable() {
|
|
8
|
-
const wit = (0, combi_1.seq)("WITH", _1.
|
|
8
|
+
const wit = (0, combi_1.seq)("WITH", _1.SimpleSource3, (0, combi_1.opt)(_1.SimpleSource3), (0, combi_1.opt)(_1.SimpleSource3), (0, combi_1.opt)(_1.SimpleSource3));
|
|
9
9
|
return wit;
|
|
10
10
|
}
|
|
11
11
|
}
|
|
@@ -126,11 +126,11 @@ class CurrentScope {
|
|
|
126
126
|
}
|
|
127
127
|
this.addNamedIdentifier(identifier.getName(), identifier);
|
|
128
128
|
}
|
|
129
|
-
addDeferred(token) {
|
|
129
|
+
addDeferred(token, type) {
|
|
130
130
|
if (token === undefined) {
|
|
131
131
|
return;
|
|
132
132
|
}
|
|
133
|
-
this.current.getData().deferred[token.getStr().toUpperCase()] = token;
|
|
133
|
+
this.current.getData().deferred[token.getStr().toUpperCase()] = { token, ooType: type };
|
|
134
134
|
}
|
|
135
135
|
addListPrefix(identifiers, prefix) {
|
|
136
136
|
for (const id of identifiers) {
|
|
@@ -235,7 +235,16 @@ class CurrentScope {
|
|
|
235
235
|
}
|
|
236
236
|
const def = (_c = this.current) === null || _c === void 0 ? void 0 : _c.findDeferred(name);
|
|
237
237
|
if (def !== undefined) {
|
|
238
|
-
|
|
238
|
+
let rttiName = prefixRTTI;
|
|
239
|
+
switch (def.ooType) {
|
|
240
|
+
case "INTF":
|
|
241
|
+
rttiName = rttiName + "\\INTERFACE=" + name;
|
|
242
|
+
break;
|
|
243
|
+
default:
|
|
244
|
+
rttiName = rttiName + "\\CLASS=" + name;
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
return { id: def.id, ooType: def.ooType, RTTIName: rttiName };
|
|
239
248
|
}
|
|
240
249
|
return undefined;
|
|
241
250
|
}
|
|
@@ -265,6 +274,11 @@ class CurrentScope {
|
|
|
265
274
|
if (typePoolName.length <= 1 || typePoolName.length > 5) {
|
|
266
275
|
return undefined;
|
|
267
276
|
}
|
|
277
|
+
if (this.parentObj.getType() === "TYPE"
|
|
278
|
+
&& this.parentObj.getName().toUpperCase() === typePoolName.toUpperCase()) {
|
|
279
|
+
// dont recurse into itself
|
|
280
|
+
return undefined;
|
|
281
|
+
}
|
|
268
282
|
const typePool = this.reg.getObject("TYPE", typePoolName);
|
|
269
283
|
if (typePool === undefined) {
|
|
270
284
|
return undefined;
|
|
@@ -282,6 +296,11 @@ class CurrentScope {
|
|
|
282
296
|
if (typePoolName.length <= 2 || typePoolName.length > 5) {
|
|
283
297
|
return undefined;
|
|
284
298
|
}
|
|
299
|
+
if (this.parentObj.getType() === "TYPE"
|
|
300
|
+
&& this.parentObj.getName().toUpperCase() === typePoolName.toUpperCase()) {
|
|
301
|
+
// dont recurse into itself
|
|
302
|
+
return undefined;
|
|
303
|
+
}
|
|
285
304
|
if (new ddic_1.DDIC(this.reg).lookupNoVoid(name) !== undefined) {
|
|
286
305
|
// this is tricky, it should not do recursion when parsing the type pool itself,
|
|
287
306
|
// think about DTEL ABAP_ENCOD vs TYPE ABAP
|
|
@@ -5,7 +5,7 @@ const Expressions = require("../../2_statements/expressions");
|
|
|
5
5
|
const source_1 = require("./source");
|
|
6
6
|
class RaiseWith {
|
|
7
7
|
runSyntax(node, scope, filename) {
|
|
8
|
-
for (const f of node.findDirectExpressions(Expressions.
|
|
8
|
+
for (const f of node.findDirectExpressions(Expressions.SimpleSource3)) {
|
|
9
9
|
new source_1.Source().runSyntax(f, scope, filename);
|
|
10
10
|
}
|
|
11
11
|
}
|
|
@@ -97,6 +97,11 @@ class Source {
|
|
|
97
97
|
else {
|
|
98
98
|
this.addIfInferred(node, scope, filename, foundType);
|
|
99
99
|
}
|
|
100
|
+
children.shift();
|
|
101
|
+
children.shift();
|
|
102
|
+
children.shift();
|
|
103
|
+
children.shift();
|
|
104
|
+
this.traverseRemainingChildren(children, scope, filename);
|
|
100
105
|
return foundType ? foundType : bodyType;
|
|
101
106
|
}
|
|
102
107
|
case "CONV":
|
|
@@ -213,6 +218,12 @@ class Source {
|
|
|
213
218
|
return context;
|
|
214
219
|
}
|
|
215
220
|
////////////////////////////////
|
|
221
|
+
traverseRemainingChildren(children, scope, filename) {
|
|
222
|
+
const last = children[children.length - 1];
|
|
223
|
+
if (last && last.get() instanceof Expressions.Source) {
|
|
224
|
+
new Source().runSyntax(last, scope, filename);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
216
227
|
infer(context, found) {
|
|
217
228
|
if (context instanceof basic_1.FloatType && found instanceof basic_1.IntegerType) {
|
|
218
229
|
return context;
|
|
@@ -61,7 +61,10 @@ class SpaghettiScopeNode extends ScopeData {
|
|
|
61
61
|
while (search !== undefined) {
|
|
62
62
|
const found = search.getData().deferred[name.toUpperCase()];
|
|
63
63
|
if (found) {
|
|
64
|
-
return
|
|
64
|
+
return {
|
|
65
|
+
id: new _identifier_1.Identifier(found.token, search.identifier.filename),
|
|
66
|
+
ooType: found.ooType,
|
|
67
|
+
};
|
|
65
68
|
}
|
|
66
69
|
search = search.getParent();
|
|
67
70
|
}
|
|
@@ -6,7 +6,7 @@ class ClassDeferred {
|
|
|
6
6
|
runSyntax(node, scope, _filename) {
|
|
7
7
|
var _a;
|
|
8
8
|
const name = (_a = node.findFirstExpression(Expressions.ClassName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
|
|
9
|
-
scope.addDeferred(name);
|
|
9
|
+
scope.addDeferred(name, "CLAS");
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
exports.ClassDeferred = ClassDeferred;
|
|
@@ -6,7 +6,7 @@ class InterfaceDeferred {
|
|
|
6
6
|
runSyntax(node, scope, _filename) {
|
|
7
7
|
var _a;
|
|
8
8
|
const name = (_a = node.findFirstExpression(Expressions.InterfaceName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
|
|
9
|
-
scope.addDeferred(name);
|
|
9
|
+
scope.addDeferred(name, "INTF");
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
exports.InterfaceDeferred = InterfaceDeferred;
|
|
@@ -6,13 +6,33 @@ const source_1 = require("../expressions/source");
|
|
|
6
6
|
const target_1 = require("../expressions/target");
|
|
7
7
|
const fstarget_1 = require("../expressions/fstarget");
|
|
8
8
|
const component_cond_1 = require("../expressions/component_cond");
|
|
9
|
+
const basic_1 = require("../../types/basic");
|
|
9
10
|
class ModifyInternal {
|
|
10
11
|
runSyntax(node, scope, filename) {
|
|
11
12
|
for (const s of node.findDirectExpressions(Expressions.Source)) {
|
|
12
13
|
new source_1.Source().runSyntax(s, scope, filename);
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
// there is only one
|
|
16
|
+
const targetExpression = node.findFirstExpression(Expressions.Target);
|
|
17
|
+
if (targetExpression) {
|
|
18
|
+
// it might be a dynamic target
|
|
19
|
+
const targetType = new target_1.Target().runSyntax(targetExpression, scope, filename);
|
|
20
|
+
if (targetType instanceof basic_1.VoidType
|
|
21
|
+
|| targetType instanceof basic_1.AnyType
|
|
22
|
+
|| targetType instanceof basic_1.UnknownType) {
|
|
23
|
+
// ok
|
|
24
|
+
}
|
|
25
|
+
else if (targetType instanceof basic_1.TableType) {
|
|
26
|
+
if (node.findDirectTokenByText("TABLE")
|
|
27
|
+
&& node.findDirectTokenByText("INDEX")
|
|
28
|
+
&& targetType.isWithHeader() === false) {
|
|
29
|
+
// MODIFY TABLE INDEX
|
|
30
|
+
throw new Error("Table does not have header line");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
throw new Error("Not an internal table");
|
|
35
|
+
}
|
|
16
36
|
}
|
|
17
37
|
const target = node.findDirectExpression(Expressions.FSTarget);
|
|
18
38
|
if (target) {
|
|
@@ -12,6 +12,9 @@ class Parameter {
|
|
|
12
12
|
if (nameToken && nameToken.getStr().length > 8) {
|
|
13
13
|
throw new Error("Parameter name too long, " + nameToken.getStr());
|
|
14
14
|
}
|
|
15
|
+
if (node.findDirectTokenByText("RADIOBUTTON") && node.findDirectTokenByText("LENGTH")) {
|
|
16
|
+
throw new Error("RADIOBUTTON and LENGTH not possible together");
|
|
17
|
+
}
|
|
15
18
|
const bfound = new basic_types_1.BasicTypes(filename, scope).parseType(node);
|
|
16
19
|
if (nameToken && bfound) {
|
|
17
20
|
scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(nameToken, filename, bfound));
|
|
@@ -25,6 +25,32 @@ class ExpressionNode extends _abstract_node_1.AbstractNode {
|
|
|
25
25
|
}
|
|
26
26
|
throw new Error("ExpressionNode, getFirstToken, no children");
|
|
27
27
|
}
|
|
28
|
+
concatTokensWithLinebreaks() {
|
|
29
|
+
let str = "";
|
|
30
|
+
let prev;
|
|
31
|
+
for (const token of this.getTokens()) {
|
|
32
|
+
if (token instanceof tokens_1.Pragma) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (str === "") {
|
|
36
|
+
str = token.getStr();
|
|
37
|
+
}
|
|
38
|
+
else if (prev && prev.getStr().length + prev.getCol() === token.getCol()
|
|
39
|
+
&& prev.getRow() === token.getRow()) {
|
|
40
|
+
str = str + token.getStr();
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
if (prev && prev.getRow() !== token.getRow()) {
|
|
44
|
+
str = str + "\n" + token.getStr();
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
str = str + " " + token.getStr();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
prev = token;
|
|
51
|
+
}
|
|
52
|
+
return str;
|
|
53
|
+
}
|
|
28
54
|
concatTokens() {
|
|
29
55
|
let str = "";
|
|
30
56
|
let prev;
|
package/build/src/registry.js
CHANGED
|
@@ -9,6 +9,7 @@ const expressions_1 = require("../abap/2_statements/expressions");
|
|
|
9
9
|
const _irule_1 = require("./_irule");
|
|
10
10
|
const version_1 = require("../version");
|
|
11
11
|
const edit_helper_1 = require("../edit_helper");
|
|
12
|
+
const _statement_1 = require("../abap/2_statements/statements/_statement");
|
|
12
13
|
class AvoidUseConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
13
14
|
constructor() {
|
|
14
15
|
super(...arguments);
|
|
@@ -18,11 +19,11 @@ class AvoidUseConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
|
18
19
|
this.define = true;
|
|
19
20
|
/** Detects statics */
|
|
20
21
|
this.statics = true;
|
|
21
|
-
/** Detects DEFAULT KEY definitions, from version v740sp02 and up */
|
|
22
|
+
/** Detects DEFAULT KEY definitions, from version v740sp02 and up. Use pseudo comment DEFAULT_KEY to ignore */
|
|
22
23
|
this.defaultKey = true;
|
|
23
24
|
/** Detects BREAK and BREAK-POINTS */
|
|
24
25
|
this.break = true;
|
|
25
|
-
/** Detects TEST SEAMS */
|
|
26
|
+
/** Detects TEST SEAMS. Use pseudo comment TEST_SEAM_USAGE to ignore */
|
|
26
27
|
this.testSeams = true;
|
|
27
28
|
/** Detects DESCRIBE TABLE LINES, use lines() instead */
|
|
28
29
|
this.describeLines = true;
|
|
@@ -70,7 +71,9 @@ BREAK points`,
|
|
|
70
71
|
var _a;
|
|
71
72
|
const issues = [];
|
|
72
73
|
let isStaticsBlock = false;
|
|
73
|
-
|
|
74
|
+
const statements = file.getStatements();
|
|
75
|
+
for (let i = 0; i < statements.length; i++) {
|
|
76
|
+
const statementNode = statements[i];
|
|
74
77
|
const statement = statementNode.get();
|
|
75
78
|
let message = undefined;
|
|
76
79
|
let fix = undefined;
|
|
@@ -98,6 +101,10 @@ BREAK points`,
|
|
|
98
101
|
message = "EXPORT TO DATABASE";
|
|
99
102
|
}
|
|
100
103
|
else if (this.conf.testSeams && statement instanceof Statements.TestSeam) {
|
|
104
|
+
const next = statements[i + 1];
|
|
105
|
+
if ((next === null || next === void 0 ? void 0 : next.get()) instanceof _statement_1.Comment && next.concatTokens().includes("EC TEST_SEAM_USAGE")) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
101
108
|
message = "TEST-SEAM";
|
|
102
109
|
}
|
|
103
110
|
else if (this.conf.statics && statement instanceof Statements.Static && isStaticsBlock === false) {
|
|
@@ -117,6 +124,10 @@ BREAK points`,
|
|
|
117
124
|
const tt = (_a = statementNode.findFirstExpression(expressions_1.TypeTable)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(expressions_1.TypeTableKey);
|
|
118
125
|
const token = tt === null || tt === void 0 ? void 0 : tt.findDirectTokenByText("DEFAULT");
|
|
119
126
|
if (tt && token) {
|
|
127
|
+
const next = statements[i + 1];
|
|
128
|
+
if ((next === null || next === void 0 ? void 0 : next.get()) instanceof _statement_1.Comment && next.concatTokens().includes("EC DEFAULT_KEY")) {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
120
131
|
message = "DEFAULT KEY";
|
|
121
132
|
issues.push(issue_1.Issue.atToken(file, token, this.getDescription(message), this.getMetadata().key, this.conf.severity));
|
|
122
133
|
}
|
|
@@ -1152,7 +1152,7 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
|
|
|
1152
1152
|
}
|
|
1153
1153
|
startToken = node.getFirstToken();
|
|
1154
1154
|
}
|
|
1155
|
-
const withs = ((_f = node.findDirectExpression(Expressions.RaiseWith)) === null || _f === void 0 ? void 0 : _f.findDirectExpressions(Expressions.
|
|
1155
|
+
const withs = ((_f = node.findDirectExpression(Expressions.RaiseWith)) === null || _f === void 0 ? void 0 : _f.findDirectExpressions(Expressions.SimpleSource3)) || [];
|
|
1156
1156
|
const className = ((_g = node.findDirectExpression(Expressions.ClassName)) === null || _g === void 0 ? void 0 : _g.concatTokens()) || "ERROR";
|
|
1157
1157
|
const uniqueName1 = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
1158
1158
|
const uniqueName2 = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
@@ -1540,7 +1540,7 @@ LOOP AT ${groupTargetName}tab ${groupTarget}.`;
|
|
|
1540
1540
|
const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
|
|
1541
1541
|
let code = `CLEAR ${target.concatTokens()}.\n`;
|
|
1542
1542
|
for (const fieldAssignment of fieldAssignments) {
|
|
1543
|
-
code += indentation + target.concatTokens() + "-" + fieldAssignment.
|
|
1543
|
+
code += indentation + target.concatTokens() + "-" + fieldAssignment.concatTokensWithLinebreaks() + `.\n`;
|
|
1544
1544
|
}
|
|
1545
1545
|
code = code.trimEnd();
|
|
1546
1546
|
const start = high.getFirstToken().getStart();
|
|
@@ -2210,7 +2210,7 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
2210
2210
|
body += data;
|
|
2211
2211
|
added = true;
|
|
2212
2212
|
}
|
|
2213
|
-
body += indentation + structureName + "-" + b.
|
|
2213
|
+
body += indentation + structureName + "-" + b.concatTokensWithLinebreaks() + ".\n";
|
|
2214
2214
|
}
|
|
2215
2215
|
else if (b.get() instanceof Expressions.Source) {
|
|
2216
2216
|
// note: it wont work with APPEND for Hashed/Sorted Tables, so use INSERT,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MethodLength = exports.MethodLengthConf = void 0;
|
|
4
4
|
const issue_1 = require("../issue");
|
|
5
|
+
const Objects = require("../objects");
|
|
5
6
|
const method_length_stats_1 = require("../utils/method_length_stats");
|
|
6
7
|
const _irule_1 = require("./_irule");
|
|
7
8
|
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
@@ -63,6 +64,12 @@ Abstract methods without statements are considered okay.`,
|
|
|
63
64
|
return this;
|
|
64
65
|
}
|
|
65
66
|
run(obj) {
|
|
67
|
+
var _a;
|
|
68
|
+
if (this.conf.ignoreTestClasses === true
|
|
69
|
+
&& obj instanceof Objects.Class
|
|
70
|
+
&& ((_a = obj.getClassDefinition()) === null || _a === void 0 ? void 0 : _a.isForTesting) === true) {
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
66
73
|
const methodStats = method_length_stats_1.MethodLengthStats.run(obj);
|
|
67
74
|
const methodIssues = this.check(methodStats, "METHOD");
|
|
68
75
|
let formIssues = [];
|
|
@@ -49,7 +49,7 @@ class UnnecessaryChaining extends _abap_rule_1.ABAPRule {
|
|
|
49
49
|
j = 1;
|
|
50
50
|
let prevStatement = statements[i - j];
|
|
51
51
|
while ((prevStatement === null || prevStatement === void 0 ? void 0 : prevStatement.get()) instanceof _statement_1.Comment) {
|
|
52
|
-
j
|
|
52
|
+
j++;
|
|
53
53
|
prevStatement = statements[i - j];
|
|
54
54
|
}
|
|
55
55
|
const next = nextStatement === null || nextStatement === void 0 ? void 0 : nextStatement.getColon();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/core",
|
|
3
|
-
"version": "2.105.
|
|
3
|
+
"version": "2.105.18",
|
|
4
4
|
"description": "abaplint - Core API",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/abaplint.d.ts",
|
|
@@ -50,13 +50,13 @@
|
|
|
50
50
|
},
|
|
51
51
|
"homepage": "https://abaplint.org",
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@microsoft/api-extractor": "^7.
|
|
53
|
+
"@microsoft/api-extractor": "^7.40.2",
|
|
54
54
|
"@types/chai": "^4.3.11",
|
|
55
55
|
"@types/mocha": "^10.0.6",
|
|
56
|
-
"@types/node": "^20.11.
|
|
56
|
+
"@types/node": "^20.11.19",
|
|
57
57
|
"chai": "^4.4.1",
|
|
58
58
|
"eslint": "^8.56.0",
|
|
59
|
-
"mocha": "^10.
|
|
59
|
+
"mocha": "^10.3.0",
|
|
60
60
|
"c8": "^9.1.0",
|
|
61
61
|
"source-map-support": "^0.5.21",
|
|
62
62
|
"ts-json-schema-generator": "^1.5.0",
|