@abaplint/core 2.86.1 → 2.86.4

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.1";
71
+ return "2.86.4";
72
72
  }
73
73
  getDDICReferences() {
74
74
  return this.references;
@@ -894,26 +894,23 @@ ${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;
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";
905
- 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";
902
+ if (forLoop.findDirectTokenByText("UNTIL")
903
+ || forLoop.findDirectTokenByText("WHILE")) {
904
+ const fieldDef = forLoop.findDirectExpression(Expressions.InlineFieldDefinition);
905
+ const field = (_c = fieldDef === null || fieldDef === void 0 ? void 0 : fieldDef.findFirstExpression(Expressions.Field)) === null || _c === void 0 ? void 0 : _c.concatTokens();
906
+ body += indentation + "DATA " + field + " TYPE i.\n";
907
+ const second = fieldDef === null || fieldDef === void 0 ? void 0 : fieldDef.getChildren()[2];
908
+ if ((second === null || second === void 0 ? void 0 : second.get()) instanceof Expressions.Source) {
909
+ body += indentation + field + " = " + second.concatTokens() + ".\n";
910
+ }
911
+ const not = forLoop.findDirectTokenByText("UNTIL") ? " NOT" : "";
914
912
  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();
913
+ body += indentation + `WHILE${not} ${cond === null || cond === void 0 ? void 0 : cond.concatTokens()}.\n`;
917
914
  end += ` ${field} = ${field} + 1.\n`;
918
915
  end += indentation + "ENDWHILE";
919
916
  }
@@ -922,7 +919,7 @@ ${indentation} output = ${topTarget}.`;
922
919
  end = "ENDLOOP";
923
920
  }
924
921
  else if (loopTargetField === undefined) {
925
- const loopTargetFieldSymbol = (_j = forLoop.findFirstExpression(Expressions.TargetFieldSymbol)) === null || _j === void 0 ? void 0 : _j.concatTokens();
922
+ const loopTargetFieldSymbol = (_d = forLoop.findFirstExpression(Expressions.TargetFieldSymbol)) === null || _d === void 0 ? void 0 : _d.concatTokens();
926
923
  body += indentation + `LOOP AT ${loopSource} ASSIGNING FIELD-SYMBOL(${loopTargetFieldSymbol}).\n`;
927
924
  end = "ENDLOOP";
928
925
  }
@@ -1269,6 +1266,7 @@ ${indentation} output = ${topTarget}.`;
1269
1266
  return undefined;
1270
1267
  }
1271
1268
  outlineCond(node, lowFile, highSyntax) {
1269
+ var _a, _b;
1272
1270
  for (const i of node.findAllExpressionsRecursive(Expressions.Source)) {
1273
1271
  if (i.getFirstToken().getStr().toUpperCase() !== "COND") {
1274
1272
  continue;
@@ -1278,13 +1276,23 @@ ${indentation} output = ${topTarget}.`;
1278
1276
  continue;
1279
1277
  }
1280
1278
  const uniqueName = this.uniqueName(i.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
1281
- const type = this.findType(i, lowFile, highSyntax);
1279
+ let type = this.findType(i, lowFile, highSyntax);
1282
1280
  if (type === undefined) {
1283
- continue;
1281
+ if (node.get() instanceof Statements.Move
1282
+ && node.findDirectExpression(Expressions.Source) === i
1283
+ && ((_a = node.findDirectExpression(Expressions.Target)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.TargetField)) !== undefined) {
1284
+ type = "LIKE " + ((_b = node.findDirectExpression(Expressions.Target)) === null || _b === void 0 ? void 0 : _b.concatTokens());
1285
+ }
1286
+ if (type === undefined) {
1287
+ continue;
1288
+ }
1289
+ }
1290
+ else {
1291
+ type = "TYPE " + type;
1284
1292
  }
1285
1293
  const indent = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
1286
1294
  const bodyCode = this.buildCondBody(body, uniqueName, indent, lowFile, highSyntax);
1287
- const abap = `DATA ${uniqueName} TYPE ${type}.\n` + bodyCode;
1295
+ const abap = `DATA ${uniqueName} ${type}.\n` + bodyCode;
1288
1296
  const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), abap);
1289
1297
  const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, i.getFirstToken().getStart(), i.getLastToken().getEnd(), uniqueName);
1290
1298
  const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
@@ -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.1",
3
+ "version": "2.86.4",
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",