@abaplint/core 2.85.21 → 2.85.24

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.
@@ -1,11 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SQLAsName = void 0;
4
+ const tokens_1 = require("../../1_lexer/tokens");
4
5
  const combi_1 = require("../combi");
5
6
  class SQLAsName extends combi_1.Expression {
6
7
  getRunnable() {
7
8
  // todo, below allows too much?
8
- return (0, combi_1.regex)(/^[&_!]?\*?\w*(\/\w+\/)?\d*[a-zA-Z_%\$][\w\*%\$\?]*(~\w+)?$/);
9
+ const field = (0, combi_1.regex)(/^[&_!]?\*?\w*(\/\w+\/)?\d*[a-zA-Z_%\$][\w\*%\$\?]*(~\w+)?$/);
10
+ return (0, combi_1.seq)(field, (0, combi_1.starPrio)((0, combi_1.seq)((0, combi_1.tok)(tokens_1.Dash), field)));
9
11
  }
10
12
  }
11
13
  exports.SQLAsName = SQLAsName;
@@ -12,7 +12,7 @@ class SQLFieldList extends combi_1.Expression {
12
12
  getRunnable() {
13
13
  const comma = (0, combi_1.optPrio)((0, combi_1.ver)(version_1.Version.v740sp05, ","));
14
14
  const abap = (0, combi_1.ver)(version_1.Version.v740sp05, (0, combi_1.seq)((0, combi_1.tok)(tokens_1.WAt), simple_field_chain_1.SimpleFieldChain));
15
- const as = (0, combi_1.seq)("AS", _1.Field);
15
+ const as = (0, combi_1.seq)("AS", _1.SQLAsName);
16
16
  const field = (0, combi_1.altPrio)(_1.SQLAggregation, _1.SQLCase, sql_function_1.SQLFunction, sql_path_1.SQLPath, _1.SQLFieldName, abap, _1.Constant);
17
17
  const sub = (0, combi_1.plusPrio)((0, combi_1.seq)((0, combi_1.altPrio)("+", "-", "*", "/", "&&"), (0, combi_1.optPrio)((0, combi_1.tok)(tokens_1.WParenLeftW)), field, (0, combi_1.optPrio)((0, combi_1.tok)(tokens_1.WParenRightW))));
18
18
  const arith = (0, combi_1.ver)(version_1.Version.v740sp05, sub);
@@ -67,6 +67,12 @@ class TypeUtils {
67
67
  }
68
68
  isOOAssignable(source, target) {
69
69
  let sid = source.getIdentifier();
70
+ let tid = target.getIdentifier();
71
+ const tname = tid.getName().toUpperCase();
72
+ const sname = sid.getName().toUpperCase();
73
+ if (tname === sname) {
74
+ return true;
75
+ }
70
76
  if (!(sid instanceof types_1.ClassDefinition || sid instanceof types_1.InterfaceDefinition)) {
71
77
  const found = this.scope.findObjectDefinition(sid.getName());
72
78
  if (found) {
@@ -76,7 +82,6 @@ class TypeUtils {
76
82
  return false;
77
83
  }
78
84
  }
79
- let tid = target.getIdentifier();
80
85
  if (!(tid instanceof types_1.ClassDefinition || tid instanceof types_1.InterfaceDefinition)) {
81
86
  const found = this.scope.findObjectDefinition(tid.getName());
82
87
  if (found) {
@@ -86,9 +91,8 @@ class TypeUtils {
86
91
  return false;
87
92
  }
88
93
  }
89
- const tname = tid.getName().toUpperCase();
90
94
  if (sid instanceof types_1.ClassDefinition && tid instanceof types_1.ClassDefinition) {
91
- if (sid.getName().toUpperCase() === tname) {
95
+ if (sname === tname) {
92
96
  return true;
93
97
  }
94
98
  const slist = this.listAllSupers(sid);
@@ -106,7 +110,7 @@ class TypeUtils {
106
110
  }
107
111
  }
108
112
  else if (sid instanceof types_1.InterfaceDefinition && tid instanceof types_1.InterfaceDefinition) {
109
- if (sid.getName().toUpperCase() === tname) {
113
+ if (sname === tname) {
110
114
  return true;
111
115
  }
112
116
  if (sid.getImplementing().some(i => i.name === tname)) {
@@ -11,6 +11,7 @@ const _reference_1 = require("../_reference");
11
11
  const _object_oriented_1 = require("../_object_oriented");
12
12
  class MethodSource {
13
13
  runSyntax(node, scope, filename) {
14
+ // todo, rewrite the context finding, and/or restructure the expression?
14
15
  const context = new method_call_chain_1.MethodCallChain().runSyntax(node, scope, filename);
15
16
  const last = node.getLastChild();
16
17
  const first = node.getFirstChild();
@@ -19,8 +20,11 @@ class MethodSource {
19
20
  }
20
21
  else if (last instanceof nodes_1.ExpressionNode && last.get() instanceof Expressions.MethodName) {
21
22
  if (context instanceof basic_1.ObjectReferenceType) {
22
- const id = context.getIdentifier();
23
- if (id instanceof types_1.ClassDefinition) {
23
+ let id = context.getIdentifier();
24
+ if (!(id instanceof types_1.ClassDefinition)) {
25
+ id = scope.findObjectDefinition(id.getName());
26
+ }
27
+ if (id instanceof types_1.ClassDefinition) { // todo || id instanceof InterfaceDefinition) {
24
28
  const methodName = last.concatTokens().toUpperCase();
25
29
  const helper = new _object_oriented_1.ObjectOriented(scope);
26
30
  const { method: foundMethod } = helper.searchMethodName(id, methodName);
@@ -72,8 +72,11 @@ class Source {
72
72
  case "SWITCH":
73
73
  {
74
74
  const foundType = this.determineType(node, scope, filename, targetType);
75
- new switch_body_1.SwitchBody().runSyntax(node.findDirectExpression(Expressions.SwitchBody), scope, filename);
76
- return foundType;
75
+ const bodyType = new switch_body_1.SwitchBody().runSyntax(node.findDirectExpression(Expressions.SwitchBody), scope, filename);
76
+ if (foundType === undefined) {
77
+ this.addIfInferred(node, scope, filename, bodyType);
78
+ }
79
+ return foundType ? foundType : bodyType;
77
80
  }
78
81
  case "COND":
79
82
  {
@@ -18,7 +18,7 @@ class SQLForAllEntries {
18
18
  if (!(type instanceof basic_1.TableType)) {
19
19
  throw new Error("FAE parameter must be table type");
20
20
  }
21
- const name = s.concatTokens();
21
+ const name = s.concatTokens().replace("[]", "");
22
22
  scope.setAllowHeaderUse(name);
23
23
  }
24
24
  }
@@ -8,9 +8,18 @@ class SwitchBody {
8
8
  if (node === undefined) {
9
9
  return;
10
10
  }
11
+ const thenSource = node.findExpressionAfterToken("THEN");
12
+ if (!((thenSource === null || thenSource === void 0 ? void 0 : thenSource.get()) instanceof Expressions.Source)) {
13
+ throw new Error("SwitchBody, unexpected");
14
+ }
15
+ const type = new source_1.Source().runSyntax(thenSource, scope, filename);
11
16
  for (const s of node.findDirectExpressions(Expressions.Source)) {
17
+ if (s === thenSource) {
18
+ continue;
19
+ }
12
20
  new source_1.Source().runSyntax(s, scope, filename);
13
21
  }
22
+ return type;
14
23
  }
15
24
  }
16
25
  exports.SwitchBody = SwitchBody;
@@ -68,7 +68,7 @@ class Registry {
68
68
  }
69
69
  static abaplintVersion() {
70
70
  // magic, see build script "version.sh"
71
- return "2.85.21";
71
+ return "2.85.24";
72
72
  }
73
73
  getDDICReferences() {
74
74
  return this.references;
@@ -56,7 +56,7 @@ Current rules:
56
56
  * PARTIALLY IMPLEMENTED removed, it can be quick fixed via rule implement_methods
57
57
  * RAISE EXCEPTION ... MESSAGE
58
58
  * APPEND expression is outlined
59
- * Moving with +=, -=, /=, *=, &&=
59
+ * Moving with +=, -=, /=, *=, &&= is expanded
60
60
 
61
61
  Only one transformation is applied to a statement at a time, so multiple steps might be required to do the full downport.`,
62
62
  tags: [_irule_1.RuleTag.Experimental, _irule_1.RuleTag.Downport, _irule_1.RuleTag.Quickfix],
@@ -224,7 +224,11 @@ Only one transformation is applied to a statement at a time, so multiple steps m
224
224
  if (found) {
225
225
  return found;
226
226
  }
227
- // todo, line_exists() should be replaced before this call
227
+ found = this.replaceLineExists(high, lowFile, highSyntax);
228
+ if (found) {
229
+ return found;
230
+ }
231
+ // note: line_exists() must be replaced before this call
228
232
  found = this.replaceTableExpression(high, lowFile, highSyntax);
229
233
  if (found) {
230
234
  return found;
@@ -233,7 +237,6 @@ Only one transformation is applied to a statement at a time, so multiple steps m
233
237
  if (found) {
234
238
  return found;
235
239
  }
236
- // todo, add more rules here
237
240
  return undefined;
238
241
  }
239
242
  //////////////////////////////////////////
@@ -1089,6 +1092,53 @@ ${indentation} output = ${topTarget}.`;
1089
1092
  }
1090
1093
  return undefined;
1091
1094
  }
1095
+ findMethodCallExpression(node, token) {
1096
+ var _a;
1097
+ for (const m of node.findAllExpressions(Expressions.MethodCall)) {
1098
+ if ((_a = m.findDirectExpression(Expressions.MethodName)) === null || _a === void 0 ? void 0 : _a.getFirstToken().getStart().equals(token.getStart())) {
1099
+ return m;
1100
+ }
1101
+ }
1102
+ return undefined;
1103
+ }
1104
+ replaceLineExists(node, lowFile, highSyntax) {
1105
+ var _a, _b;
1106
+ const spag = highSyntax.spaghetti.lookupPosition(node.getFirstToken().getStart(), lowFile.getFilename());
1107
+ for (const r of (spag === null || spag === void 0 ? void 0 : spag.getData().references) || []) {
1108
+ if (r.referenceType === _reference_1.ReferenceType.BuiltinMethodReference
1109
+ && r.position.getName().toUpperCase() === "LINE_EXISTS") {
1110
+ const token = r.position.getToken();
1111
+ const expression = this.findMethodCallExpression(node, token);
1112
+ if (expression === undefined) {
1113
+ continue;
1114
+ }
1115
+ let condition = "";
1116
+ for (const c of ((_a = expression === null || expression === void 0 ? void 0 : expression.findFirstExpression(Expressions.TableExpression)) === null || _a === void 0 ? void 0 : _a.getChildren()) || []) {
1117
+ if (c.getFirstToken().getStr() === "[" || c.getFirstToken().getStr() === "]") {
1118
+ continue;
1119
+ }
1120
+ else if (c.get() instanceof Expressions.ComponentChainSimple && condition === "") {
1121
+ condition = "WITH KEY ";
1122
+ }
1123
+ condition += c.concatTokens() + " ";
1124
+ }
1125
+ const tableName = (_b = expression === null || expression === void 0 ? void 0 : expression.findFirstExpression(Expressions.SourceField)) === null || _b === void 0 ? void 0 : _b.concatTokens();
1126
+ const uniqueName = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
1127
+ const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
1128
+ const code = `DATA ${uniqueName} LIKE sy-subrc.\n` +
1129
+ indentation + `READ TABLE ${tableName} ${condition}TRANSPORTING NO FIELDS.\n` +
1130
+ indentation + uniqueName + " = sy-subrc.\n" +
1131
+ indentation;
1132
+ const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);
1133
+ const start = expression.getFirstToken().getStart();
1134
+ const end = expression.getLastToken().getEnd();
1135
+ const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, start, end, uniqueName + " = 0");
1136
+ const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
1137
+ return issue_1.Issue.atToken(lowFile, token, "Use BOOLC", this.getMetadata().key, this.conf.severity, fix);
1138
+ }
1139
+ }
1140
+ return undefined;
1141
+ }
1092
1142
  newToCreateObject(node, lowFile, highSyntax) {
1093
1143
  const source = node.findDirectExpression(Expressions.Source);
1094
1144
  let fix = undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.85.21",
3
+ "version": "2.85.24",
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.19.4",
49
49
  "@types/chai": "^4.3.0",
50
50
  "@types/mocha": "^9.1.0",
51
- "@types/node": "^17.0.19",
51
+ "@types/node": "^17.0.21",
52
52
  "chai": "^4.3.6",
53
53
  "eslint": "^8.9.0",
54
54
  "mocha": "^9.2.1",