@abaplint/transpiler-cli 2.13.99 → 2.13.100

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.
Files changed (2) hide show
  1. package/build/bundle.js +130 -13
  2. package/package.json +3 -3
package/build/bundle.js CHANGED
@@ -32488,6 +32488,9 @@ class FormParam {
32488
32488
  else if (typeName === "P" && bfound instanceof basic_1.PackedType) {
32489
32489
  bfound = basic_1.PGenericType.get();
32490
32490
  }
32491
+ else if (typeName === "N" && bfound instanceof basic_1.NumericType) {
32492
+ bfound = basic_1.NGenericType.get();
32493
+ }
32491
32494
  }
32492
32495
  if (nameToken && bfound) {
32493
32496
  return new _typed_identifier_1.TypedIdentifier(nameToken, input.filename, bfound, ["form_parameter" /* IdentifierMeta.FormParameter */]);
@@ -33874,6 +33877,9 @@ class MethodParam {
33874
33877
  else if (concat === "TYPE P" || concat.startsWith("TYPE P ")) {
33875
33878
  return new _typed_identifier_1.TypedIdentifier(name.getFirstToken(), input.filename, basic_1.PGenericType.get(), meta);
33876
33879
  }
33880
+ else if (concat === "TYPE N" || concat.startsWith("TYPE N ")) {
33881
+ return new _typed_identifier_1.TypedIdentifier(name.getFirstToken(), input.filename, basic_1.NGenericType.get(), meta);
33882
+ }
33877
33883
  const found = new basic_types_1.BasicTypes(input).parseType(type);
33878
33884
  if (found) {
33879
33885
  return new _typed_identifier_1.TypedIdentifier(name.getFirstToken(), input.filename, found, meta);
@@ -40576,9 +40582,9 @@ class CreateObject {
40576
40582
  if (name === undefined) {
40577
40583
  continue;
40578
40584
  }
40579
- const source = p.findDirectExpression(Expressions.Source);
40580
- const sourceType = source_1.Source.runSyntax(source, input);
40581
40585
  const found = allImporting === null || allImporting === void 0 ? void 0 : allImporting.find(p => p.getName().toUpperCase() === name);
40586
+ const source = p.findDirectExpression(Expressions.Source);
40587
+ const sourceType = source_1.Source.runSyntax(source, input, found === null || found === void 0 ? void 0 : found.getType());
40582
40588
  if (found === undefined) {
40583
40589
  const message = `constructor parameter "${name}" does not exist`;
40584
40590
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
@@ -52035,6 +52041,7 @@ __exportStar(__webpack_require__(/*! ./generic_object_reference_type */ "./node_
52035
52041
  __exportStar(__webpack_require__(/*! ./hex_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/hex_type.js"), exports);
52036
52042
  __exportStar(__webpack_require__(/*! ./integer_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/integer_type.js"), exports);
52037
52043
  __exportStar(__webpack_require__(/*! ./integer8_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/integer8_type.js"), exports);
52044
+ __exportStar(__webpack_require__(/*! ./ngeneric_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/ngeneric_type.js"), exports);
52038
52045
  __exportStar(__webpack_require__(/*! ./numeric_generic_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/numeric_generic_type.js"), exports);
52039
52046
  __exportStar(__webpack_require__(/*! ./numeric_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/numeric_type.js"), exports);
52040
52047
  __exportStar(__webpack_require__(/*! ./object_reference_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/object_reference_type.js"), exports);
@@ -52143,6 +52150,39 @@ IntegerType.singletons = new Map();
52143
52150
 
52144
52151
  /***/ },
52145
52152
 
52153
+ /***/ "./node_modules/@abaplint/core/build/src/abap/types/basic/ngeneric_type.js"
52154
+ /*!*********************************************************************************!*\
52155
+ !*** ./node_modules/@abaplint/core/build/src/abap/types/basic/ngeneric_type.js ***!
52156
+ \*********************************************************************************/
52157
+ (__unused_webpack_module, exports, __webpack_require__) {
52158
+
52159
+ "use strict";
52160
+
52161
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
52162
+ exports.NGenericType = void 0;
52163
+ const numeric_type_1 = __webpack_require__(/*! ./numeric_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/numeric_type.js");
52164
+ // "TYPE n" of a method or FORM parameter, where no length can be given.
52165
+ // It is a NumericType, so everything that handles n keeps treating it as such
52166
+ class NGenericType extends numeric_type_1.NumericType {
52167
+ static get() {
52168
+ return this.singleton;
52169
+ }
52170
+ constructor() {
52171
+ super(1);
52172
+ }
52173
+ toText() {
52174
+ return "```n```";
52175
+ }
52176
+ isGeneric() {
52177
+ return true;
52178
+ }
52179
+ }
52180
+ exports.NGenericType = NGenericType;
52181
+ NGenericType.singleton = new NGenericType();
52182
+ //# sourceMappingURL=ngeneric_type.js.map
52183
+
52184
+ /***/ },
52185
+
52146
52186
  /***/ "./node_modules/@abaplint/core/build/src/abap/types/basic/numeric_generic_type.js"
52147
52187
  /*!****************************************************************************************!*\
52148
52188
  !*** ./node_modules/@abaplint/core/build/src/abap/types/basic/numeric_generic_type.js ***!
@@ -71037,7 +71077,7 @@ class Registry {
71037
71077
  }
71038
71078
  static abaplintVersion() {
71039
71079
  // magic, see build script "version.js"
71040
- return "2.120.68";
71080
+ return "2.120.69";
71041
71081
  }
71042
71082
  getDDICReferences() {
71043
71083
  return this.ddicReferences;
@@ -80536,8 +80576,17 @@ ${indentation} output = ${uniqueName}.\n`;
80536
80576
  const extra = (valueBody === null || valueBody === void 0 ? void 0 : valueBody.findDirectExpression(Expressions.For)) ? " " : "";
80537
80577
  data = indentation + extra + `DATA ${structureName} LIKE LINE OF ${uniqueName}.\n`;
80538
80578
  }
80579
+ // all rows are built in the same work area, a component a row leaves out must be initial,
80580
+ // not what an earlier row (or an earlier pass of a surrounding loop) put there
80581
+ const clearRows = valueBody !== undefined && this.valueRowsNeedClear(valueBody);
80582
+ const prefix = [];
80539
80583
  for (const a of (valueBody === null || valueBody === void 0 ? void 0 : valueBody.getChildren()) || []) {
80540
80584
  if (a.get() instanceof Expressions.FieldAssignment) {
80585
+ if (clearRows === true) {
80586
+ // the shared prefix applies to every following row, re-applied after each CLEAR
80587
+ prefix.push(a.concatTokens());
80588
+ continue;
80589
+ }
80541
80590
  if (added === false) {
80542
80591
  body += data;
80543
80592
  added = true;
@@ -80561,6 +80610,16 @@ ${indentation} output = ${uniqueName}.\n`;
80561
80610
  }
80562
80611
  if (a instanceof nodes_1.ExpressionNode && a.get() instanceof Expressions.ValueBodyLine) {
80563
80612
  let skip = false;
80613
+ if (clearRows === true && this.isStructuredValueRow(a)) {
80614
+ if (added === false) {
80615
+ body += data;
80616
+ added = true;
80617
+ }
80618
+ body += indentation + `CLEAR ${structureName}.\n`;
80619
+ for (const p of prefix) {
80620
+ body += indentation + structureName + "-" + p + ".\n";
80621
+ }
80622
+ }
80564
80623
  for (const b of (a === null || a === void 0 ? void 0 : a.getChildren()) || []) {
80565
80624
  if (b.get() instanceof Expressions.FieldAssignment) {
80566
80625
  if (added === false) {
@@ -80639,6 +80698,39 @@ ${indentation} output = ${uniqueName}.\n`;
80639
80698
  }
80640
80699
  return undefined;
80641
80700
  }
80701
+ /** a row that is built in the work area, ie. not "( source )" or "( LINES OF source )" */
80702
+ isStructuredValueRow(row) {
80703
+ return row.findDirectExpression(Expressions.Source) === undefined
80704
+ && row.findDirectExpression(Expressions.ValueBodyLines) === undefined;
80705
+ }
80706
+ /** true if a row can observe a component that an earlier row, or an earlier pass of a surrounding loop,
80707
+ * left in the shared work area. Not the case if all rows assign the same components, and the shared
80708
+ * prefix is not changed between rows, eg. FOR rows or "( a = 1 b = 2 ) ( a = 3 b = 4 )" */
80709
+ valueRowsNeedClear(valueBody) {
80710
+ let shape = undefined;
80711
+ let rowSeen = false;
80712
+ for (const c of valueBody.getChildren()) {
80713
+ if (c.get() instanceof Expressions.FieldAssignment) {
80714
+ if (rowSeen === true) {
80715
+ return true;
80716
+ }
80717
+ }
80718
+ else if (c instanceof nodes_1.ExpressionNode
80719
+ && c.get() instanceof Expressions.ValueBodyLine
80720
+ && this.isStructuredValueRow(c)) {
80721
+ rowSeen = true;
80722
+ const current = c.findDirectExpressions(Expressions.FieldAssignment)
80723
+ .map(f => { var _a; return (_a = f.findDirectExpression(Expressions.FieldSub)) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase().replace(/\s/g, ""); })
80724
+ .sort()
80725
+ .join(",");
80726
+ if (shape !== undefined && shape !== current) {
80727
+ return true;
80728
+ }
80729
+ shape = current;
80730
+ }
80731
+ }
80732
+ return false;
80733
+ }
80642
80734
  outlineLet(node, indentation, highSyntax, lowFile) {
80643
80735
  var _a;
80644
80736
  let ret = "";
@@ -95914,7 +96006,9 @@ class RFCErrorHandling extends _abap_rule_1.ABAPRule {
95914
96006
  title: "RFC error handling",
95915
96007
  tags: [_irule_1.RuleTag.SingleFile],
95916
96008
  shortDescription: `Checks that exceptions 'system_failure' and 'communication_failure' are handled in RFC calls`,
95917
- extendedInformation: `https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/abenrfc_exception.html`,
96009
+ extendedInformation: `RESOURCE_FAILURE is also required for asynchronous calls with DESTINATION IN GROUP.
96010
+
96011
+ https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/abenrfc_exception.html`,
95918
96012
  badExample: `CALL FUNCTION 'ZRFC'
95919
96013
  DESTINATION lv_rfc.`,
95920
96014
  goodExample: `CALL FUNCTION 'ZRFC'
@@ -95922,12 +96016,12 @@ class RFCErrorHandling extends _abap_rule_1.ABAPRule {
95922
96016
  EXCEPTIONS
95923
96017
  system_failure = 1 MESSAGE msg
95924
96018
  communication_failure = 2 MESSAGE msg
95925
- resource_failure = 3
95926
- OTHERS = 4.`,
96019
+ OTHERS = 3.`,
95927
96020
  };
95928
96021
  }
95929
- getMessage() {
95930
- return "RFC error handling: At least one unhandled exception from SYSTEM_FAILURE, COMMUNICATION_FAILURE, RESOURCE_FAILURE";
96022
+ getMessage(requireResourceFailure) {
96023
+ return "RFC error handling: At least one unhandled exception from SYSTEM_FAILURE, COMMUNICATION_FAILURE"
96024
+ + (requireResourceFailure ? ", RESOURCE_FAILURE" : "");
95931
96025
  }
95932
96026
  getConfig() {
95933
96027
  return this.conf;
@@ -95942,12 +96036,15 @@ class RFCErrorHandling extends _abap_rule_1.ABAPRule {
95942
96036
  if (!(stat.get() instanceof Statements.CallFunction)) {
95943
96037
  continue;
95944
96038
  }
95945
- if (!stat.findFirstExpression(Expressions.Destination)) {
96039
+ const destination = stat.findFirstExpression(Expressions.Destination);
96040
+ if (destination === undefined) {
95946
96041
  continue;
95947
96042
  }
96043
+ const requireResourceFailure = stat.findDirectTokenByText("STARTING") !== undefined
96044
+ && destination.findDirectTokenByText("GROUP") !== undefined;
95948
96045
  const list = stat.findFirstExpression(Expressions.ParameterListExceptions);
95949
96046
  if (list === undefined) {
95950
- const issue = issue_1.Issue.atToken(file, token, this.getMessage(), this.getMetadata().key, this.conf.severity);
96047
+ const issue = issue_1.Issue.atToken(file, token, this.getMessage(requireResourceFailure), this.getMetadata().key, this.conf.severity);
95951
96048
  output.push(issue);
95952
96049
  continue;
95953
96050
  }
@@ -95958,8 +96055,8 @@ class RFCErrorHandling extends _abap_rule_1.ABAPRule {
95958
96055
  }
95959
96056
  if (names.indexOf("SYSTEM_FAILURE") < 0
95960
96057
  || names.indexOf("COMMUNICATION_FAILURE") < 0
95961
- || names.indexOf("RESOURCE_FAILURE") < 0) {
95962
- const issue = issue_1.Issue.atToken(file, token, this.getMessage(), this.getMetadata().key, this.conf.severity);
96058
+ || (requireResourceFailure && names.indexOf("RESOURCE_FAILURE") < 0)) {
96059
+ const issue = issue_1.Issue.atToken(file, token, this.getMessage(requireResourceFailure), this.getMetadata().key, this.conf.severity);
95963
96060
  output.push(issue);
95964
96061
  continue;
95965
96062
  }
@@ -121228,8 +121325,18 @@ class SelectTranspiler {
121228
121325
  const having = node.findDirectExpression(abaplint.Expressions.Select)
121229
121326
  ?.findDirectExpression(abaplint.Expressions.SQLHaving);
121230
121327
  const havingCond = having?.findFirstExpression(abaplint.Expressions.SQLCond);
121328
+ let dynamicHaving;
121231
121329
  if (havingCond) {
121232
- select += "HAVING " + new expressions_1.SQLCondTranspiler().transpile(havingCond, traversal, table).getCode() + " ";
121330
+ const dynamic = havingCond.findFirstExpression(abaplint.Expressions.Dynamic);
121331
+ const chain = dynamic?.findFirstExpression(abaplint.Expressions.FieldChain);
121332
+ if (chain && havingCond.concatTokens() === dynamic?.concatTokens()) {
121333
+ dynamicHaving = dynamic;
121334
+ const code = new expressions_1.FieldChainTranspiler(false).transpile(chain, traversal).getCode();
121335
+ select += `" + ${this.dynamicHavingClause(code)} + " `;
121336
+ }
121337
+ else {
121338
+ select += "HAVING " + new expressions_1.SQLCondTranspiler().transpile(havingCond, traversal, table).getCode() + " ";
121339
+ }
121233
121340
  }
121234
121341
  const upTo = node.findFirstExpression(abaplint.Expressions.SQLUpTo);
121235
121342
  if (upTo) {
@@ -121249,6 +121356,9 @@ class SelectTranspiler {
121249
121356
  const groupByDynamics = new Set(groupBy?.findAllExpressionsRecursive(abaplint.Expressions.Dynamic) || []);
121250
121357
  const orderByDynamics = new Set(orderBy?.findAllExpressionsRecursive(abaplint.Expressions.Dynamic) || []);
121251
121358
  for (const d of node.findAllExpressionsRecursive(abaplint.Expressions.Dynamic)) {
121359
+ if (d === dynamicHaving) {
121360
+ continue;
121361
+ }
121252
121362
  const chain = d.findFirstExpression(abaplint.Expressions.FieldChain);
121253
121363
  if (chain) {
121254
121364
  const search = d.concatTokens();
@@ -121405,6 +121515,13 @@ abap.builtin.sy.get().dbcnt.set(${target}.getArrayLength());
121405
121515
  + ` ? (${code}.array().length === 0 ? "" : "${keyword} " + ${code}.array().map(row => row.get()).join(", "))`
121406
121516
  + ` : (("" + ${code}.get()).trim() === "" ? "" : "${keyword} " + ${code}.get()))`;
121407
121517
  }
121518
+ dynamicHavingClause(code) {
121519
+ return `((value) => {
121520
+ const condition = value instanceof abap.types.Table || value instanceof abap.types.HashedTable
121521
+ ? value.array().map(row => row.get()).join(" ") : value.get();
121522
+ return condition.trim() === "" ? "" : "HAVING " + abap.expandDynamic(condition, (name) => {try { return eval(name);} catch {}});
121523
+ })(${code})`;
121524
+ }
121408
121525
  isWhereExpression(node, expression) {
121409
121526
  // check if previous token before sqlCond is "WHERE". It could also be "ON" in case of join condition
121410
121527
  let prevToken;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/transpiler-cli",
3
- "version": "2.13.99",
3
+ "version": "2.13.100",
4
4
  "description": "Transpiler - Command Line Interface",
5
5
  "funding": "https://github.com/sponsors/larshp",
6
6
  "bin": {
@@ -27,8 +27,8 @@
27
27
  "author": "abaplint",
28
28
  "license": "MIT",
29
29
  "devDependencies": {
30
- "@abaplint/core": "^2.120.68",
31
- "@abaplint/transpiler": "^2.13.99",
30
+ "@abaplint/core": "^2.120.69",
31
+ "@abaplint/transpiler": "^2.13.100",
32
32
  "@types/glob": "^9.0.0",
33
33
  "@types/node": "^26.6.2",
34
34
  "@types/progress": "^2.0.7",