@abaplint/cli 2.120.43 → 2.120.44

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/cli.js +157 -21
  2. package/package.json +2 -2
package/build/cli.js CHANGED
@@ -24361,6 +24361,7 @@ exports.ABAPFileInformationParser = void 0;
24361
24361
  const Structures = __importStar(__webpack_require__(/*! ../3_structures/structures */ "../core/build/src/abap/3_structures/structures/index.js"));
24362
24362
  const Expressions = __importStar(__webpack_require__(/*! ../2_statements/expressions */ "../core/build/src/abap/2_statements/expressions/index.js"));
24363
24363
  const Statements = __importStar(__webpack_require__(/*! ../2_statements/statements */ "../core/build/src/abap/2_statements/statements/index.js"));
24364
+ const nodes_1 = __webpack_require__(/*! ../nodes */ "../core/build/src/abap/nodes/index.js");
24364
24365
  const _identifier_1 = __webpack_require__(/*! ./_identifier */ "../core/build/src/abap/4_file_information/_identifier.js");
24365
24366
  const Tokens = __importStar(__webpack_require__(/*! ../1_lexer/tokens */ "../core/build/src/abap/1_lexer/tokens/index.js"));
24366
24367
  const visibility_1 = __webpack_require__(/*! ./visibility */ "../core/build/src/abap/4_file_information/visibility.js");
@@ -24500,6 +24501,7 @@ class ABAPFileInformationParser {
24500
24501
  riskLevel,
24501
24502
  isAbstract: (cdef === null || cdef === void 0 ? void 0 : cdef.findDirectTokenByText("ABSTRACT")) !== undefined,
24502
24503
  isSharedMemory: concat.includes(" SHARED MEMORY ENABLED"),
24504
+ behaviorDefinitionName: this.findBehaviorDefinitionName(cdef),
24503
24505
  isFinal: found.findFirstExpression(Expressions.ClassFinal) !== undefined,
24504
24506
  aliases,
24505
24507
  attributes,
@@ -24509,6 +24511,20 @@ class ABAPFileInformationParser {
24509
24511
  return classes;
24510
24512
  }
24511
24513
  ///////////////////
24514
+ /** "FOR BEHAVIOR OF" and "FOR EVENTS OF" both use the BehaviorDefinitionName expression,
24515
+ * so look at the token two positions before the expression to tell them apart */
24516
+ findBehaviorDefinitionName(cdef) {
24517
+ const children = (cdef === null || cdef === void 0 ? void 0 : cdef.getChildren()) || [];
24518
+ for (let i = 2; i < children.length; i++) {
24519
+ const child = children[i];
24520
+ if (child instanceof nodes_1.ExpressionNode
24521
+ && child.get() instanceof Expressions.BehaviorDefinitionName
24522
+ && children[i - 2].concatTokens().toUpperCase() === "BEHAVIOR") {
24523
+ return child.concatTokens();
24524
+ }
24525
+ }
24526
+ return undefined;
24527
+ }
24512
24528
  getImplementing(input) {
24513
24529
  const ret = [];
24514
24530
  for (const node of input.findAllStatements(Statements.InterfaceDef)) {
@@ -26204,6 +26220,18 @@ class CurrentScope {
26204
26220
  }
26205
26221
  return undefined;
26206
26222
  }
26223
+ /** the BDEF from "FOR BEHAVIOR OF" of the enclosing global class, undefined if not a behavior pool */
26224
+ findBehaviorDefinition() {
26225
+ var _a;
26226
+ if (this.parentObj.getType() !== "CLAS") {
26227
+ return undefined;
26228
+ }
26229
+ const name = (_a = this.parentObj.getClassDefinition()) === null || _a === void 0 ? void 0 : _a.behaviorDefinitionName;
26230
+ if (name === undefined) {
26231
+ return undefined;
26232
+ }
26233
+ return this.reg.getObject("BDEF", name);
26234
+ }
26207
26235
  isBadiDef(name) {
26208
26236
  const upper = name.toUpperCase();
26209
26237
  for (const enhs of this.reg.getObjectsByType("ENHS")) {
@@ -28513,7 +28541,7 @@ class BasicTypes {
28513
28541
  return undefined;
28514
28542
  }
28515
28543
  parseTable(node, name) {
28516
- var _a, _b, _c, _d;
28544
+ var _a, _b, _c;
28517
28545
  const typename = node.findFirstExpression(Expressions.TypeName) || node.findFirstExpression(Expressions.EntityAssociation);
28518
28546
  const text = (_a = node.findFirstExpression(Expressions.TypeTable)) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase();
28519
28547
  if (text === undefined) {
@@ -28650,25 +28678,31 @@ class BasicTypes {
28650
28678
  return new Types.TableType(structure, options);
28651
28679
  }
28652
28680
  else if (typename && this.isRAPTableFor(text)) {
28653
- const name = typename.concatTokens();
28654
- const ddlsName = this.getRAPBaseEntityName(name);
28655
- const type = (_d = this.input.scope.getDDIC().lookupDDLS(ddlsName)) === null || _d === void 0 ? void 0 : _d.type;
28656
- if (type) {
28657
- return new Types.TableType(basic_1.VoidType.get("RAP-TODO"), options);
28658
- }
28659
- else if (this.isRAPDerivedEntityName(name)) {
28660
- return Types.VoidType.get(name);
28661
- }
28662
- else if (this.input.scope.getDDIC().inErrorNamespace(ddlsName)) {
28663
- return new Types.UnknownType(`DDLS ${ddlsName} not found`);
28664
- }
28665
- else {
28666
- return Types.VoidType.get(name);
28667
- }
28681
+ return this.rapTableFor(typename.concatTokens(), options);
28668
28682
  }
28669
28683
  // fallback to old style syntax, OCCURS etc
28670
28684
  return this.parseType(node, name);
28671
28685
  }
28686
+ /** type of a RAP derived table type, ie the "TABLE FOR LOCK zentity" part of a type */
28687
+ rapTableFor(entityName, options) {
28688
+ var _a;
28689
+ const ddlsName = this.resolveRAPAlias(this.getRAPBaseEntityName(entityName));
28690
+ if ((_a = this.input.scope.getDDIC().lookupDDLS(ddlsName)) === null || _a === void 0 ? void 0 : _a.type) {
28691
+ return new Types.TableType(basic_1.VoidType.get("RAP-TODO"), options !== null && options !== void 0 ? options : {
28692
+ withHeader: false,
28693
+ keyType: Types.TableKeyType.user,
28694
+ primaryKey: { name: "primary_key", type: basic_1.TableAccessType.standard, isUnique: false, keyFields: [] },
28695
+ secondary: [],
28696
+ });
28697
+ }
28698
+ else if (this.isRAPDerivedEntityName(entityName)) {
28699
+ return Types.VoidType.get(entityName);
28700
+ }
28701
+ else if (this.input.scope.getDDIC().inErrorNamespace(ddlsName)) {
28702
+ return new Types.UnknownType(`DDLS ${ddlsName} not found`);
28703
+ }
28704
+ return Types.VoidType.get(entityName);
28705
+ }
28672
28706
  parseType(node, qualifiedName) {
28673
28707
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
28674
28708
  const typeName = node.findFirstExpression(Expressions.TypeName);
@@ -28862,6 +28896,12 @@ class BasicTypes {
28862
28896
  const splitAt = Math.min(...candidates);
28863
28897
  return name.substring(0, splitAt);
28864
28898
  }
28899
+ /** inside a behavior pool the entities are referenced via the aliases defined in the BDEF */
28900
+ resolveRAPAlias(name) {
28901
+ var _a;
28902
+ var _b;
28903
+ return (_b = (_a = this.input.scope.findBehaviorDefinition()) === null || _a === void 0 ? void 0 : _a.findEntityNameByAlias(name)) !== null && _b !== void 0 ? _b : name;
28904
+ }
28865
28905
  isRAPDerivedEntityName(name) {
28866
28906
  return name.includes("\\") || name.includes("~");
28867
28907
  }
@@ -53432,6 +53472,7 @@ const _typed_identifier_1 = __webpack_require__(/*! ./_typed_identifier */ "../c
53432
53472
  const basic_1 = __webpack_require__(/*! ./basic */ "../core/build/src/abap/types/basic/index.js");
53433
53473
  const method_def_returning_1 = __webpack_require__(/*! ../5_syntax/expressions/method_def_returning */ "../core/build/src/abap/5_syntax/expressions/method_def_returning.js");
53434
53474
  const method_param_1 = __webpack_require__(/*! ../5_syntax/expressions/method_param */ "../core/build/src/abap/5_syntax/expressions/method_param.js");
53475
+ const basic_types_1 = __webpack_require__(/*! ../5_syntax/basic_types */ "../core/build/src/abap/5_syntax/basic_types.js");
53435
53476
  const _object_oriented_1 = __webpack_require__(/*! ../5_syntax/_object_oriented */ "../core/build/src/abap/5_syntax/_object_oriented.js");
53436
53477
  const _reference_1 = __webpack_require__(/*! ../5_syntax/_reference */ "../core/build/src/abap/5_syntax/_reference.js");
53437
53478
  const identifier_1 = __webpack_require__(/*! ../1_lexer/tokens/identifier */ "../core/build/src/abap/1_lexer/tokens/identifier.js");
@@ -53619,24 +53660,37 @@ class MethodParameters {
53619
53660
  }
53620
53661
  }
53621
53662
  workaroundRAP(node, input, parentName) {
53663
+ var _a;
53622
53664
  const resultName = node.findExpressionAfterToken("RESULT");
53623
53665
  const concat = node.concatTokens().toUpperCase();
53624
53666
  const isRap = node.findExpressionAfterToken("IMPORTING")
53625
53667
  || (concat.includes(" IMPORTING REQUEST ") ? node.findExpressionAfterToken("REQUEST") : undefined);
53626
53668
  if (isRap) {
53669
+ // "FOR LOCK" handlers have a well defined signature, so the types can be derived
53670
+ const lockEntity = concat.includes(" FOR LOCK ")
53671
+ ? (_a = node.findExpressionAfterToken("LOCK")) === null || _a === void 0 ? void 0 : _a.concatTokens()
53672
+ : undefined;
53627
53673
  for (const foo of node.findDirectExpressions(Expressions.MethodParamName)) {
53628
53674
  if (foo === resultName) {
53629
53675
  continue;
53630
53676
  }
53631
- this.importing.push(new _typed_identifier_1.TypedIdentifier(foo.getFirstToken(), input.filename, basic_1.VoidType.get("RapMethodParameter"), ["importing" /* IdentifierMeta.MethodImporting */]));
53677
+ const type = lockEntity === undefined
53678
+ ? basic_1.VoidType.get("RapMethodParameter")
53679
+ : new basic_types_1.BasicTypes(input).rapTableFor(lockEntity);
53680
+ this.importing.push(new _typed_identifier_1.TypedIdentifier(foo.getFirstToken(), input.filename, type, ["importing" /* IdentifierMeta.MethodImporting */]));
53632
53681
  }
53633
- if (concat.includes(" FOR VALIDATE ")
53682
+ if (lockEntity !== undefined) {
53683
+ // note: "mapped" is not part of the signature for "FOR LOCK"
53684
+ const token = isRap.getFirstToken();
53685
+ this.exporting.push(new _typed_identifier_1.TypedIdentifier(new identifier_1.Identifier(token.getStart(), "failed"), input.filename, basic_1.VoidType.get(`RESPONSE FOR FAILED EARLY ${lockEntity}`), ["exporting" /* IdentifierMeta.MethodExporting */]));
53686
+ this.exporting.push(new _typed_identifier_1.TypedIdentifier(new identifier_1.Identifier(token.getStart(), "reported"), input.filename, basic_1.VoidType.get(`RESPONSE FOR REPORTED EARLY ${lockEntity}`), ["exporting" /* IdentifierMeta.MethodExporting */]));
53687
+ }
53688
+ else if (concat.includes(" FOR VALIDATE ")
53634
53689
  || concat.includes(" FOR BEHAVIOR ")
53635
53690
  || concat.includes(" FOR DETERMINE ")
53636
53691
  || concat.includes(" FOR FEATURES ")
53637
53692
  || concat.includes(" FOR INSTANCE FEATURES ")
53638
53693
  || concat.includes(" FOR GLOBAL AUTHORIZATION ")
53639
- || concat.includes(" FOR LOCK ")
53640
53694
  || concat.includes(" FOR PRECHECK ")
53641
53695
  || concat.includes(" FOR NUMBERING ")
53642
53696
  || concat.includes(" FOR READ ")
@@ -61595,6 +61649,10 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
61595
61649
  exports.BehaviorDefinition = void 0;
61596
61650
  const _abstract_object_1 = __webpack_require__(/*! ./_abstract_object */ "../core/build/src/objects/_abstract_object.js");
61597
61651
  class BehaviorDefinition extends _abstract_object_1.AbstractObject {
61652
+ constructor() {
61653
+ super(...arguments);
61654
+ this.parsedData = undefined;
61655
+ }
61598
61656
  getType() {
61599
61657
  return "BDEF";
61600
61658
  }
@@ -61608,6 +61666,49 @@ class BehaviorDefinition extends _abstract_object_1.AbstractObject {
61608
61666
  // todo
61609
61667
  return undefined;
61610
61668
  }
61669
+ setDirty() {
61670
+ this.parsedData = undefined;
61671
+ super.setDirty();
61672
+ }
61673
+ findSourceFile() {
61674
+ return this.getFiles().find(f => f.getFilename().endsWith(".asbdef"));
61675
+ }
61676
+ listEntities() {
61677
+ return this.parseSource().entities;
61678
+ }
61679
+ /** finds the entity name for a given alias, undefined if the alias is not defined */
61680
+ findEntityNameByAlias(alias) {
61681
+ var _a;
61682
+ const upper = alias.toUpperCase();
61683
+ for (const entity of this.listEntities()) {
61684
+ if (((_a = entity.alias) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === upper) {
61685
+ return entity.name;
61686
+ }
61687
+ }
61688
+ return undefined;
61689
+ }
61690
+ /////////////////////////
61691
+ parseSource() {
61692
+ var _a;
61693
+ if (this.parsedData !== undefined) {
61694
+ return this.parsedData;
61695
+ }
61696
+ this.parsedData = { entities: [] };
61697
+ const raw = (_a = this.findSourceFile()) === null || _a === void 0 ? void 0 : _a.getRaw();
61698
+ if (raw === undefined) {
61699
+ return this.parsedData;
61700
+ }
61701
+ // BDEF uses "//" for line comments
61702
+ const stripped = raw.replace(/\/\/.*$/gm, "");
61703
+ // eg. "define behavior for ZI_Booking alias Booking", also "define abstract behavior for ..."
61704
+ const regex = /\bdefine\s+(?:\w+\s+)*?behavior\s+for\s+([\w/]+)(?:\s+alias\s+(\w+))?/gi;
61705
+ let match = regex.exec(stripped);
61706
+ while (match !== null) {
61707
+ this.parsedData.entities.push({ name: match[1], alias: match[2] });
61708
+ match = regex.exec(stripped);
61709
+ }
61710
+ return this.parsedData;
61711
+ }
61611
61712
  }
61612
61713
  exports.BehaviorDefinition = BehaviorDefinition;
61613
61714
  //# sourceMappingURL=behavior_definition.js.map
@@ -65112,6 +65213,7 @@ exports.LockObject = void 0;
65112
65213
  const basic_1 = __webpack_require__(/*! ../abap/types/basic */ "../core/build/src/abap/types/basic/index.js");
65113
65214
  const ddic_1 = __webpack_require__(/*! ../ddic */ "../core/build/src/ddic.js");
65114
65215
  const _abstract_object_1 = __webpack_require__(/*! ./_abstract_object */ "../core/build/src/objects/_abstract_object.js");
65216
+ const xml_utils_1 = __webpack_require__(/*! ../xml_utils */ "../core/build/src/xml_utils.js");
65115
65217
  class LockObject extends _abstract_object_1.AbstractObject {
65116
65218
  getType() {
65117
65219
  return "ENQU";
@@ -65132,6 +65234,11 @@ class LockObject extends _abstract_object_1.AbstractObject {
65132
65234
  this.parse();
65133
65235
  return (_a = this.parsedXML) === null || _a === void 0 ? void 0 : _a.primaryTable;
65134
65236
  }
65237
+ getParameters() {
65238
+ var _a;
65239
+ this.parse();
65240
+ return (_a = this.parsedXML) === null || _a === void 0 ? void 0 : _a.parameters;
65241
+ }
65135
65242
  parseType(reg) {
65136
65243
  var _a;
65137
65244
  this.parse();
@@ -65156,7 +65263,7 @@ class LockObject extends _abstract_object_1.AbstractObject {
65156
65263
  }
65157
65264
  }
65158
65265
  parse() {
65159
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
65266
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
65160
65267
  if (this.parsedXML) {
65161
65268
  return { updated: false, runtime: 0 };
65162
65269
  }
@@ -65170,6 +65277,18 @@ class LockObject extends _abstract_object_1.AbstractObject {
65170
65277
  }
65171
65278
  this.parsedXML.primaryTable = (_f = (_e = (_d = (_c = parsed.abapGit) === null || _c === void 0 ? void 0 : _c["asx:abap"]) === null || _d === void 0 ? void 0 : _d["asx:values"]) === null || _e === void 0 ? void 0 : _e.DD25V) === null || _f === void 0 ? void 0 : _f.ROOTTAB;
65172
65279
  this.parsedXML.description = (_k = (_j = (_h = (_g = parsed.abapGit) === null || _g === void 0 ? void 0 : _g["asx:abap"]) === null || _h === void 0 ? void 0 : _h["asx:values"]) === null || _j === void 0 ? void 0 : _j.DD25V) === null || _k === void 0 ? void 0 : _k.DDTEXT;
65280
+ this.parsedXML.parameters = [];
65281
+ const parameters = (_o = (_m = (_l = parsed.abapGit) === null || _l === void 0 ? void 0 : _l["asx:abap"]) === null || _m === void 0 ? void 0 : _m["asx:values"]) === null || _o === void 0 ? void 0 : _o.DD27P_TABLE;
65282
+ for (const parameter of (0, xml_utils_1.xmlToArray)(parameters === null || parameters === void 0 ? void 0 : parameters.DD27P)) {
65283
+ if (typeof (parameter === null || parameter === void 0 ? void 0 : parameter.VIEWFIELD) !== "string") {
65284
+ continue;
65285
+ }
65286
+ this.parsedXML.parameters.push({
65287
+ VIEWFIELD: parameter.VIEWFIELD,
65288
+ TABNAME: parameter.TABNAME,
65289
+ FIELDNAME: parameter.FIELDNAME,
65290
+ });
65291
+ }
65173
65292
  const end = Date.now();
65174
65293
  return { updated: true, runtime: end - start };
65175
65294
  }
@@ -70176,7 +70295,7 @@ class Registry {
70176
70295
  }
70177
70296
  static abaplintVersion() {
70178
70297
  // magic, see build script "version.js"
70179
- return "2.120.43";
70298
+ return "2.120.44";
70180
70299
  }
70181
70300
  getDDICReferences() {
70182
70301
  return this.ddicReferences;
@@ -100104,6 +100223,7 @@ class XMLConsistency {
100104
100223
  * XML is well-formed and parseable
100105
100224
  * Naming for CLAS and INTF objects
100106
100225
  * QUAN fields in TABL objects have reference table and field values
100226
+ * Lock parameter names in ENQU objects are max 16 characters
100107
100227
  * Texts and translations do not exceed maximum allowed length.`,
100108
100228
  tags: [_irule_1.RuleTag.Naming, _irule_1.RuleTag.Syntax],
100109
100229
  };
@@ -100161,6 +100281,9 @@ class XMLConsistency {
100161
100281
  else if (obj instanceof Objects.Table) {
100162
100282
  issues.push(...this.runTable(obj, file));
100163
100283
  }
100284
+ else if (obj instanceof Objects.LockObject) {
100285
+ issues.push(...this.runLockObject(obj, file));
100286
+ }
100164
100287
  if (obj instanceof _abap_object_1.ABAPObject) {
100165
100288
  issues.push(...this.runTextPool(obj, file));
100166
100289
  }
@@ -100344,6 +100467,19 @@ class XMLConsistency {
100344
100467
  }
100345
100468
  return issues;
100346
100469
  }
100470
+ runLockObject(obj, file) {
100471
+ var _a;
100472
+ const maxParameterLength = 16;
100473
+ const issues = [];
100474
+ for (const parameter of (_a = obj.getParameters()) !== null && _a !== void 0 ? _a : []) {
100475
+ if (parameter.VIEWFIELD.length > maxParameterLength) {
100476
+ const message = `Lock parameter ${parameter.VIEWFIELD} exceeds maximum length of ` +
100477
+ `${maxParameterLength} characters (actual: ${parameter.VIEWFIELD.length})`;
100478
+ issues.push(issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.conf.severity));
100479
+ }
100480
+ }
100481
+ return issues;
100482
+ }
100347
100483
  runTable(obj, file) {
100348
100484
  var _a, _b;
100349
100485
  var _c;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/cli",
3
- "version": "2.120.43",
3
+ "version": "2.120.44",
4
4
  "description": "abaplint - Command Line Interface",
5
5
  "funding": "https://github.com/sponsors/larshp",
6
6
  "bin": {
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "homepage": "https://abaplint.org",
41
41
  "devDependencies": {
42
- "@abaplint/core": "^2.120.43",
42
+ "@abaplint/core": "^2.120.44",
43
43
  "@types/chai": "^4.3.20",
44
44
  "@types/minimist": "^1.2.5",
45
45
  "@types/mocha": "^10.0.10",