@abaplint/cli 2.119.37 → 2.119.39

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 +91 -24
  2. package/package.json +2 -2
package/build/cli.js CHANGED
@@ -26933,16 +26933,16 @@ class BasicTypes {
26933
26933
  options.primaryKey.type = basic_1.TableAccessType.standard;
26934
26934
  return new Types.TableType(structure, options);
26935
26935
  }
26936
- else if (typename && (text.startsWith("TYPE TABLE FOR CREATE ")
26937
- || text.startsWith("TYPE TABLE FOR READ ")
26938
- || text.startsWith("TYPE TABLE FOR DELETE ")
26939
- || text.startsWith("TYPE TABLE FOR UPDATE "))) {
26936
+ else if (typename && this.isRAPTableFor(text)) {
26940
26937
  const name = typename.concatTokens();
26941
26938
  const ddlsName = this.getRAPBaseEntityName(name);
26942
26939
  const type = (_d = this.input.scope.getDDIC().lookupDDLS(ddlsName)) === null || _d === void 0 ? void 0 : _d.type;
26943
26940
  if (type) {
26944
26941
  return new Types.TableType(basic_1.VoidType.get("RAP-TODO"), options);
26945
26942
  }
26943
+ else if (this.isRAPDerivedEntityName(name)) {
26944
+ return Types.VoidType.get(name);
26945
+ }
26946
26946
  else if (this.input.scope.getDDIC().inErrorNamespace(ddlsName)) {
26947
26947
  return new Types.UnknownType(`DDLS ${ddlsName} not found`);
26948
26948
  }
@@ -26954,7 +26954,7 @@ class BasicTypes {
26954
26954
  return this.parseType(node, name);
26955
26955
  }
26956
26956
  parseType(node, qualifiedName) {
26957
- var _a, _b, _c, _d, _e, _f, _g, _h;
26957
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
26958
26958
  const typeName = node.findFirstExpression(Expressions.TypeName);
26959
26959
  let text = (_a = node.findFirstExpression(Expressions.Type)) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase();
26960
26960
  if (text === undefined) {
@@ -26967,7 +26967,10 @@ class BasicTypes {
26967
26967
  }
26968
26968
  }
26969
26969
  if (text === undefined) {
26970
- text = (_d = node.findFirstExpression(Expressions.FormParamType)) === null || _d === void 0 ? void 0 : _d.concatTokens().toUpperCase();
26970
+ text = (_d = node.findFirstExpression(Expressions.TypeStructure)) === null || _d === void 0 ? void 0 : _d.concatTokens().toUpperCase();
26971
+ }
26972
+ if (text === undefined) {
26973
+ text = (_e = node.findFirstExpression(Expressions.FormParamType)) === null || _e === void 0 ? void 0 : _e.concatTokens().toUpperCase();
26971
26974
  }
26972
26975
  if (text === undefined
26973
26976
  && node.get() instanceof Statements.Parameter
@@ -26978,8 +26981,11 @@ class BasicTypes {
26978
26981
  text = "TYPE";
26979
26982
  }
26980
26983
  let found = undefined;
26981
- if (text.startsWith("LIKE LINE OF ")) {
26982
- const name = (_e = node.findFirstExpression(Expressions.FieldChain)) === null || _e === void 0 ? void 0 : _e.concatTokens();
26984
+ if (this.isRAPTypeStructure(text)) {
26985
+ return Types.VoidType.get((_f = node.findFirstExpression(Expressions.TypeStructure)) === null || _f === void 0 ? void 0 : _f.concatTokens());
26986
+ }
26987
+ else if (text.startsWith("LIKE LINE OF ")) {
26988
+ const name = (_g = node.findFirstExpression(Expressions.FieldChain)) === null || _g === void 0 ? void 0 : _g.concatTokens();
26983
26989
  let e = node.findFirstExpression(Expressions.Type);
26984
26990
  if (e === undefined) {
26985
26991
  e = node.findFirstExpression(Expressions.FormParamType);
@@ -27002,7 +27008,7 @@ class BasicTypes {
27002
27008
  }
27003
27009
  }
27004
27010
  else if (text.startsWith("LIKE REF TO ")) {
27005
- const name = (_f = node.findFirstExpression(Expressions.FieldChain)) === null || _f === void 0 ? void 0 : _f.concatTokens();
27011
+ const name = (_h = node.findFirstExpression(Expressions.FieldChain)) === null || _h === void 0 ? void 0 : _h.concatTokens();
27006
27012
  const type = this.resolveLikeName(node.findFirstExpression(Expressions.Type), false);
27007
27013
  if (type === undefined) {
27008
27014
  return new Types.UnknownType("Type error, could not resolve \"" + name + "\", parseType");
@@ -27093,7 +27099,7 @@ class BasicTypes {
27093
27099
  }
27094
27100
  }
27095
27101
  if (text.includes(" WITH INDICATORS ")) {
27096
- const componentName = (_h = (_g = node.findFirstExpression(Expressions.Type)) === null || _g === void 0 ? void 0 : _g.findDirectExpression(Expressions.ComponentName)) === null || _h === void 0 ? void 0 : _h.concatTokens().toUpperCase();
27102
+ const componentName = (_k = (_j = node.findFirstExpression(Expressions.Type)) === null || _j === void 0 ? void 0 : _j.findDirectExpression(Expressions.ComponentName)) === null || _k === void 0 ? void 0 : _k.concatTokens().toUpperCase();
27097
27103
  if (componentName === undefined) {
27098
27104
  throw new Error("parseType, componentName expected");
27099
27105
  }
@@ -27119,12 +27125,38 @@ class BasicTypes {
27119
27125
  getRAPBaseEntityName(name) {
27120
27126
  const association = name.indexOf("\\_");
27121
27127
  const path = name.indexOf("\\\\");
27122
- if (association === -1 && path === -1) {
27128
+ const action = name.indexOf("~");
27129
+ if (association === -1 && path === -1 && action === -1) {
27123
27130
  return name;
27124
27131
  }
27125
- const splitAt = association === -1 ? path : path === -1 ? association : Math.min(association, path);
27132
+ const candidates = [association, path, action].filter(i => i !== -1);
27133
+ const splitAt = Math.min(...candidates);
27126
27134
  return name.substring(0, splitAt);
27127
27135
  }
27136
+ isRAPDerivedEntityName(name) {
27137
+ return name.includes("\\") || name.includes("~");
27138
+ }
27139
+ isRAPTableFor(text) {
27140
+ return text.startsWith("TYPE TABLE FOR ACTION IMPORT ")
27141
+ || text.startsWith("TYPE TABLE FOR ACTION RESULT ")
27142
+ || text.startsWith("TYPE TABLE FOR CREATE ")
27143
+ || text.startsWith("TYPE TABLE FOR DELETE ")
27144
+ || text.startsWith("TYPE TABLE FOR DETERMINATION ")
27145
+ || text.startsWith("TYPE TABLE FOR EVENT ")
27146
+ || text.startsWith("TYPE TABLE FOR FAILED ")
27147
+ || text.startsWith("TYPE TABLE FOR FAILED EARLY ")
27148
+ || text.startsWith("TYPE TABLE FOR LOCK ")
27149
+ || text.startsWith("TYPE TABLE FOR READ ")
27150
+ || text.startsWith("TYPE TABLE FOR READ IMPORT ")
27151
+ || text.startsWith("TYPE TABLE FOR READ RESULT ")
27152
+ || text.startsWith("TYPE TABLE FOR REPORTED EARLY ")
27153
+ || text.startsWith("TYPE TABLE FOR UPDATE ");
27154
+ }
27155
+ isRAPTypeStructure(text) {
27156
+ return text.startsWith("TYPE STRUCTURE FOR ")
27157
+ || text.startsWith("TYPE RESPONSE FOR ")
27158
+ || text.startsWith("TYPE REQUEST FOR CHANGE ");
27159
+ }
27128
27160
  // todo, rewrite this method
27129
27161
  resolveTypeChain(expr) {
27130
27162
  var _a, _b, _c, _d;
@@ -37383,6 +37415,7 @@ const source_1 = __webpack_require__(/*! ../expressions/source */ "../core/build
37383
37415
  const component_compare_1 = __webpack_require__(/*! ../expressions/component_compare */ "../core/build/src/abap/5_syntax/expressions/component_compare.js");
37384
37416
  const component_cond_1 = __webpack_require__(/*! ../expressions/component_cond */ "../core/build/src/abap/5_syntax/expressions/component_cond.js");
37385
37417
  const basic_1 = __webpack_require__(/*! ../../types/basic */ "../core/build/src/abap/types/basic/index.js");
37418
+ const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "../core/build/src/abap/5_syntax/_syntax_input.js");
37386
37419
  class DeleteInternal {
37387
37420
  runSyntax(node, input) {
37388
37421
  var _a;
@@ -37393,7 +37426,8 @@ class DeleteInternal {
37393
37426
  const target = node.findDirectExpression(Expressions.Target);
37394
37427
  if (target) {
37395
37428
  let tabl = undefined;
37396
- if (node.getChildren().length === 5 && node.getChildren()[2].concatTokens().toUpperCase() === "FROM") {
37429
+ const localVariable = input.scope.findVariable(target.concatTokens());
37430
+ if (localVariable === undefined && node.getChildren().length === 5 && node.getChildren()[2].concatTokens().toUpperCase() === "FROM") {
37397
37431
  // it might be a database table
37398
37432
  tabl = (_a = input.scope.getDDIC()) === null || _a === void 0 ? void 0 : _a.lookupTableOrView(target.concatTokens());
37399
37433
  if (tabl) {
@@ -37402,6 +37436,14 @@ class DeleteInternal {
37402
37436
  }
37403
37437
  if (tabl === undefined) {
37404
37438
  targetType = target_1.Target.runSyntax(target, input);
37439
+ if (node.findDirectTokenByText("TABLE") === undefined
37440
+ && node.findDirectTokenByText("FROM")
37441
+ && targetType instanceof basic_1.TableType
37442
+ && targetType.getAccessType() === basic_1.TableAccessType.hashed) {
37443
+ const message = "Implicit or explicit index operation on hashed table is not possible";
37444
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
37445
+ return;
37446
+ }
37405
37447
  if (targetType instanceof basic_1.TableType) {
37406
37448
  targetType = targetType.getRowType();
37407
37449
  }
@@ -45846,6 +45888,10 @@ class SyntaxLogic {
45846
45888
  this.scope.addList(values);
45847
45889
  return true;
45848
45890
  }
45891
+ else if (stru instanceof Structures.TestInjection) {
45892
+ // todo: skipped for now
45893
+ return true;
45894
+ }
45849
45895
  return false;
45850
45896
  }
45851
45897
  updateScopeStatement(node) {
@@ -66531,7 +66577,7 @@ class Registry {
66531
66577
  }
66532
66578
  static abaplintVersion() {
66533
66579
  // magic, see build script "version.js"
66534
- return "2.119.37";
66580
+ return "2.119.39";
66535
66581
  }
66536
66582
  getDDICReferences() {
66537
66583
  return this.ddicReferences;
@@ -89398,6 +89444,9 @@ class SelectionScreenTextsMissing {
89398
89444
  key: "selection_screen_texts_missing",
89399
89445
  title: "Selection screen texts missing",
89400
89446
  shortDescription: `Checks that selection screen parameters and select-options have selection texts`,
89447
+ extendedInformation: `Excludes parameters and select-options that:
89448
+ * are inside a "SELECTION-SCREEN BEGIN OF LINE" block
89449
+ * have the addition "NO-DISPLAY"`,
89401
89450
  };
89402
89451
  }
89403
89452
  getConfig() {
@@ -89423,7 +89472,7 @@ class SelectionScreenTextsMissing {
89423
89472
  this.checkFile(obj.getMainABAPFile(), selTexts, output, checked);
89424
89473
  return output;
89425
89474
  }
89426
- checkFile(file, selTexts, output, checked) {
89475
+ checkFile(file, selTexts, output, checked, mainProgName = undefined) {
89427
89476
  if (file === undefined) {
89428
89477
  return;
89429
89478
  }
@@ -89431,26 +89480,44 @@ class SelectionScreenTextsMissing {
89431
89480
  return;
89432
89481
  }
89433
89482
  checked.add(file.getFilename());
89483
+ let inLine = false;
89434
89484
  for (const stat of file.getStatements()) {
89435
89485
  const s = stat.get();
89436
- if (s instanceof statements_1.Parameter || s instanceof statements_1.SelectOption) {
89437
- const fieldNode = stat.findFirstExpression(expressions_1.FieldSub);
89438
- if (fieldNode) {
89439
- const fieldName = fieldNode.getFirstToken().getStr().toUpperCase();
89440
- if (selTexts[fieldName] === undefined) {
89441
- output.push(issue_1.Issue.atToken(file, fieldNode.getFirstToken(), `Selection text missing for "${fieldName}"`, this.getMetadata().key, this.conf.severity));
89442
- }
89486
+ if (s instanceof statements_1.SelectionScreen) {
89487
+ const tokens = stat.concatTokens().toUpperCase();
89488
+ if (tokens.includes("BEGIN OF LINE")) {
89489
+ inLine = true;
89443
89490
  }
89491
+ else if (tokens.includes("END OF LINE")) {
89492
+ // known issue: doesn't support BEGIN and END OF LINE span across several includes (not seen a lot in the wild)
89493
+ inLine = false;
89494
+ }
89495
+ continue;
89444
89496
  }
89445
- else if (s instanceof statements_1.Include) {
89497
+ if (s instanceof statements_1.Include) {
89446
89498
  const nameNode = stat.findFirstExpression(expressions_1.IncludeName);
89447
89499
  if (nameNode) {
89448
89500
  const inclName = nameNode.getFirstToken().getStr().toUpperCase();
89449
89501
  const inclObj = this.reg.getObject("PROG", inclName);
89450
89502
  if (inclObj) {
89451
- this.checkFile(inclObj.getMainABAPFile(), selTexts, output, checked);
89503
+ this.checkFile(inclObj.getMainABAPFile(), selTexts, output, checked, mainProgName !== null && mainProgName !== void 0 ? mainProgName : file.getFilename());
89452
89504
  }
89453
89505
  }
89506
+ continue;
89507
+ }
89508
+ if (inLine || !(s instanceof statements_1.Parameter || s instanceof statements_1.SelectOption)) {
89509
+ continue;
89510
+ }
89511
+ if (stat.concatTokens().toUpperCase().includes("NO-DISPLAY")) {
89512
+ continue;
89513
+ }
89514
+ const fieldNode = stat.findFirstExpression(expressions_1.FieldSub);
89515
+ if (fieldNode) {
89516
+ const fieldName = fieldNode.getFirstToken().getStr().toUpperCase();
89517
+ if (selTexts[fieldName] === undefined) {
89518
+ const suffix = mainProgName ? `, ${mainProgName}` : ``;
89519
+ output.push(issue_1.Issue.atToken(file, fieldNode.getFirstToken(), `Selection text missing for "${fieldName}"${suffix}`, this.getMetadata().key, this.conf.severity));
89520
+ }
89454
89521
  }
89455
89522
  }
89456
89523
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/cli",
3
- "version": "2.119.37",
3
+ "version": "2.119.39",
4
4
  "description": "abaplint - Command Line Interface",
5
5
  "funding": "https://github.com/sponsors/larshp",
6
6
  "bin": {
@@ -38,7 +38,7 @@
38
38
  },
39
39
  "homepage": "https://abaplint.org",
40
40
  "devDependencies": {
41
- "@abaplint/core": "^2.119.37",
41
+ "@abaplint/core": "^2.119.39",
42
42
  "@types/chai": "^4.3.20",
43
43
  "@types/minimist": "^1.2.5",
44
44
  "@types/mocha": "^10.0.10",