@abaplint/transpiler-cli 2.13.98 → 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 +402 -70
- package/package.json +3 -3
package/build/bundle.js
CHANGED
|
@@ -17464,7 +17464,9 @@ class ModifyLine {
|
|
|
17464
17464
|
const ocp = (0, combi_1.str)("OF CURRENT PAGE");
|
|
17465
17465
|
const intensified = (0, combi_1.seq)("INTENSIFIED", onOff);
|
|
17466
17466
|
const intensifiedOpt = (0, combi_1.seq)("INTENSIFIED", (0, combi_1.opt)(onOff));
|
|
17467
|
-
const
|
|
17467
|
+
const inputOpt = (0, combi_1.seq)("INPUT", (0, combi_1.opt)((0, combi_1.alt)(eq, onOff)));
|
|
17468
|
+
const inverseOpt = (0, combi_1.seq)("INVERSE", (0, combi_1.opt)((0, combi_1.alt)(eq, onOff)));
|
|
17469
|
+
const lineFormat = (0, combi_1.seq)("LINE FORMAT", (0, combi_1.per)(inputOpt, inverseOpt, "RESET", intensifiedOpt, expressions_1.Color));
|
|
17468
17470
|
const options = (0, combi_1.per)(index, value, format, page, lineFormat, lineValue, ocp, intensified, expressions_1.Color);
|
|
17469
17471
|
const ret = (0, combi_1.seq)("MODIFY", (0, combi_1.altPrio)("CURRENT LINE", (0, combi_1.seq)("LINE", expressions_1.Source)), (0, combi_1.opt)(options));
|
|
17470
17472
|
return (0, combi_1.verNotLang)(version_1.LanguageVersion.Cloud, ret);
|
|
@@ -27023,6 +27025,7 @@ class CurrentScope {
|
|
|
27023
27025
|
if (name === undefined) {
|
|
27024
27026
|
return undefined;
|
|
27025
27027
|
}
|
|
27028
|
+
name = name.replace(/^!/, "");
|
|
27026
27029
|
const found = (_a = this.current) === null || _a === void 0 ? void 0 : _a.findVariable(name);
|
|
27027
27030
|
if (found) {
|
|
27028
27031
|
return found;
|
|
@@ -27128,6 +27131,17 @@ class CurrentScope {
|
|
|
27128
27131
|
var _a;
|
|
27129
27132
|
return ((_a = this.localFriends.get(className.toUpperCase())) === null || _a === void 0 ? void 0 : _a.includes(friendName.toUpperCase())) === true;
|
|
27130
27133
|
}
|
|
27134
|
+
getEnclosingMethodName() {
|
|
27135
|
+
let curr = this.current;
|
|
27136
|
+
while (curr !== undefined) {
|
|
27137
|
+
const stype = curr.getIdentifier().stype;
|
|
27138
|
+
if (stype === _scope_type_1.ScopeType.Method || stype === _scope_type_1.ScopeType.MethodInstance) {
|
|
27139
|
+
return curr.getIdentifier().sname;
|
|
27140
|
+
}
|
|
27141
|
+
curr = curr.getParent();
|
|
27142
|
+
}
|
|
27143
|
+
return undefined;
|
|
27144
|
+
}
|
|
27131
27145
|
getEnclosingClassName() {
|
|
27132
27146
|
let curr = this.current;
|
|
27133
27147
|
while (curr !== undefined) {
|
|
@@ -27352,6 +27366,97 @@ class ObjectOriented {
|
|
|
27352
27366
|
}
|
|
27353
27367
|
// does the supplied class have friendship with "friendName"?
|
|
27354
27368
|
// note that interfaces of the friend, and subclasses of the friend also have friendship
|
|
27369
|
+
// returns the visibility as text if a member declared in foundDef, reached via def, cannot be accessed from enclosing
|
|
27370
|
+
memberNotVisible(visibility, def, foundDef, enclosing) {
|
|
27371
|
+
var _a, _b;
|
|
27372
|
+
if (visibility === visibility_1.Visibility.Public || foundDef === undefined) {
|
|
27373
|
+
return undefined;
|
|
27374
|
+
}
|
|
27375
|
+
else if (!(foundDef instanceof types_1.ClassDefinition)) {
|
|
27376
|
+
// interface members are always public
|
|
27377
|
+
return undefined;
|
|
27378
|
+
}
|
|
27379
|
+
const name = foundDef.getName().toUpperCase();
|
|
27380
|
+
enclosing = enclosing === null || enclosing === void 0 ? void 0 : enclosing.toUpperCase();
|
|
27381
|
+
if (enclosing === undefined || enclosing === name) {
|
|
27382
|
+
return undefined;
|
|
27383
|
+
}
|
|
27384
|
+
// friendship with the class used at the call site also gives access to inherited members
|
|
27385
|
+
const visited = [];
|
|
27386
|
+
let current = def instanceof types_1.ClassDefinition ? def : foundDef;
|
|
27387
|
+
while (current !== undefined && visited.includes(current.getName().toUpperCase()) === false) {
|
|
27388
|
+
visited.push(current.getName().toUpperCase());
|
|
27389
|
+
if (this.hasFriendship(current, enclosing)) {
|
|
27390
|
+
return undefined;
|
|
27391
|
+
}
|
|
27392
|
+
const sup = current.getSuperClass();
|
|
27393
|
+
current = sup === undefined ? undefined : this.scope.findClassDefinition(sup);
|
|
27394
|
+
}
|
|
27395
|
+
if (visibility === visibility_1.Visibility.Protected) {
|
|
27396
|
+
// subclasses can access protected members
|
|
27397
|
+
let sup = (_a = this.scope.findClassDefinition(enclosing)) === null || _a === void 0 ? void 0 : _a.getSuperClass();
|
|
27398
|
+
while (sup !== undefined) {
|
|
27399
|
+
if (sup.toUpperCase() === name) {
|
|
27400
|
+
return undefined;
|
|
27401
|
+
}
|
|
27402
|
+
sup = (_b = this.scope.findClassDefinition(sup)) === null || _b === void 0 ? void 0 : _b.getSuperClass();
|
|
27403
|
+
}
|
|
27404
|
+
return "protected";
|
|
27405
|
+
}
|
|
27406
|
+
return "private";
|
|
27407
|
+
}
|
|
27408
|
+
// the fixture methods of a test class are called by ABAP Unit only, returns the message otherwise
|
|
27409
|
+
checkSpecialTestMethodCall(method, foundDef) {
|
|
27410
|
+
if (method === undefined
|
|
27411
|
+
|| !(foundDef instanceof types_1.ClassDefinition)
|
|
27412
|
+
|| foundDef.isForTesting() === false) {
|
|
27413
|
+
return undefined;
|
|
27414
|
+
}
|
|
27415
|
+
const name = method.getName().toUpperCase();
|
|
27416
|
+
if (["SETUP", "TEARDOWN", "CLASS_SETUP", "CLASS_TEARDOWN"].includes(name) === false) {
|
|
27417
|
+
return undefined;
|
|
27418
|
+
}
|
|
27419
|
+
return `The special method "${name}" cannot be called directly`;
|
|
27420
|
+
}
|
|
27421
|
+
// SUPER-> can only call the previous implementation of the method it is used in, returns the message otherwise
|
|
27422
|
+
// both names are resolved in the super class, so an alias and the method it stands for are the same
|
|
27423
|
+
checkSuperCall(superDef, methodName) {
|
|
27424
|
+
const enclosing = this.scope.getEnclosingMethodName();
|
|
27425
|
+
if (methodName === undefined
|
|
27426
|
+
|| enclosing === undefined
|
|
27427
|
+
|| methodName.toUpperCase() === enclosing.toUpperCase()) {
|
|
27428
|
+
return undefined;
|
|
27429
|
+
}
|
|
27430
|
+
const message = "SUPER-> can only be used to call the previous implementation of the same method";
|
|
27431
|
+
// a method that is not a redefinition has no previous implementation
|
|
27432
|
+
const enclosingClass = this.scope.findClassDefinition(this.scope.getEnclosingClassName());
|
|
27433
|
+
const ownDefinition = enclosingClass === null || enclosingClass === void 0 ? void 0 : enclosingClass.getMethodDefinitions().getByName(enclosing);
|
|
27434
|
+
if (ownDefinition !== undefined && ownDefinition.isRedefinition() === false) {
|
|
27435
|
+
return message;
|
|
27436
|
+
}
|
|
27437
|
+
const called = this.searchMethodName(superDef, methodName).method;
|
|
27438
|
+
const own = this.searchMethodName(superDef, enclosing).method;
|
|
27439
|
+
if (called === undefined || own === undefined || called === own) {
|
|
27440
|
+
return undefined;
|
|
27441
|
+
}
|
|
27442
|
+
return message;
|
|
27443
|
+
}
|
|
27444
|
+
// the class declaring the attribute or constant, searched from def up through the super classes
|
|
27445
|
+
findAttributeOwner(def, found) {
|
|
27446
|
+
const visited = [];
|
|
27447
|
+
let current = def;
|
|
27448
|
+
while (current instanceof types_1.ClassDefinition && visited.includes(current.getName().toUpperCase()) === false) {
|
|
27449
|
+
visited.push(current.getName().toUpperCase());
|
|
27450
|
+
const attributes = current.getAttributes();
|
|
27451
|
+
if (attributes.getAll().includes(found)
|
|
27452
|
+
|| attributes.getConstants().includes(found)) {
|
|
27453
|
+
return current;
|
|
27454
|
+
}
|
|
27455
|
+
const sup = current.getSuperClass();
|
|
27456
|
+
current = sup === undefined ? undefined : this.findSuperDefinition(sup);
|
|
27457
|
+
}
|
|
27458
|
+
return undefined;
|
|
27459
|
+
}
|
|
27355
27460
|
hasFriendship(cd, friendName) {
|
|
27356
27461
|
var _a;
|
|
27357
27462
|
const friends = cd.getFriends().map(f => f.toUpperCase());
|
|
@@ -30328,6 +30433,8 @@ const _object_oriented_1 = __webpack_require__(/*! ../_object_oriented */ "./nod
|
|
|
30328
30433
|
const data_reference_type_1 = __webpack_require__(/*! ../../types/basic/data_reference_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/data_reference_type.js");
|
|
30329
30434
|
const _reference_1 = __webpack_require__(/*! ../_reference */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_reference.js");
|
|
30330
30435
|
const basic_1 = __webpack_require__(/*! ../../types/basic */ "./node_modules/@abaplint/core/build/src/abap/types/basic/index.js");
|
|
30436
|
+
const class_attribute_1 = __webpack_require__(/*! ../../types/class_attribute */ "./node_modules/@abaplint/core/build/src/abap/types/class_attribute.js");
|
|
30437
|
+
const class_constant_1 = __webpack_require__(/*! ../../types/class_constant */ "./node_modules/@abaplint/core/build/src/abap/types/class_constant.js");
|
|
30331
30438
|
const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
|
|
30332
30439
|
class AttributeName {
|
|
30333
30440
|
static runSyntax(context, node, input, type, error = true) {
|
|
@@ -30356,6 +30463,15 @@ class AttributeName {
|
|
|
30356
30463
|
}
|
|
30357
30464
|
return void_type_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
30358
30465
|
}
|
|
30466
|
+
if (found instanceof class_attribute_1.ClassAttribute || found instanceof class_constant_1.ClassConstant) {
|
|
30467
|
+
const owner = helper.findAttributeOwner(def, found);
|
|
30468
|
+
const notVisible = helper.memberNotVisible(found.getVisibility(), def, owner, input.scope.getEnclosingClassName());
|
|
30469
|
+
if (notVisible !== undefined) {
|
|
30470
|
+
const message = `Attribute "${name}" is ${notVisible} and cannot be accessed`;
|
|
30471
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, token, message));
|
|
30472
|
+
return void_type_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
30473
|
+
}
|
|
30474
|
+
}
|
|
30359
30475
|
if (type) {
|
|
30360
30476
|
input.scope.addReference(token, found, type, input.filename);
|
|
30361
30477
|
}
|
|
@@ -32372,6 +32488,9 @@ class FormParam {
|
|
|
32372
32488
|
else if (typeName === "P" && bfound instanceof basic_1.PackedType) {
|
|
32373
32489
|
bfound = basic_1.PGenericType.get();
|
|
32374
32490
|
}
|
|
32491
|
+
else if (typeName === "N" && bfound instanceof basic_1.NumericType) {
|
|
32492
|
+
bfound = basic_1.NGenericType.get();
|
|
32493
|
+
}
|
|
32375
32494
|
}
|
|
32376
32495
|
if (nameToken && bfound) {
|
|
32377
32496
|
return new _typed_identifier_1.TypedIdentifier(nameToken, input.filename, bfound, ["form_parameter" /* IdentifierMeta.FormParameter */]);
|
|
@@ -33294,8 +33413,6 @@ const _reference_1 = __webpack_require__(/*! ../_reference */ "./node_modules/@a
|
|
|
33294
33413
|
const component_name_1 = __webpack_require__(/*! ./component_name */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/component_name.js");
|
|
33295
33414
|
const attribute_name_1 = __webpack_require__(/*! ./attribute_name */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/attribute_name.js");
|
|
33296
33415
|
const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
|
|
33297
|
-
const visibility_1 = __webpack_require__(/*! ../../4_file_information/visibility */ "./node_modules/@abaplint/core/build/src/abap/4_file_information/visibility.js");
|
|
33298
|
-
const class_definition_1 = __webpack_require__(/*! ../../types/class_definition */ "./node_modules/@abaplint/core/build/src/abap/types/class_definition.js");
|
|
33299
33416
|
class MethodCallChain {
|
|
33300
33417
|
static runSyntax(node, input, targetType) {
|
|
33301
33418
|
var _a, _b;
|
|
@@ -33325,6 +33442,14 @@ class MethodCallChain {
|
|
|
33325
33442
|
const methodToken = (_a = current.findDirectExpression(Expressions.MethodName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
|
|
33326
33443
|
const methodName = methodToken === null || methodToken === void 0 ? void 0 : methodToken.getStr();
|
|
33327
33444
|
const def = input.scope.findObjectDefinition(className);
|
|
33445
|
+
const isSuper = current === children[2]
|
|
33446
|
+
&& first.get() instanceof Expressions.FieldChain
|
|
33447
|
+
&& first.concatTokens().toUpperCase() === "SUPER";
|
|
33448
|
+
const superMessage = isSuper ? helper.checkSuperCall(def, methodName) : undefined;
|
|
33449
|
+
if (superMessage !== undefined) {
|
|
33450
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, methodToken, superMessage));
|
|
33451
|
+
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
33452
|
+
}
|
|
33328
33453
|
// eslint-disable-next-line prefer-const
|
|
33329
33454
|
let { method, def: foundDef } = helper.searchMethodName(def, methodName);
|
|
33330
33455
|
if (method === undefined && current === first) {
|
|
@@ -33344,12 +33469,19 @@ class MethodCallChain {
|
|
|
33344
33469
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, methodToken, message));
|
|
33345
33470
|
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
33346
33471
|
}
|
|
33347
|
-
const notVisible = method
|
|
33472
|
+
const notVisible = method
|
|
33473
|
+
? helper.memberNotVisible(method.getVisibility(), def, foundDef, input.scope.getEnclosingClassName())
|
|
33474
|
+
: undefined;
|
|
33348
33475
|
if (notVisible !== undefined) {
|
|
33349
33476
|
const message = `Method "${methodName}" is ${notVisible} and cannot be accessed`;
|
|
33350
33477
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, methodToken, message));
|
|
33351
33478
|
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
33352
33479
|
}
|
|
33480
|
+
const specialMessage = isSuper ? undefined : helper.checkSpecialTestMethodCall(method, foundDef);
|
|
33481
|
+
if (specialMessage !== undefined) {
|
|
33482
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, methodToken, specialMessage));
|
|
33483
|
+
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
33484
|
+
}
|
|
33353
33485
|
const voidedName = context instanceof basic_1.VoidType ? context.getVoided() : undefined;
|
|
33354
33486
|
const extra = helper.methodReferenceExtras(foundDef, className || voidedName);
|
|
33355
33487
|
input.scope.addReference(methodToken, method, _reference_1.ReferenceType.MethodReference, input.filename, extra);
|
|
@@ -33392,47 +33524,6 @@ class MethodCallChain {
|
|
|
33392
33524
|
return context;
|
|
33393
33525
|
}
|
|
33394
33526
|
//////////////////////////////////////
|
|
33395
|
-
// returns the visibility as text if the method cannot be accessed from the current scope
|
|
33396
|
-
static checkVisibility(method, def, foundDef, input) {
|
|
33397
|
-
var _a, _b, _c;
|
|
33398
|
-
const visibility = method.getVisibility();
|
|
33399
|
-
if (visibility === visibility_1.Visibility.Public || foundDef === undefined) {
|
|
33400
|
-
return undefined;
|
|
33401
|
-
}
|
|
33402
|
-
else if (!(foundDef instanceof class_definition_1.ClassDefinition)) {
|
|
33403
|
-
// interface members are always public
|
|
33404
|
-
return undefined;
|
|
33405
|
-
}
|
|
33406
|
-
const name = foundDef.getName().toUpperCase();
|
|
33407
|
-
const enclosing = (_a = input.scope.getEnclosingClassName()) === null || _a === void 0 ? void 0 : _a.toUpperCase();
|
|
33408
|
-
if (enclosing === undefined || enclosing === name) {
|
|
33409
|
-
return undefined;
|
|
33410
|
-
}
|
|
33411
|
-
// friendship with the class used at the call site also gives access to inherited members
|
|
33412
|
-
const helper = new _object_oriented_1.ObjectOriented(input.scope);
|
|
33413
|
-
const visited = [];
|
|
33414
|
-
let current = def instanceof class_definition_1.ClassDefinition ? def : foundDef;
|
|
33415
|
-
while (current !== undefined && visited.includes(current.getName().toUpperCase()) === false) {
|
|
33416
|
-
visited.push(current.getName().toUpperCase());
|
|
33417
|
-
if (helper.hasFriendship(current, enclosing)) {
|
|
33418
|
-
return undefined;
|
|
33419
|
-
}
|
|
33420
|
-
const sup = current.getSuperClass();
|
|
33421
|
-
current = sup === undefined ? undefined : input.scope.findClassDefinition(sup);
|
|
33422
|
-
}
|
|
33423
|
-
if (visibility === visibility_1.Visibility.Protected) {
|
|
33424
|
-
// subclasses can access protected members
|
|
33425
|
-
let sup = (_b = input.scope.findClassDefinition(enclosing)) === null || _b === void 0 ? void 0 : _b.getSuperClass();
|
|
33426
|
-
while (sup !== undefined) {
|
|
33427
|
-
if (sup.toUpperCase() === name) {
|
|
33428
|
-
return undefined;
|
|
33429
|
-
}
|
|
33430
|
-
sup = (_c = input.scope.findClassDefinition(sup)) === null || _c === void 0 ? void 0 : _c.getSuperClass();
|
|
33431
|
-
}
|
|
33432
|
-
return "protected";
|
|
33433
|
-
}
|
|
33434
|
-
return "private";
|
|
33435
|
-
}
|
|
33436
33527
|
static findTop(first, input, targetType) {
|
|
33437
33528
|
var _a;
|
|
33438
33529
|
if (first.get() instanceof Expressions.ClassName) {
|
|
@@ -33786,6 +33877,9 @@ class MethodParam {
|
|
|
33786
33877
|
else if (concat === "TYPE P" || concat.startsWith("TYPE P ")) {
|
|
33787
33878
|
return new _typed_identifier_1.TypedIdentifier(name.getFirstToken(), input.filename, basic_1.PGenericType.get(), meta);
|
|
33788
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
|
+
}
|
|
33789
33883
|
const found = new basic_types_1.BasicTypes(input).parseType(type);
|
|
33790
33884
|
if (found) {
|
|
33791
33885
|
return new _typed_identifier_1.TypedIdentifier(name.getFirstToken(), input.filename, found, meta);
|
|
@@ -34254,6 +34348,14 @@ class MethodSource {
|
|
|
34254
34348
|
const methodToken = current.getFirstToken();
|
|
34255
34349
|
const methodName = methodToken === null || methodToken === void 0 ? void 0 : methodToken.getStr();
|
|
34256
34350
|
const def = input.scope.findObjectDefinition(className);
|
|
34351
|
+
const isSuper = implicitMe === false
|
|
34352
|
+
&& first.get() instanceof Expressions.SourceField
|
|
34353
|
+
&& first.concatTokens().toUpperCase() === "SUPER";
|
|
34354
|
+
const superMessage = isSuper ? helper.checkSuperCall(def, methodName) : undefined;
|
|
34355
|
+
if (superMessage !== undefined) {
|
|
34356
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, methodToken, superMessage));
|
|
34357
|
+
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
34358
|
+
}
|
|
34257
34359
|
// eslint-disable-next-line prefer-const
|
|
34258
34360
|
let { method, def: foundDef } = helper.searchMethodName(def, methodName);
|
|
34259
34361
|
if (implicitMe && current === first && (method === null || method === void 0 ? void 0 : method.isStatic()) === false && input.scope.isInStaticMethod() === true) {
|
|
@@ -34270,6 +34372,11 @@ class MethodSource {
|
|
|
34270
34372
|
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
34271
34373
|
}
|
|
34272
34374
|
else if (method) {
|
|
34375
|
+
const specialMessage = isSuper ? undefined : helper.checkSpecialTestMethodCall(method, foundDef);
|
|
34376
|
+
if (specialMessage !== undefined) {
|
|
34377
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, methodToken, specialMessage));
|
|
34378
|
+
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
34379
|
+
}
|
|
34273
34380
|
const extra = helper.methodReferenceExtras(foundDef, className);
|
|
34274
34381
|
input.scope.addReference(methodToken, method, _reference_1.ReferenceType.MethodReference, input.filename, extra);
|
|
34275
34382
|
context = method;
|
|
@@ -35368,6 +35475,7 @@ const corresponding_body_1 = __webpack_require__(/*! ./corresponding_body */ "./
|
|
|
35368
35475
|
const _builtin_1 = __webpack_require__(/*! ../_builtin */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_builtin.js");
|
|
35369
35476
|
const attribute_chain_1 = __webpack_require__(/*! ./attribute_chain */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/attribute_chain.js");
|
|
35370
35477
|
const dereference_1 = __webpack_require__(/*! ./dereference */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/dereference.js");
|
|
35478
|
+
const cast_1 = __webpack_require__(/*! ./cast */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/cast.js");
|
|
35371
35479
|
const _typed_identifier_1 = __webpack_require__(/*! ../../types/_typed_identifier */ "./node_modules/@abaplint/core/build/src/abap/types/_typed_identifier.js");
|
|
35372
35480
|
const _type_utils_1 = __webpack_require__(/*! ../_type_utils */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_type_utils.js");
|
|
35373
35481
|
const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
|
|
@@ -35591,6 +35699,10 @@ class Source {
|
|
|
35591
35699
|
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
35592
35700
|
}
|
|
35593
35701
|
}
|
|
35702
|
+
else if (get instanceof Expressions.Cast) {
|
|
35703
|
+
const found = cast_1.Cast.runSyntax(first, input, targetType);
|
|
35704
|
+
context = arithmetic === true ? this.infer(context, found, true) : found;
|
|
35705
|
+
}
|
|
35594
35706
|
else if (get instanceof Expressions.FieldChain) {
|
|
35595
35707
|
const found = field_chain_1.FieldChain.runSyntax(first, input, type, allowGenericDeference);
|
|
35596
35708
|
context = arithmetic === true ? this.infer(context, found, true) : found;
|
|
@@ -35607,6 +35719,11 @@ class Source {
|
|
|
35607
35719
|
context = this.infer(context, found, arithmetic);
|
|
35608
35720
|
}
|
|
35609
35721
|
else if (get instanceof Expressions.Dereference) {
|
|
35722
|
+
if (this.isNewObjectDereference(node, first)) {
|
|
35723
|
+
const message = "NEW cannot be dereferenced directly";
|
|
35724
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, first.getFirstToken(), message));
|
|
35725
|
+
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
35726
|
+
}
|
|
35610
35727
|
context = dereference_1.Dereference.runSyntax(first, context, input);
|
|
35611
35728
|
}
|
|
35612
35729
|
else if (get instanceof Expressions.ComponentChain) {
|
|
@@ -35794,6 +35911,16 @@ class Source {
|
|
|
35794
35911
|
}
|
|
35795
35912
|
return targetType;
|
|
35796
35913
|
}
|
|
35914
|
+
// "NEW ty( )->*" is a syntax error, also in releases where a method call can be dereferenced
|
|
35915
|
+
static isNewObjectDereference(node, deref) {
|
|
35916
|
+
var _a;
|
|
35917
|
+
const children = node.getChildren();
|
|
35918
|
+
const before = children[children.indexOf(deref) - 1];
|
|
35919
|
+
return before instanceof nodes_1.ExpressionNode
|
|
35920
|
+
&& before.get() instanceof Expressions.MethodCallChain
|
|
35921
|
+
&& before.getChildren().length === 1
|
|
35922
|
+
&& ((_a = before.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.NewObject;
|
|
35923
|
+
}
|
|
35797
35924
|
}
|
|
35798
35925
|
exports.Source = Source;
|
|
35799
35926
|
//# sourceMappingURL=source.js.map
|
|
@@ -36761,6 +36888,7 @@ const expressions_1 = __webpack_require__(/*! ../../2_statements/expressions */
|
|
|
36761
36888
|
const field_length_1 = __webpack_require__(/*! ./field_length */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/field_length.js");
|
|
36762
36889
|
const cast_1 = __webpack_require__(/*! ./cast */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/cast.js");
|
|
36763
36890
|
const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
|
|
36891
|
+
const version_1 = __webpack_require__(/*! ../../../version */ "./node_modules/@abaplint/core/build/src/version.js");
|
|
36764
36892
|
class Target {
|
|
36765
36893
|
static runSyntax(node, input) {
|
|
36766
36894
|
const concat = node.concatTokens();
|
|
@@ -36826,6 +36954,12 @@ class Target {
|
|
|
36826
36954
|
if (!(context instanceof basic_1.VoidType)) {
|
|
36827
36955
|
context = context.getType();
|
|
36828
36956
|
}
|
|
36957
|
+
if ((context === null || context === void 0 ? void 0 : context.isGeneric()) === true
|
|
36958
|
+
&& !(0, version_1.releaseAtLeast)(input.scope.getRelease(), version_1.Release.v756)
|
|
36959
|
+
&& input.scope.getLanguageVersion() !== version_1.LanguageVersion.Cloud
|
|
36960
|
+
&& !input.scope.getOpenABAP()) {
|
|
36961
|
+
throw new Error("A generic reference cannot be dereferenced");
|
|
36962
|
+
}
|
|
36829
36963
|
}
|
|
36830
36964
|
else if (current.get() instanceof Expressions.ComponentName) {
|
|
36831
36965
|
context = component_name_1.ComponentName.runSyntax(context, current, input);
|
|
@@ -40448,9 +40582,9 @@ class CreateObject {
|
|
|
40448
40582
|
if (name === undefined) {
|
|
40449
40583
|
continue;
|
|
40450
40584
|
}
|
|
40451
|
-
const source = p.findDirectExpression(Expressions.Source);
|
|
40452
|
-
const sourceType = source_1.Source.runSyntax(source, input);
|
|
40453
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());
|
|
40454
40588
|
if (found === undefined) {
|
|
40455
40589
|
const message = `constructor parameter "${name}" does not exist`;
|
|
40456
40590
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
@@ -51907,6 +52041,7 @@ __exportStar(__webpack_require__(/*! ./generic_object_reference_type */ "./node_
|
|
|
51907
52041
|
__exportStar(__webpack_require__(/*! ./hex_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/hex_type.js"), exports);
|
|
51908
52042
|
__exportStar(__webpack_require__(/*! ./integer_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/integer_type.js"), exports);
|
|
51909
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);
|
|
51910
52045
|
__exportStar(__webpack_require__(/*! ./numeric_generic_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/numeric_generic_type.js"), exports);
|
|
51911
52046
|
__exportStar(__webpack_require__(/*! ./numeric_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/numeric_type.js"), exports);
|
|
51912
52047
|
__exportStar(__webpack_require__(/*! ./object_reference_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/object_reference_type.js"), exports);
|
|
@@ -52015,6 +52150,39 @@ IntegerType.singletons = new Map();
|
|
|
52015
52150
|
|
|
52016
52151
|
/***/ },
|
|
52017
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
|
+
|
|
52018
52186
|
/***/ "./node_modules/@abaplint/core/build/src/abap/types/basic/numeric_generic_type.js"
|
|
52019
52187
|
/*!****************************************************************************************!*\
|
|
52020
52188
|
!*** ./node_modules/@abaplint/core/build/src/abap/types/basic/numeric_generic_type.js ***!
|
|
@@ -70615,6 +70783,7 @@ class Indent {
|
|
|
70615
70783
|
|| type instanceof Statements.ProcessBeforeOutput
|
|
70616
70784
|
|| type instanceof Statements.ProcessOnValueRequest
|
|
70617
70785
|
|| type instanceof Statements.TopOfPage
|
|
70786
|
+
|| type instanceof Statements.EndOfPage
|
|
70618
70787
|
|| type instanceof Statements.Get
|
|
70619
70788
|
|| type instanceof Statements.EndOfSelection
|
|
70620
70789
|
|| type instanceof Statements.LoadOfProgram) {
|
|
@@ -70710,6 +70879,7 @@ class Indent {
|
|
|
70710
70879
|
|| type instanceof Statements.Initialization
|
|
70711
70880
|
|| type instanceof Statements.AtUserCommand
|
|
70712
70881
|
|| type instanceof Statements.TopOfPage
|
|
70882
|
+
|| type instanceof Statements.EndOfPage
|
|
70713
70883
|
|| type instanceof Statements.EndOfSelection
|
|
70714
70884
|
|| type instanceof Statements.Public
|
|
70715
70885
|
|| type instanceof Statements.Protected
|
|
@@ -70907,7 +71077,7 @@ class Registry {
|
|
|
70907
71077
|
}
|
|
70908
71078
|
static abaplintVersion() {
|
|
70909
71079
|
// magic, see build script "version.js"
|
|
70910
|
-
return "2.120.
|
|
71080
|
+
return "2.120.69";
|
|
70911
71081
|
}
|
|
70912
71082
|
getDDICReferences() {
|
|
70913
71083
|
return this.ddicReferences;
|
|
@@ -80406,8 +80576,17 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
80406
80576
|
const extra = (valueBody === null || valueBody === void 0 ? void 0 : valueBody.findDirectExpression(Expressions.For)) ? " " : "";
|
|
80407
80577
|
data = indentation + extra + `DATA ${structureName} LIKE LINE OF ${uniqueName}.\n`;
|
|
80408
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 = [];
|
|
80409
80583
|
for (const a of (valueBody === null || valueBody === void 0 ? void 0 : valueBody.getChildren()) || []) {
|
|
80410
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
|
+
}
|
|
80411
80590
|
if (added === false) {
|
|
80412
80591
|
body += data;
|
|
80413
80592
|
added = true;
|
|
@@ -80431,6 +80610,16 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
80431
80610
|
}
|
|
80432
80611
|
if (a instanceof nodes_1.ExpressionNode && a.get() instanceof Expressions.ValueBodyLine) {
|
|
80433
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
|
+
}
|
|
80434
80623
|
for (const b of (a === null || a === void 0 ? void 0 : a.getChildren()) || []) {
|
|
80435
80624
|
if (b.get() instanceof Expressions.FieldAssignment) {
|
|
80436
80625
|
if (added === false) {
|
|
@@ -80509,6 +80698,39 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
80509
80698
|
}
|
|
80510
80699
|
return undefined;
|
|
80511
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
|
+
}
|
|
80512
80734
|
outlineLet(node, indentation, highSyntax, lowFile) {
|
|
80513
80735
|
var _a;
|
|
80514
80736
|
let ret = "";
|
|
@@ -95784,7 +96006,9 @@ class RFCErrorHandling extends _abap_rule_1.ABAPRule {
|
|
|
95784
96006
|
title: "RFC error handling",
|
|
95785
96007
|
tags: [_irule_1.RuleTag.SingleFile],
|
|
95786
96008
|
shortDescription: `Checks that exceptions 'system_failure' and 'communication_failure' are handled in RFC calls`,
|
|
95787
|
-
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`,
|
|
95788
96012
|
badExample: `CALL FUNCTION 'ZRFC'
|
|
95789
96013
|
DESTINATION lv_rfc.`,
|
|
95790
96014
|
goodExample: `CALL FUNCTION 'ZRFC'
|
|
@@ -95792,12 +96016,12 @@ class RFCErrorHandling extends _abap_rule_1.ABAPRule {
|
|
|
95792
96016
|
EXCEPTIONS
|
|
95793
96017
|
system_failure = 1 MESSAGE msg
|
|
95794
96018
|
communication_failure = 2 MESSAGE msg
|
|
95795
|
-
|
|
95796
|
-
OTHERS = 4.`,
|
|
96019
|
+
OTHERS = 3.`,
|
|
95797
96020
|
};
|
|
95798
96021
|
}
|
|
95799
|
-
getMessage() {
|
|
95800
|
-
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" : "");
|
|
95801
96025
|
}
|
|
95802
96026
|
getConfig() {
|
|
95803
96027
|
return this.conf;
|
|
@@ -95812,12 +96036,15 @@ class RFCErrorHandling extends _abap_rule_1.ABAPRule {
|
|
|
95812
96036
|
if (!(stat.get() instanceof Statements.CallFunction)) {
|
|
95813
96037
|
continue;
|
|
95814
96038
|
}
|
|
95815
|
-
|
|
96039
|
+
const destination = stat.findFirstExpression(Expressions.Destination);
|
|
96040
|
+
if (destination === undefined) {
|
|
95816
96041
|
continue;
|
|
95817
96042
|
}
|
|
96043
|
+
const requireResourceFailure = stat.findDirectTokenByText("STARTING") !== undefined
|
|
96044
|
+
&& destination.findDirectTokenByText("GROUP") !== undefined;
|
|
95818
96045
|
const list = stat.findFirstExpression(Expressions.ParameterListExceptions);
|
|
95819
96046
|
if (list === undefined) {
|
|
95820
|
-
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);
|
|
95821
96048
|
output.push(issue);
|
|
95822
96049
|
continue;
|
|
95823
96050
|
}
|
|
@@ -95828,8 +96055,8 @@ class RFCErrorHandling extends _abap_rule_1.ABAPRule {
|
|
|
95828
96055
|
}
|
|
95829
96056
|
if (names.indexOf("SYSTEM_FAILURE") < 0
|
|
95830
96057
|
|| names.indexOf("COMMUNICATION_FAILURE") < 0
|
|
95831
|
-
|| names.indexOf("RESOURCE_FAILURE") < 0) {
|
|
95832
|
-
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);
|
|
95833
96060
|
output.push(issue);
|
|
95834
96061
|
continue;
|
|
95835
96062
|
}
|
|
@@ -121098,8 +121325,18 @@ class SelectTranspiler {
|
|
|
121098
121325
|
const having = node.findDirectExpression(abaplint.Expressions.Select)
|
|
121099
121326
|
?.findDirectExpression(abaplint.Expressions.SQLHaving);
|
|
121100
121327
|
const havingCond = having?.findFirstExpression(abaplint.Expressions.SQLCond);
|
|
121328
|
+
let dynamicHaving;
|
|
121101
121329
|
if (havingCond) {
|
|
121102
|
-
|
|
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
|
+
}
|
|
121103
121340
|
}
|
|
121104
121341
|
const upTo = node.findFirstExpression(abaplint.Expressions.SQLUpTo);
|
|
121105
121342
|
if (upTo) {
|
|
@@ -121119,6 +121356,9 @@ class SelectTranspiler {
|
|
|
121119
121356
|
const groupByDynamics = new Set(groupBy?.findAllExpressionsRecursive(abaplint.Expressions.Dynamic) || []);
|
|
121120
121357
|
const orderByDynamics = new Set(orderBy?.findAllExpressionsRecursive(abaplint.Expressions.Dynamic) || []);
|
|
121121
121358
|
for (const d of node.findAllExpressionsRecursive(abaplint.Expressions.Dynamic)) {
|
|
121359
|
+
if (d === dynamicHaving) {
|
|
121360
|
+
continue;
|
|
121361
|
+
}
|
|
121122
121362
|
const chain = d.findFirstExpression(abaplint.Expressions.FieldChain);
|
|
121123
121363
|
if (chain) {
|
|
121124
121364
|
const search = d.concatTokens();
|
|
@@ -121275,6 +121515,13 @@ abap.builtin.sy.get().dbcnt.set(${target}.getArrayLength());
|
|
|
121275
121515
|
+ ` ? (${code}.array().length === 0 ? "" : "${keyword} " + ${code}.array().map(row => row.get()).join(", "))`
|
|
121276
121516
|
+ ` : (("" + ${code}.get()).trim() === "" ? "" : "${keyword} " + ${code}.get()))`;
|
|
121277
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
|
+
}
|
|
121278
121525
|
isWhereExpression(node, expression) {
|
|
121279
121526
|
// check if previous token before sqlCond is "WHERE". It could also be "ON" in case of join condition
|
|
121280
121527
|
let prevToken;
|
|
@@ -125598,6 +125845,10 @@ class Traversal {
|
|
|
125598
125845
|
doOrWhileIndexBackups = new Map();
|
|
125599
125846
|
statementsInsideLoop = new WeakSet();
|
|
125600
125847
|
enclosingDoOrWhile = new WeakMap();
|
|
125848
|
+
/** DATA, CONSTANTS and FIELD-SYMBOLS nested in blocks, already declared in front of the block */
|
|
125849
|
+
declaredEarly = new WeakSet();
|
|
125850
|
+
emittingEarly = false;
|
|
125851
|
+
blockDepth = 0;
|
|
125601
125852
|
reg;
|
|
125602
125853
|
options;
|
|
125603
125854
|
constructor(spaghetti, file, obj, reg, options) {
|
|
@@ -126436,17 +126687,15 @@ this.INTERNAL_ID = abap.internalIdCounter++;\n`;
|
|
|
126436
126687
|
}
|
|
126437
126688
|
else if (c.get() instanceof abaplint.Expressions.AttributeName
|
|
126438
126689
|
&& context instanceof abaplint.BasicTypes.ObjectReferenceType) {
|
|
126439
|
-
const
|
|
126440
|
-
if (
|
|
126441
|
-
const
|
|
126442
|
-
|
|
126443
|
-
|
|
126444
|
-
|
|
126445
|
-
|
|
126446
|
-
|
|
126447
|
-
|
|
126448
|
-
context = id.getAttributes().findByName(concat)?.getType();
|
|
126449
|
-
}
|
|
126690
|
+
const concat = c.concatTokens();
|
|
126691
|
+
if (concat.includes("~")) {
|
|
126692
|
+
const [iname, aname] = concat.split("~");
|
|
126693
|
+
const intf = this.findInterfaceDefinition(iname, scope);
|
|
126694
|
+
context = intf?.getAttributes().findByName(aname)?.getType();
|
|
126695
|
+
}
|
|
126696
|
+
else {
|
|
126697
|
+
// Global references can carry an identifier rather than a class definition.
|
|
126698
|
+
context = this.narrowContextAttribute(context, concat, scope);
|
|
126450
126699
|
}
|
|
126451
126700
|
}
|
|
126452
126701
|
else if (c.get() instanceof abaplint.Expressions.AttributeName
|
|
@@ -126460,7 +126709,7 @@ this.INTERNAL_ID = abap.internalIdCounter++;\n`;
|
|
|
126460
126709
|
return context;
|
|
126461
126710
|
}
|
|
126462
126711
|
isInsideLoop(node) {
|
|
126463
|
-
return this.statementsInsideLoop.has(node);
|
|
126712
|
+
return this.statementsInsideLoop.has(node) && !this.declaredEarly.has(node);
|
|
126464
126713
|
}
|
|
126465
126714
|
isInsideDoOrWhile(node) {
|
|
126466
126715
|
return this.findCurrentDoOrWhileIndexBackup(node) !== undefined;
|
|
@@ -126555,7 +126804,87 @@ this.INTERNAL_ID = abap.internalIdCounter++;\n`;
|
|
|
126555
126804
|
return this.obj.getType() + "-" + this.obj.getName() + "-";
|
|
126556
126805
|
}
|
|
126557
126806
|
////////////////////////////
|
|
126807
|
+
/** In ABAP, DATA, CONSTANTS and FIELD-SYMBOLS are visible in the whole method/form/program, but a
|
|
126808
|
+
* javascript "let" inside the block of an IF, LOOP, TRY etc. is not. So before each block on
|
|
126809
|
+
* method/form/program level the declarations nested in it are output, in source order, and
|
|
126810
|
+
* skipped inside the block. They then exist after the block even if the branch did not run,
|
|
126811
|
+
* and are initialized once, also when the block is a loop */
|
|
126812
|
+
traverseProcedureLevel(node) {
|
|
126813
|
+
const ret = new chunk_1.Chunk();
|
|
126814
|
+
for (const c of node.getChildren()) {
|
|
126815
|
+
if (c instanceof abaplint.Nodes.StructureNode && Traversal.isDeclaration(c) === false) {
|
|
126816
|
+
ret.appendChunk(this.declareNestedEarly(c));
|
|
126817
|
+
this.blockDepth++;
|
|
126818
|
+
try {
|
|
126819
|
+
ret.appendChunk(this.traverseStructure(c));
|
|
126820
|
+
}
|
|
126821
|
+
finally {
|
|
126822
|
+
this.blockDepth--;
|
|
126823
|
+
}
|
|
126824
|
+
}
|
|
126825
|
+
else {
|
|
126826
|
+
ret.appendChunk(this.traverse(c));
|
|
126827
|
+
}
|
|
126828
|
+
}
|
|
126829
|
+
return ret;
|
|
126830
|
+
}
|
|
126831
|
+
declareNestedEarly(block) {
|
|
126832
|
+
const found = [];
|
|
126833
|
+
Traversal.findNestedDeclarations(block, found);
|
|
126834
|
+
for (const node of found) {
|
|
126835
|
+
this.declaredEarly.add(node);
|
|
126836
|
+
if (node instanceof abaplint.Nodes.StructureNode) {
|
|
126837
|
+
for (const statement of node.findAllStatementNodes()) {
|
|
126838
|
+
this.declaredEarly.add(statement);
|
|
126839
|
+
}
|
|
126840
|
+
}
|
|
126841
|
+
}
|
|
126842
|
+
const ret = new chunk_1.Chunk();
|
|
126843
|
+
this.emittingEarly = true;
|
|
126844
|
+
try {
|
|
126845
|
+
for (const node of found) {
|
|
126846
|
+
ret.appendChunk(this.traverse(node));
|
|
126847
|
+
}
|
|
126848
|
+
}
|
|
126849
|
+
finally {
|
|
126850
|
+
this.emittingEarly = false;
|
|
126851
|
+
}
|
|
126852
|
+
return ret;
|
|
126853
|
+
}
|
|
126854
|
+
static isDeclaration(node) {
|
|
126855
|
+
const get = node.get();
|
|
126856
|
+
return get instanceof abaplint.Structures.Data
|
|
126857
|
+
|| get instanceof abaplint.Structures.Constants
|
|
126858
|
+
|| get instanceof abaplint.Structures.Types;
|
|
126859
|
+
}
|
|
126860
|
+
static findNestedDeclarations(node, found) {
|
|
126861
|
+
for (const c of node.getChildren()) {
|
|
126862
|
+
if (c instanceof abaplint.Nodes.StatementNode) {
|
|
126863
|
+
const get = c.get();
|
|
126864
|
+
if (get instanceof abaplint.Statements.Data
|
|
126865
|
+
|| get instanceof abaplint.Statements.Constant
|
|
126866
|
+
|| get instanceof abaplint.Statements.FieldSymbol) {
|
|
126867
|
+
found.push(c);
|
|
126868
|
+
}
|
|
126869
|
+
}
|
|
126870
|
+
else if (c instanceof abaplint.Nodes.StructureNode) {
|
|
126871
|
+
const get = c.get();
|
|
126872
|
+
if (get instanceof abaplint.Structures.Data || get instanceof abaplint.Structures.Constants) {
|
|
126873
|
+
found.push(c);
|
|
126874
|
+
}
|
|
126875
|
+
else {
|
|
126876
|
+
Traversal.findNestedDeclarations(c, found);
|
|
126877
|
+
}
|
|
126878
|
+
}
|
|
126879
|
+
}
|
|
126880
|
+
}
|
|
126558
126881
|
traverseStructure(node) {
|
|
126882
|
+
if (this.declaredEarly.has(node) && this.emittingEarly === false) {
|
|
126883
|
+
return new chunk_1.Chunk();
|
|
126884
|
+
}
|
|
126885
|
+
else if (this.blockDepth === 0 && node.get() instanceof abaplint.Structures.Normal) {
|
|
126886
|
+
return this.traverseProcedureLevel(node);
|
|
126887
|
+
}
|
|
126559
126888
|
const list = StructureTranspilers;
|
|
126560
126889
|
const ret = new chunk_1.Chunk();
|
|
126561
126890
|
const search = node.get().constructor.name + "Transpiler";
|
|
@@ -126578,6 +126907,9 @@ this.INTERNAL_ID = abap.internalIdCounter++;\n`;
|
|
|
126578
126907
|
return ret;
|
|
126579
126908
|
}
|
|
126580
126909
|
traverseStatement(node) {
|
|
126910
|
+
if (this.declaredEarly.has(node) && this.emittingEarly === false) {
|
|
126911
|
+
return new chunk_1.Chunk();
|
|
126912
|
+
}
|
|
126581
126913
|
const list = StatementTranspilers;
|
|
126582
126914
|
const search = node.get().constructor.name + "Transpiler";
|
|
126583
126915
|
if (list[search]) {
|
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",
|