@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.
- package/build/bundle.js +130 -13
- 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.
|
|
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: `
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
31
|
-
"@abaplint/transpiler": "^2.13.
|
|
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",
|