@abaplint/core 2.86.2 → 2.86.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.
@@ -68,7 +68,7 @@ class Registry {
68
68
  }
69
69
  static abaplintVersion() {
70
70
  // magic, see build script "version.sh"
71
- return "2.86.2";
71
+ return "2.86.5";
72
72
  }
73
73
  getDDICReferences() {
74
74
  return this.references;
@@ -894,36 +894,37 @@ ${indentation} output = ${topTarget}.`;
894
894
  return undefined;
895
895
  }
896
896
  outlineFor(forLoop, indentation, lowFile, highSyntax) {
897
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
897
+ var _a, _b, _c, _d, _e;
898
898
  let body = "";
899
899
  let end = "";
900
900
  const loopSource = (_a = forLoop.findFirstExpression(Expressions.Source)) === null || _a === void 0 ? void 0 : _a.concatTokens();
901
901
  const loopTargetField = (_b = forLoop.findFirstExpression(Expressions.TargetField)) === null || _b === void 0 ? void 0 : _b.concatTokens();
902
- if (forLoop.findDirectTokenByText("UNTIL")) {
903
- const name = (_c = forLoop.findFirstExpression(Expressions.Field)) === null || _c === void 0 ? void 0 : _c.concatTokens();
904
- body += indentation + "DATA " + name + " TYPE i.\n";
902
+ let cond = ((_c = forLoop.findDirectExpression(Expressions.ComponentCond)) === null || _c === void 0 ? void 0 : _c.concatTokens()) || "";
903
+ if (cond !== "") {
904
+ cond = " WHERE " + cond;
905
+ }
906
+ if (forLoop.findDirectTokenByText("UNTIL")
907
+ || forLoop.findDirectTokenByText("WHILE")) {
908
+ const fieldDef = forLoop.findDirectExpression(Expressions.InlineFieldDefinition);
909
+ const field = (_d = fieldDef === null || fieldDef === void 0 ? void 0 : fieldDef.findFirstExpression(Expressions.Field)) === null || _d === void 0 ? void 0 : _d.concatTokens();
910
+ body += indentation + "DATA " + field + " TYPE i.\n";
911
+ const second = fieldDef === null || fieldDef === void 0 ? void 0 : fieldDef.getChildren()[2];
912
+ if ((second === null || second === void 0 ? void 0 : second.get()) instanceof Expressions.Source) {
913
+ body += indentation + field + " = " + second.concatTokens() + ".\n";
914
+ }
915
+ const not = forLoop.findDirectTokenByText("UNTIL") ? " NOT" : "";
905
916
  const cond = forLoop.findFirstExpression(Expressions.Cond);
906
- body += indentation + `WHILE NOT ${cond === null || cond === void 0 ? void 0 : cond.concatTokens()}.\n`;
907
- const field = (_e = (_d = forLoop.findDirectExpression(Expressions.InlineFieldDefinition)) === null || _d === void 0 ? void 0 : _d.findFirstExpression(Expressions.Field)) === null || _e === void 0 ? void 0 : _e.concatTokens();
908
- end += ` ${field} = ${field} + 1.\n`;
909
- end += indentation + "ENDWHILE";
910
- }
911
- else if (forLoop.findDirectTokenByText("WHILE")) {
912
- const name = (_f = forLoop.findFirstExpression(Expressions.Field)) === null || _f === void 0 ? void 0 : _f.concatTokens();
913
- body += indentation + "DATA " + name + " TYPE i.\n";
914
- const cond = forLoop.findFirstExpression(Expressions.Cond);
915
- body += indentation + `WHILE ${cond === null || cond === void 0 ? void 0 : cond.concatTokens()}.\n`;
916
- const field = (_h = (_g = forLoop.findDirectExpression(Expressions.InlineFieldDefinition)) === null || _g === void 0 ? void 0 : _g.findFirstExpression(Expressions.Field)) === null || _h === void 0 ? void 0 : _h.concatTokens();
917
+ body += indentation + `WHILE${not} ${cond === null || cond === void 0 ? void 0 : cond.concatTokens()}.\n`;
917
918
  end += ` ${field} = ${field} + 1.\n`;
918
919
  end += indentation + "ENDWHILE";
919
920
  }
920
921
  else if (loopTargetField) {
921
- body += indentation + `LOOP AT ${loopSource} INTO DATA(${loopTargetField}).\n`;
922
+ body += indentation + `LOOP AT ${loopSource} INTO DATA(${loopTargetField})${cond}.\n`;
922
923
  end = "ENDLOOP";
923
924
  }
924
925
  else if (loopTargetField === undefined) {
925
- const loopTargetFieldSymbol = (_j = forLoop.findFirstExpression(Expressions.TargetFieldSymbol)) === null || _j === void 0 ? void 0 : _j.concatTokens();
926
- body += indentation + `LOOP AT ${loopSource} ASSIGNING FIELD-SYMBOL(${loopTargetFieldSymbol}).\n`;
926
+ const loopTargetFieldSymbol = (_e = forLoop.findFirstExpression(Expressions.TargetFieldSymbol)) === null || _e === void 0 ? void 0 : _e.concatTokens();
927
+ body += indentation + `LOOP AT ${loopSource} ASSIGNING FIELD-SYMBOL(${loopTargetFieldSymbol})${cond}.\n`;
927
928
  end = "ENDLOOP";
928
929
  }
929
930
  const l = forLoop.findDirectExpression(Expressions.Let);
@@ -1026,12 +1027,12 @@ ${indentation} output = ${topTarget}.`;
1026
1027
  name = init.getFirstToken().getStr();
1027
1028
  body += indentation + `DATA(${name}) = ${(_a = reduceBody.findFirstExpression(Expressions.Source)) === null || _a === void 0 ? void 0 : _a.concatTokens()}.\n`;
1028
1029
  }
1029
- const forLoop = reduceBody.findDirectExpression(Expressions.For);
1030
- if (forLoop === undefined) {
1031
- continue;
1030
+ let end = "";
1031
+ for (const forLoop of (reduceBody === null || reduceBody === void 0 ? void 0 : reduceBody.findDirectExpressions(Expressions.For)) || []) {
1032
+ const outlineFor = this.outlineFor(forLoop, indentation, lowFile, highSyntax);
1033
+ body += outlineFor.body;
1034
+ end = outlineFor.end + `.\n` + end;
1032
1035
  }
1033
- const outlineFor = this.outlineFor(forLoop, indentation, lowFile, highSyntax);
1034
- body += outlineFor.body;
1035
1036
  const next = reduceBody.findDirectExpression(Expressions.ReduceNext);
1036
1037
  if (next === undefined) {
1037
1038
  continue;
@@ -1051,7 +1052,7 @@ ${indentation} output = ${topTarget}.`;
1051
1052
  body += concat;
1052
1053
  }
1053
1054
  }
1054
- body += indentation + outlineFor.end + `.\n`;
1055
+ body += indentation + end;
1055
1056
  body += indentation + `${uniqueName} = ${name}.\n`;
1056
1057
  const abap = `DATA ${uniqueName} TYPE ${type}.\n` +
1057
1058
  body +
@@ -1351,6 +1352,10 @@ ${indentation} output = ${topTarget}.`;
1351
1352
  if (i.getFirstToken().getStr().toUpperCase() !== "CONV") {
1352
1353
  continue;
1353
1354
  }
1355
+ const end = i.findDirectTokenByText(")");
1356
+ if (end === undefined) {
1357
+ continue;
1358
+ }
1354
1359
  const body = (_a = i.findDirectExpression(Expressions.ConvBody)) === null || _a === void 0 ? void 0 : _a.concatTokens();
1355
1360
  if (body === undefined) {
1356
1361
  continue;
@@ -1362,7 +1367,7 @@ ${indentation} output = ${topTarget}.`;
1362
1367
  indent + `${uniqueName} = ${body}.\n` +
1363
1368
  indent;
1364
1369
  const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), abap);
1365
- const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, i.getFirstToken().getStart(), i.getLastToken().getEnd(), uniqueName);
1370
+ const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, i.getFirstToken().getStart(), end.getEnd(), uniqueName);
1366
1371
  const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
1367
1372
  return issue_1.Issue.atToken(lowFile, i.getFirstToken(), "Downport CONV", this.getMetadata().key, this.conf.severity, fix);
1368
1373
  }
@@ -19,6 +19,7 @@ class NoAliases extends _abap_rule_1.ABAPRule {
19
19
  key: "no_aliases",
20
20
  title: "No ALIASES",
21
21
  shortDescription: `Detects use of the ALIAS statement`,
22
+ extendedInformation: `Only one issue is reported for chained statements`,
22
23
  tags: [_irule_1.RuleTag.SingleFile],
23
24
  };
24
25
  }
@@ -31,9 +32,14 @@ class NoAliases extends _abap_rule_1.ABAPRule {
31
32
  runParsed(file) {
32
33
  const issues = [];
33
34
  const message = "Do not use ALIASES";
35
+ let prev = undefined;
34
36
  for (const stat of file.getStatements()) {
35
37
  if (stat.get() instanceof Statements.Aliases) {
38
+ if (prev && prev.getColon() === stat.getColon()) {
39
+ continue;
40
+ }
36
41
  issues.push(issue_1.Issue.atStatement(file, stat, message, this.getMetadata().key, this.conf.severity));
42
+ prev = stat;
37
43
  }
38
44
  }
39
45
  return issues;
@@ -33,7 +33,6 @@ class UnnecessaryChaining extends _abap_rule_1.ABAPRule {
33
33
  this.conf = conf;
34
34
  }
35
35
  runParsed(file) {
36
- var _a;
37
36
  const issues = [];
38
37
  const statements = file.getStatements();
39
38
  for (let i = 0; i < statements.length; i++) {
@@ -41,15 +40,20 @@ class UnnecessaryChaining extends _abap_rule_1.ABAPRule {
41
40
  if (colon === undefined) {
42
41
  continue;
43
42
  }
44
- // find the next non Comment statement
45
43
  let j = 1;
46
44
  let nextStatement = statements[i + j];
47
45
  while ((nextStatement === null || nextStatement === void 0 ? void 0 : nextStatement.get()) instanceof _statement_1.Comment) {
48
46
  j++;
49
47
  nextStatement = statements[i + j];
50
48
  }
49
+ j = 1;
50
+ let prevStatement = statements[i - j];
51
+ while ((prevStatement === null || prevStatement === void 0 ? void 0 : prevStatement.get()) instanceof _statement_1.Comment) {
52
+ j--;
53
+ prevStatement = statements[i - j];
54
+ }
51
55
  const next = nextStatement === null || nextStatement === void 0 ? void 0 : nextStatement.getColon();
52
- const prev = (_a = statements[i - 1]) === null || _a === void 0 ? void 0 : _a.getColon();
56
+ const prev = prevStatement === null || prevStatement === void 0 ? void 0 : prevStatement.getColon();
53
57
  if (next !== undefined && colon.getStart().equals(next.getStart())) {
54
58
  continue;
55
59
  }
@@ -36,25 +36,6 @@ class WorkArea {
36
36
  return this.workarea.length;
37
37
  }
38
38
  }
39
- /*
40
- function removeDuplicates(list: readonly TypedIdentifier[]): readonly TypedIdentifier[] {
41
- const deduplicated: TypedIdentifier[] = [];
42
- for (const result of list) {
43
- let cont = false;
44
- for (const d of deduplicated) {
45
- if (result.getStart().equals(d.getStart())) {
46
- cont = true;
47
- break;
48
- }
49
- }
50
- if (cont === true) {
51
- continue;
52
- }
53
- deduplicated.push(result);
54
- }
55
- return deduplicated;
56
- }
57
- */
58
39
  class UnusedTypesConf extends _basic_rule_config_1.BasicRuleConfig {
59
40
  constructor() {
60
41
  super(...arguments);
@@ -149,7 +130,6 @@ class UnusedTypes {
149
130
  }
150
131
  }
151
132
  checkNode(node, obj, add) {
152
- var _a;
153
133
  const ret = [];
154
134
  if (add === true) {
155
135
  const types = node.getData().types;
@@ -158,7 +138,8 @@ class UnusedTypes {
158
138
  if (obj.containsFile(identifier.getFilename()) === false) {
159
139
  continue;
160
140
  }
161
- else if (((_a = this.conf.skipNames) === null || _a === void 0 ? void 0 : _a.length) > 0
141
+ else if (this.conf.skipNames
142
+ && this.conf.skipNames.length > 0
162
143
  && this.conf.skipNames.some((a) => a.toUpperCase() === name)) {
163
144
  continue;
164
145
  }
@@ -138,7 +138,6 @@ Unused variables are not reported if the object contains syntax errors. Errors f
138
138
  }
139
139
  }
140
140
  buildWorkarea(node, obj) {
141
- var _a;
142
141
  const stype = node.getIdentifier().stype;
143
142
  if (stype === _scope_type_1.ScopeType.OpenSQL) {
144
143
  return;
@@ -150,7 +149,8 @@ Unused variables are not reported if the object contains syntax errors. Errors f
150
149
  const vars = node.getData().vars;
151
150
  for (const name in vars) {
152
151
  const meta = vars[name].getMeta();
153
- if (((_a = this.conf.skipNames) === null || _a === void 0 ? void 0 : _a.length) > 0
152
+ if (this.conf.skipNames
153
+ && this.conf.skipNames.length > 0
154
154
  && this.conf.skipNames.some((a) => a.toUpperCase() === name)) {
155
155
  continue;
156
156
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.86.2",
3
+ "version": "2.86.5",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "homepage": "https://abaplint.org",
47
47
  "devDependencies": {
48
- "@microsoft/api-extractor": "^7.19.5",
48
+ "@microsoft/api-extractor": "^7.20.0",
49
49
  "@types/chai": "^4.3.0",
50
50
  "@types/mocha": "^9.1.0",
51
51
  "@types/node": "^17.0.23",