@abaplint/transpiler-cli 2.13.97 → 2.13.99

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 +288 -63
  2. package/package.json +3 -3
package/build/bundle.js CHANGED
@@ -8119,7 +8119,9 @@ class Source extends combi_1.Expression {
8119
8119
  const comp = (0, combi_1.seq)((0, combi_1.tok)(tokens_1.Dash), _1.ComponentChain);
8120
8120
  const attr = (0, combi_1.seq)(_1.Arrow, attribute_chain_1.AttributeChain);
8121
8121
  const deref = (0, combi_1.optPrio)((0, combi_1.ver)(version_1.Release.v756, dereference_1.Dereference));
8122
- const dynChain = (0, combi_1.star)((0, combi_1.altPrio)((0, _dynamic_access_1.dynAttr)(), (0, _dynamic_access_1.dynComp)(), dereference_1.Dereference));
8122
+ // below v756 "->*" directly after a functional method call is a syntax error, CAST can be dereferenced
8123
+ const dynChain = (0, combi_1.star)((0, combi_1.seq)((0, combi_1.altPrio)((0, _dynamic_access_1.dynAttr)(), (0, _dynamic_access_1.dynComp)()), (0, combi_1.optPrio)(dereference_1.Dereference)));
8124
+ const castDeref = (0, combi_1.seq)(_1.Cast, dereference_1.Dereference);
8123
8125
  const method = (0, combi_1.seq)(_1.MethodCallChain, (0, combi_1.optPrio)((0, combi_1.altPrio)(attr, comp)), deref, dynChain);
8124
8126
  const rparen = (0, combi_1.tok)(tokens_1.WParenRightW);
8125
8127
  const rparenNoSpace = (0, combi_1.altPrio)((0, combi_1.tok)(tokens_1.ParenRightW), (0, combi_1.tok)(tokens_1.WParenRightW));
@@ -8129,7 +8131,7 @@ class Source extends combi_1.Expression {
8129
8131
  const after = (0, combi_1.seq)((0, combi_1.altPrio)("&", "&&", _1.ArithOperator), Source);
8130
8132
  const bool = (0, combi_1.seq)((0, combi_1.altPrio)((0, combi_1.ver)(version_1.Release.v702, (0, combi_1.regex)(/^BOOLC$/i), { also: combi_1.AlsoIn.OpenABAP }), (0, combi_1.ver)(version_1.Release.v740sp08, (0, combi_1.regex)(/^XSDBOOL$/i), { also: combi_1.AlsoIn.OpenABAP })), (0, combi_1.tok)(tokens_1.ParenLeftW), _1.Cond, ")");
8131
8133
  const prefix = (0, combi_1.altPrio)((0, combi_1.tok)(tokens_1.WPlus), "BIT-NOT");
8132
- const old = (0, combi_1.seq)((0, combi_1.optPrio)(prefix), (0, combi_1.altPrio)(_1.Constant, _1.StringTemplate, text_element_1.TextElement, bool, method, (0, combi_1.seq)(_1.FieldChain, deref), paren), (0, combi_1.optPrio)(after));
8134
+ const old = (0, combi_1.seq)((0, combi_1.optPrio)(prefix), (0, combi_1.altPrio)(_1.Constant, _1.StringTemplate, text_element_1.TextElement, bool, castDeref, method, (0, combi_1.seq)(_1.FieldChain, deref), paren), (0, combi_1.optPrio)(after));
8133
8135
  const corr = (0, combi_1.ver)(version_1.Release.v740sp05, (0, combi_1.seq)("CORRESPONDING", _1.TypeNameOrInfer, (0, combi_1.tok)(tokens_1.ParenLeftW), _1.CorrespondingBody, rparen, (0, combi_1.optPrio)(after)), { also: combi_1.AlsoIn.OpenABAP });
8134
8136
  const conv = (0, combi_1.ver)(version_1.Release.v740sp02, (0, combi_1.seq)("CONV", _1.TypeNameOrInfer, lparenNoSpace, _1.ConvBody, rparenNoSpace, (0, combi_1.optPrio)(after)), { also: combi_1.AlsoIn.OpenABAP });
8135
8137
  const swit = (0, combi_1.ver)(version_1.Release.v740sp02, (0, combi_1.seq)("SWITCH", _1.TypeNameOrInfer, (0, combi_1.tok)(tokens_1.ParenLeftW), _1.SwitchBody, rparenNoSpace, (0, combi_1.optPrio)(after)), { also: combi_1.AlsoIn.OpenABAP });
@@ -17462,7 +17464,9 @@ class ModifyLine {
17462
17464
  const ocp = (0, combi_1.str)("OF CURRENT PAGE");
17463
17465
  const intensified = (0, combi_1.seq)("INTENSIFIED", onOff);
17464
17466
  const intensifiedOpt = (0, combi_1.seq)("INTENSIFIED", (0, combi_1.opt)(onOff));
17465
- const lineFormat = (0, combi_1.seq)("LINE FORMAT", (0, combi_1.per)("INPUT OFF", "INVERSE", "RESET", intensifiedOpt, expressions_1.Color));
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));
17466
17470
  const options = (0, combi_1.per)(index, value, format, page, lineFormat, lineValue, ocp, intensified, expressions_1.Color);
17467
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));
17468
17472
  return (0, combi_1.verNotLang)(version_1.LanguageVersion.Cloud, ret);
@@ -27021,6 +27025,7 @@ class CurrentScope {
27021
27025
  if (name === undefined) {
27022
27026
  return undefined;
27023
27027
  }
27028
+ name = name.replace(/^!/, "");
27024
27029
  const found = (_a = this.current) === null || _a === void 0 ? void 0 : _a.findVariable(name);
27025
27030
  if (found) {
27026
27031
  return found;
@@ -27126,6 +27131,17 @@ class CurrentScope {
27126
27131
  var _a;
27127
27132
  return ((_a = this.localFriends.get(className.toUpperCase())) === null || _a === void 0 ? void 0 : _a.includes(friendName.toUpperCase())) === true;
27128
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
+ }
27129
27145
  getEnclosingClassName() {
27130
27146
  let curr = this.current;
27131
27147
  while (curr !== undefined) {
@@ -27350,6 +27366,97 @@ class ObjectOriented {
27350
27366
  }
27351
27367
  // does the supplied class have friendship with "friendName"?
27352
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
+ }
27353
27460
  hasFriendship(cd, friendName) {
27354
27461
  var _a;
27355
27462
  const friends = cd.getFriends().map(f => f.toUpperCase());
@@ -30326,6 +30433,8 @@ const _object_oriented_1 = __webpack_require__(/*! ../_object_oriented */ "./nod
30326
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");
30327
30434
  const _reference_1 = __webpack_require__(/*! ../_reference */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_reference.js");
30328
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");
30329
30438
  const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
30330
30439
  class AttributeName {
30331
30440
  static runSyntax(context, node, input, type, error = true) {
@@ -30354,6 +30463,15 @@ class AttributeName {
30354
30463
  }
30355
30464
  return void_type_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
30356
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
+ }
30357
30475
  if (type) {
30358
30476
  input.scope.addReference(token, found, type, input.filename);
30359
30477
  }
@@ -33292,8 +33410,6 @@ const _reference_1 = __webpack_require__(/*! ../_reference */ "./node_modules/@a
33292
33410
  const component_name_1 = __webpack_require__(/*! ./component_name */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/component_name.js");
33293
33411
  const attribute_name_1 = __webpack_require__(/*! ./attribute_name */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/attribute_name.js");
33294
33412
  const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
33295
- const visibility_1 = __webpack_require__(/*! ../../4_file_information/visibility */ "./node_modules/@abaplint/core/build/src/abap/4_file_information/visibility.js");
33296
- const class_definition_1 = __webpack_require__(/*! ../../types/class_definition */ "./node_modules/@abaplint/core/build/src/abap/types/class_definition.js");
33297
33413
  class MethodCallChain {
33298
33414
  static runSyntax(node, input, targetType) {
33299
33415
  var _a, _b;
@@ -33323,6 +33439,14 @@ class MethodCallChain {
33323
33439
  const methodToken = (_a = current.findDirectExpression(Expressions.MethodName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
33324
33440
  const methodName = methodToken === null || methodToken === void 0 ? void 0 : methodToken.getStr();
33325
33441
  const def = input.scope.findObjectDefinition(className);
33442
+ const isSuper = current === children[2]
33443
+ && first.get() instanceof Expressions.FieldChain
33444
+ && first.concatTokens().toUpperCase() === "SUPER";
33445
+ const superMessage = isSuper ? helper.checkSuperCall(def, methodName) : undefined;
33446
+ if (superMessage !== undefined) {
33447
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, methodToken, superMessage));
33448
+ return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
33449
+ }
33326
33450
  // eslint-disable-next-line prefer-const
33327
33451
  let { method, def: foundDef } = helper.searchMethodName(def, methodName);
33328
33452
  if (method === undefined && current === first) {
@@ -33342,12 +33466,19 @@ class MethodCallChain {
33342
33466
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, methodToken, message));
33343
33467
  return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
33344
33468
  }
33345
- const notVisible = method ? this.checkVisibility(method, def, foundDef, input) : undefined;
33469
+ const notVisible = method
33470
+ ? helper.memberNotVisible(method.getVisibility(), def, foundDef, input.scope.getEnclosingClassName())
33471
+ : undefined;
33346
33472
  if (notVisible !== undefined) {
33347
33473
  const message = `Method "${methodName}" is ${notVisible} and cannot be accessed`;
33348
33474
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, methodToken, message));
33349
33475
  return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
33350
33476
  }
33477
+ const specialMessage = isSuper ? undefined : helper.checkSpecialTestMethodCall(method, foundDef);
33478
+ if (specialMessage !== undefined) {
33479
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, methodToken, specialMessage));
33480
+ return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
33481
+ }
33351
33482
  const voidedName = context instanceof basic_1.VoidType ? context.getVoided() : undefined;
33352
33483
  const extra = helper.methodReferenceExtras(foundDef, className || voidedName);
33353
33484
  input.scope.addReference(methodToken, method, _reference_1.ReferenceType.MethodReference, input.filename, extra);
@@ -33390,47 +33521,6 @@ class MethodCallChain {
33390
33521
  return context;
33391
33522
  }
33392
33523
  //////////////////////////////////////
33393
- // returns the visibility as text if the method cannot be accessed from the current scope
33394
- static checkVisibility(method, def, foundDef, input) {
33395
- var _a, _b, _c;
33396
- const visibility = method.getVisibility();
33397
- if (visibility === visibility_1.Visibility.Public || foundDef === undefined) {
33398
- return undefined;
33399
- }
33400
- else if (!(foundDef instanceof class_definition_1.ClassDefinition)) {
33401
- // interface members are always public
33402
- return undefined;
33403
- }
33404
- const name = foundDef.getName().toUpperCase();
33405
- const enclosing = (_a = input.scope.getEnclosingClassName()) === null || _a === void 0 ? void 0 : _a.toUpperCase();
33406
- if (enclosing === undefined || enclosing === name) {
33407
- return undefined;
33408
- }
33409
- // friendship with the class used at the call site also gives access to inherited members
33410
- const helper = new _object_oriented_1.ObjectOriented(input.scope);
33411
- const visited = [];
33412
- let current = def instanceof class_definition_1.ClassDefinition ? def : foundDef;
33413
- while (current !== undefined && visited.includes(current.getName().toUpperCase()) === false) {
33414
- visited.push(current.getName().toUpperCase());
33415
- if (helper.hasFriendship(current, enclosing)) {
33416
- return undefined;
33417
- }
33418
- const sup = current.getSuperClass();
33419
- current = sup === undefined ? undefined : input.scope.findClassDefinition(sup);
33420
- }
33421
- if (visibility === visibility_1.Visibility.Protected) {
33422
- // subclasses can access protected members
33423
- let sup = (_b = input.scope.findClassDefinition(enclosing)) === null || _b === void 0 ? void 0 : _b.getSuperClass();
33424
- while (sup !== undefined) {
33425
- if (sup.toUpperCase() === name) {
33426
- return undefined;
33427
- }
33428
- sup = (_c = input.scope.findClassDefinition(sup)) === null || _c === void 0 ? void 0 : _c.getSuperClass();
33429
- }
33430
- return "protected";
33431
- }
33432
- return "private";
33433
- }
33434
33524
  static findTop(first, input, targetType) {
33435
33525
  var _a;
33436
33526
  if (first.get() instanceof Expressions.ClassName) {
@@ -33854,6 +33944,9 @@ const field_chain_1 = __webpack_require__(/*! ./field_chain */ "./node_modules/@
33854
33944
  const _reference_1 = __webpack_require__(/*! ../_reference */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_reference.js");
33855
33945
  const _check_offset_length_1 = __webpack_require__(/*! ./_check_offset_length */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_offset_length.js");
33856
33946
  const _check_text_symbol_1 = __webpack_require__(/*! ./_check_text_symbol */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_text_symbol.js");
33947
+ function normalizeParameterName(name) {
33948
+ return name.replace(/^!/, "").toUpperCase();
33949
+ }
33857
33950
  class MethodParameters {
33858
33951
  constructor() {
33859
33952
  this.requiredParameters = undefined;
@@ -34040,7 +34133,7 @@ class MethodParameters {
34040
34133
  throw new assert_error_1.AssertError("parameterListS, unexpected node, child");
34041
34134
  }
34042
34135
  const nameNode = c.findDirectExpression(Expressions.ParameterName);
34043
- const name = nameNode === null || nameNode === void 0 ? void 0 : nameNode.getFirstToken().getStr().toUpperCase();
34136
+ const name = nameNode === undefined ? undefined : normalizeParameterName(nameNode.getFirstToken().getStr());
34044
34137
  if (name === undefined || nameNode === undefined) {
34045
34138
  throw new assert_error_1.AssertError("parameterListS, no name determined");
34046
34139
  }
@@ -34095,7 +34188,7 @@ class MethodParameters {
34095
34188
  throw new assert_error_1.AssertError("parameterListT, unexpected node, child");
34096
34189
  }
34097
34190
  const nameNode = c.findDirectExpression(Expressions.ParameterName);
34098
- const name = nameNode === null || nameNode === void 0 ? void 0 : nameNode.getFirstToken().getStr().toUpperCase();
34191
+ const name = nameNode === undefined ? undefined : normalizeParameterName(nameNode.getFirstToken().getStr());
34099
34192
  if (name === undefined || nameNode === undefined) {
34100
34193
  throw new assert_error_1.AssertError("parameterListT, no name determined");
34101
34194
  }
@@ -34249,6 +34342,14 @@ class MethodSource {
34249
34342
  const methodToken = current.getFirstToken();
34250
34343
  const methodName = methodToken === null || methodToken === void 0 ? void 0 : methodToken.getStr();
34251
34344
  const def = input.scope.findObjectDefinition(className);
34345
+ const isSuper = implicitMe === false
34346
+ && first.get() instanceof Expressions.SourceField
34347
+ && first.concatTokens().toUpperCase() === "SUPER";
34348
+ const superMessage = isSuper ? helper.checkSuperCall(def, methodName) : undefined;
34349
+ if (superMessage !== undefined) {
34350
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, methodToken, superMessage));
34351
+ return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
34352
+ }
34252
34353
  // eslint-disable-next-line prefer-const
34253
34354
  let { method, def: foundDef } = helper.searchMethodName(def, methodName);
34254
34355
  if (implicitMe && current === first && (method === null || method === void 0 ? void 0 : method.isStatic()) === false && input.scope.isInStaticMethod() === true) {
@@ -34265,6 +34366,11 @@ class MethodSource {
34265
34366
  return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
34266
34367
  }
34267
34368
  else if (method) {
34369
+ const specialMessage = isSuper ? undefined : helper.checkSpecialTestMethodCall(method, foundDef);
34370
+ if (specialMessage !== undefined) {
34371
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, methodToken, specialMessage));
34372
+ return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
34373
+ }
34268
34374
  const extra = helper.methodReferenceExtras(foundDef, className);
34269
34375
  input.scope.addReference(methodToken, method, _reference_1.ReferenceType.MethodReference, input.filename, extra);
34270
34376
  context = method;
@@ -35363,6 +35469,7 @@ const corresponding_body_1 = __webpack_require__(/*! ./corresponding_body */ "./
35363
35469
  const _builtin_1 = __webpack_require__(/*! ../_builtin */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_builtin.js");
35364
35470
  const attribute_chain_1 = __webpack_require__(/*! ./attribute_chain */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/attribute_chain.js");
35365
35471
  const dereference_1 = __webpack_require__(/*! ./dereference */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/dereference.js");
35472
+ const cast_1 = __webpack_require__(/*! ./cast */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/cast.js");
35366
35473
  const _typed_identifier_1 = __webpack_require__(/*! ../../types/_typed_identifier */ "./node_modules/@abaplint/core/build/src/abap/types/_typed_identifier.js");
35367
35474
  const _type_utils_1 = __webpack_require__(/*! ../_type_utils */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_type_utils.js");
35368
35475
  const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
@@ -35586,6 +35693,10 @@ class Source {
35586
35693
  return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
35587
35694
  }
35588
35695
  }
35696
+ else if (get instanceof Expressions.Cast) {
35697
+ const found = cast_1.Cast.runSyntax(first, input, targetType);
35698
+ context = arithmetic === true ? this.infer(context, found, true) : found;
35699
+ }
35589
35700
  else if (get instanceof Expressions.FieldChain) {
35590
35701
  const found = field_chain_1.FieldChain.runSyntax(first, input, type, allowGenericDeference);
35591
35702
  context = arithmetic === true ? this.infer(context, found, true) : found;
@@ -35602,6 +35713,11 @@ class Source {
35602
35713
  context = this.infer(context, found, arithmetic);
35603
35714
  }
35604
35715
  else if (get instanceof Expressions.Dereference) {
35716
+ if (this.isNewObjectDereference(node, first)) {
35717
+ const message = "NEW cannot be dereferenced directly";
35718
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, first.getFirstToken(), message));
35719
+ return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
35720
+ }
35605
35721
  context = dereference_1.Dereference.runSyntax(first, context, input);
35606
35722
  }
35607
35723
  else if (get instanceof Expressions.ComponentChain) {
@@ -35789,6 +35905,16 @@ class Source {
35789
35905
  }
35790
35906
  return targetType;
35791
35907
  }
35908
+ // "NEW ty( )->*" is a syntax error, also in releases where a method call can be dereferenced
35909
+ static isNewObjectDereference(node, deref) {
35910
+ var _a;
35911
+ const children = node.getChildren();
35912
+ const before = children[children.indexOf(deref) - 1];
35913
+ return before instanceof nodes_1.ExpressionNode
35914
+ && before.get() instanceof Expressions.MethodCallChain
35915
+ && before.getChildren().length === 1
35916
+ && ((_a = before.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.NewObject;
35917
+ }
35792
35918
  }
35793
35919
  exports.Source = Source;
35794
35920
  //# sourceMappingURL=source.js.map
@@ -36756,6 +36882,7 @@ const expressions_1 = __webpack_require__(/*! ../../2_statements/expressions */
36756
36882
  const field_length_1 = __webpack_require__(/*! ./field_length */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/field_length.js");
36757
36883
  const cast_1 = __webpack_require__(/*! ./cast */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/cast.js");
36758
36884
  const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
36885
+ const version_1 = __webpack_require__(/*! ../../../version */ "./node_modules/@abaplint/core/build/src/version.js");
36759
36886
  class Target {
36760
36887
  static runSyntax(node, input) {
36761
36888
  const concat = node.concatTokens();
@@ -36821,6 +36948,12 @@ class Target {
36821
36948
  if (!(context instanceof basic_1.VoidType)) {
36822
36949
  context = context.getType();
36823
36950
  }
36951
+ if ((context === null || context === void 0 ? void 0 : context.isGeneric()) === true
36952
+ && !(0, version_1.releaseAtLeast)(input.scope.getRelease(), version_1.Release.v756)
36953
+ && input.scope.getLanguageVersion() !== version_1.LanguageVersion.Cloud
36954
+ && !input.scope.getOpenABAP()) {
36955
+ throw new Error("A generic reference cannot be dereferenced");
36956
+ }
36824
36957
  }
36825
36958
  else if (current.get() instanceof Expressions.ComponentName) {
36826
36959
  context = component_name_1.ComponentName.runSyntax(context, current, input);
@@ -40114,7 +40247,7 @@ class Convert {
40114
40247
  if ((stampTarget === null || stampTarget === void 0 ? void 0 : stampTarget.get()) instanceof Expressions.Target) {
40115
40248
  const inline = stampTarget === null || stampTarget === void 0 ? void 0 : stampTarget.findDirectExpression(Expressions.InlineData);
40116
40249
  if (inline) {
40117
- inline_data_1.InlineData.runSyntax(inline, input, new basic_1.PackedType(8, 4));
40250
+ inline_data_1.InlineData.runSyntax(inline, input, new basic_1.PackedType(8, 0));
40118
40251
  }
40119
40252
  else {
40120
40253
  target_1.Target.runSyntax(stampTarget, input);
@@ -51466,6 +51599,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
51466
51599
  exports.DataReference = void 0;
51467
51600
  const _abstract_type_1 = __webpack_require__(/*! ./_abstract_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/_abstract_type.js");
51468
51601
  const any_type_1 = __webpack_require__(/*! ./any_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/any_type.js");
51602
+ const table_type_1 = __webpack_require__(/*! ./table_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/table_type.js");
51469
51603
  class DataReference extends _abstract_type_1.AbstractType {
51470
51604
  constructor(type, qualifiedName) {
51471
51605
  super({ qualifiedName: qualifiedName });
@@ -51488,6 +51622,10 @@ class DataReference extends _abstract_type_1.AbstractType {
51488
51622
  if (this.type instanceof any_type_1.AnyType) {
51489
51623
  return true;
51490
51624
  }
51625
+ // LIKE REF TO a generic table, eg. a field symbol TYPE STANDARD TABLE
51626
+ if (this.type instanceof table_type_1.TableType && this.type.isGeneric()) {
51627
+ return true;
51628
+ }
51491
51629
  return false;
51492
51630
  }
51493
51631
  containsVoid() {
@@ -70605,6 +70743,7 @@ class Indent {
70605
70743
  || type instanceof Statements.ProcessBeforeOutput
70606
70744
  || type instanceof Statements.ProcessOnValueRequest
70607
70745
  || type instanceof Statements.TopOfPage
70746
+ || type instanceof Statements.EndOfPage
70608
70747
  || type instanceof Statements.Get
70609
70748
  || type instanceof Statements.EndOfSelection
70610
70749
  || type instanceof Statements.LoadOfProgram) {
@@ -70700,6 +70839,7 @@ class Indent {
70700
70839
  || type instanceof Statements.Initialization
70701
70840
  || type instanceof Statements.AtUserCommand
70702
70841
  || type instanceof Statements.TopOfPage
70842
+ || type instanceof Statements.EndOfPage
70703
70843
  || type instanceof Statements.EndOfSelection
70704
70844
  || type instanceof Statements.Public
70705
70845
  || type instanceof Statements.Protected
@@ -70897,7 +71037,7 @@ class Registry {
70897
71037
  }
70898
71038
  static abaplintVersion() {
70899
71039
  // magic, see build script "version.js"
70900
- return "2.120.65";
71040
+ return "2.120.68";
70901
71041
  }
70902
71042
  getDDICReferences() {
70903
71043
  return this.ddicReferences;
@@ -125588,6 +125728,10 @@ class Traversal {
125588
125728
  doOrWhileIndexBackups = new Map();
125589
125729
  statementsInsideLoop = new WeakSet();
125590
125730
  enclosingDoOrWhile = new WeakMap();
125731
+ /** DATA, CONSTANTS and FIELD-SYMBOLS nested in blocks, already declared in front of the block */
125732
+ declaredEarly = new WeakSet();
125733
+ emittingEarly = false;
125734
+ blockDepth = 0;
125591
125735
  reg;
125592
125736
  options;
125593
125737
  constructor(spaghetti, file, obj, reg, options) {
@@ -126426,17 +126570,15 @@ this.INTERNAL_ID = abap.internalIdCounter++;\n`;
126426
126570
  }
126427
126571
  else if (c.get() instanceof abaplint.Expressions.AttributeName
126428
126572
  && context instanceof abaplint.BasicTypes.ObjectReferenceType) {
126429
- const id = context.getIdentifier();
126430
- if (id instanceof abaplint.Types.ClassDefinition || id instanceof abaplint.Types.InterfaceDefinition) {
126431
- const concat = c.concatTokens();
126432
- if (concat.includes("~")) {
126433
- const [iname, aname] = concat.split("~");
126434
- const intf = this.findInterfaceDefinition(iname, scope);
126435
- context = intf?.getAttributes().findByName(aname)?.getType();
126436
- }
126437
- else {
126438
- context = id.getAttributes().findByName(concat)?.getType();
126439
- }
126573
+ const concat = c.concatTokens();
126574
+ if (concat.includes("~")) {
126575
+ const [iname, aname] = concat.split("~");
126576
+ const intf = this.findInterfaceDefinition(iname, scope);
126577
+ context = intf?.getAttributes().findByName(aname)?.getType();
126578
+ }
126579
+ else {
126580
+ // Global references can carry an identifier rather than a class definition.
126581
+ context = this.narrowContextAttribute(context, concat, scope);
126440
126582
  }
126441
126583
  }
126442
126584
  else if (c.get() instanceof abaplint.Expressions.AttributeName
@@ -126450,7 +126592,7 @@ this.INTERNAL_ID = abap.internalIdCounter++;\n`;
126450
126592
  return context;
126451
126593
  }
126452
126594
  isInsideLoop(node) {
126453
- return this.statementsInsideLoop.has(node);
126595
+ return this.statementsInsideLoop.has(node) && !this.declaredEarly.has(node);
126454
126596
  }
126455
126597
  isInsideDoOrWhile(node) {
126456
126598
  return this.findCurrentDoOrWhileIndexBackup(node) !== undefined;
@@ -126545,7 +126687,87 @@ this.INTERNAL_ID = abap.internalIdCounter++;\n`;
126545
126687
  return this.obj.getType() + "-" + this.obj.getName() + "-";
126546
126688
  }
126547
126689
  ////////////////////////////
126690
+ /** In ABAP, DATA, CONSTANTS and FIELD-SYMBOLS are visible in the whole method/form/program, but a
126691
+ * javascript "let" inside the block of an IF, LOOP, TRY etc. is not. So before each block on
126692
+ * method/form/program level the declarations nested in it are output, in source order, and
126693
+ * skipped inside the block. They then exist after the block even if the branch did not run,
126694
+ * and are initialized once, also when the block is a loop */
126695
+ traverseProcedureLevel(node) {
126696
+ const ret = new chunk_1.Chunk();
126697
+ for (const c of node.getChildren()) {
126698
+ if (c instanceof abaplint.Nodes.StructureNode && Traversal.isDeclaration(c) === false) {
126699
+ ret.appendChunk(this.declareNestedEarly(c));
126700
+ this.blockDepth++;
126701
+ try {
126702
+ ret.appendChunk(this.traverseStructure(c));
126703
+ }
126704
+ finally {
126705
+ this.blockDepth--;
126706
+ }
126707
+ }
126708
+ else {
126709
+ ret.appendChunk(this.traverse(c));
126710
+ }
126711
+ }
126712
+ return ret;
126713
+ }
126714
+ declareNestedEarly(block) {
126715
+ const found = [];
126716
+ Traversal.findNestedDeclarations(block, found);
126717
+ for (const node of found) {
126718
+ this.declaredEarly.add(node);
126719
+ if (node instanceof abaplint.Nodes.StructureNode) {
126720
+ for (const statement of node.findAllStatementNodes()) {
126721
+ this.declaredEarly.add(statement);
126722
+ }
126723
+ }
126724
+ }
126725
+ const ret = new chunk_1.Chunk();
126726
+ this.emittingEarly = true;
126727
+ try {
126728
+ for (const node of found) {
126729
+ ret.appendChunk(this.traverse(node));
126730
+ }
126731
+ }
126732
+ finally {
126733
+ this.emittingEarly = false;
126734
+ }
126735
+ return ret;
126736
+ }
126737
+ static isDeclaration(node) {
126738
+ const get = node.get();
126739
+ return get instanceof abaplint.Structures.Data
126740
+ || get instanceof abaplint.Structures.Constants
126741
+ || get instanceof abaplint.Structures.Types;
126742
+ }
126743
+ static findNestedDeclarations(node, found) {
126744
+ for (const c of node.getChildren()) {
126745
+ if (c instanceof abaplint.Nodes.StatementNode) {
126746
+ const get = c.get();
126747
+ if (get instanceof abaplint.Statements.Data
126748
+ || get instanceof abaplint.Statements.Constant
126749
+ || get instanceof abaplint.Statements.FieldSymbol) {
126750
+ found.push(c);
126751
+ }
126752
+ }
126753
+ else if (c instanceof abaplint.Nodes.StructureNode) {
126754
+ const get = c.get();
126755
+ if (get instanceof abaplint.Structures.Data || get instanceof abaplint.Structures.Constants) {
126756
+ found.push(c);
126757
+ }
126758
+ else {
126759
+ Traversal.findNestedDeclarations(c, found);
126760
+ }
126761
+ }
126762
+ }
126763
+ }
126548
126764
  traverseStructure(node) {
126765
+ if (this.declaredEarly.has(node) && this.emittingEarly === false) {
126766
+ return new chunk_1.Chunk();
126767
+ }
126768
+ else if (this.blockDepth === 0 && node.get() instanceof abaplint.Structures.Normal) {
126769
+ return this.traverseProcedureLevel(node);
126770
+ }
126549
126771
  const list = StructureTranspilers;
126550
126772
  const ret = new chunk_1.Chunk();
126551
126773
  const search = node.get().constructor.name + "Transpiler";
@@ -126568,6 +126790,9 @@ this.INTERNAL_ID = abap.internalIdCounter++;\n`;
126568
126790
  return ret;
126569
126791
  }
126570
126792
  traverseStatement(node) {
126793
+ if (this.declaredEarly.has(node) && this.emittingEarly === false) {
126794
+ return new chunk_1.Chunk();
126795
+ }
126571
126796
  const list = StatementTranspilers;
126572
126797
  const search = node.get().constructor.name + "Transpiler";
126573
126798
  if (list[search]) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/transpiler-cli",
3
- "version": "2.13.97",
3
+ "version": "2.13.99",
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.65",
31
- "@abaplint/transpiler": "^2.13.97",
30
+ "@abaplint/core": "^2.120.68",
31
+ "@abaplint/transpiler": "^2.13.99",
32
32
  "@types/glob": "^9.0.0",
33
33
  "@types/node": "^26.6.2",
34
34
  "@types/progress": "^2.0.7",