@abaplint/cli 2.115.2 → 2.115.4

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 +116 -22
  2. package/package.json +2 -2
package/build/cli.js CHANGED
@@ -11974,7 +11974,7 @@ const combi_1 = __webpack_require__(/*! ../combi */ "./node_modules/@abaplint/co
11974
11974
  const expressions_1 = __webpack_require__(/*! ../expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js");
11975
11975
  class DataBegin {
11976
11976
  getMatcher() {
11977
- const occurs = (0, combi_1.seq)("OCCURS", expressions_1.Integer);
11977
+ const occurs = (0, combi_1.seq)("OCCURS", (0, combi_1.altPrio)(expressions_1.Integer, expressions_1.FieldChain));
11978
11978
  const common = (0, combi_1.seq)("COMMON PART", (0, combi_1.optPrio)(expressions_1.DefinitionName));
11979
11979
  const structure = (0, combi_1.seq)("BEGIN OF", (0, combi_1.altPrio)(common, (0, combi_1.seq)(expressions_1.DefinitionName, (0, combi_1.optPrio)("READ-ONLY"), (0, combi_1.optPrio)(occurs))));
11980
11980
  return (0, combi_1.seq)("DATA", structure);
@@ -18678,7 +18678,8 @@ class Write {
18678
18678
  const as = (0, combi_1.seq)("AS", (0, combi_1.altPrio)("LINE", "ICON", "CHECKBOX", "SYMBOL"));
18679
18679
  const to = (0, combi_1.seq)("TO", expressions_1.Target);
18680
18680
  const options = (0, combi_1.per)(mask, to, (0, combi_1.seq)("EXPONENT", expressions_1.Source), "NO-GROUPING", "NO-ZERO", "CENTERED", (0, combi_1.seq)("INPUT", (0, combi_1.opt)(onOff)), "NO-GAP", "LEFT-JUSTIFIED", as, (0, combi_1.seq)("FRAMES", onOff), (0, combi_1.seq)("HOTSPOT", (0, combi_1.opt)(onOff)), "RIGHT-JUSTIFIED", (0, combi_1.seq)("TIME ZONE", expressions_1.Source), (0, combi_1.seq)("UNDER", expressions_1.Source), (0, combi_1.seq)("STYLE", expressions_1.Source), (0, combi_1.seq)("ROUND", expressions_1.Source), (0, combi_1.seq)("QUICKINFO", expressions_1.Source), "ENVIRONMENT TIME FORMAT", dateFormat, (0, combi_1.seq)("UNIT", expressions_1.Source), (0, combi_1.seq)("INTENSIFIED", (0, combi_1.opt)(onOff)), (0, combi_1.seq)("INDEX", expressions_1.Source), (0, combi_1.seq)("DECIMALS", expressions_1.Source), (0, combi_1.seq)("INVERSE", (0, combi_1.opt)(onOff)), expressions_1.Color, (0, combi_1.seq)("CURRENCY", expressions_1.Source), "RESET", "NO-SIGN");
18681
- const ret = (0, combi_1.seq)("WRITE", (0, combi_1.alt)("AT /", (0, combi_1.seq)((0, combi_1.opt)(expressions_1.WriteOffsetLength), (0, combi_1.alt)(expressions_1.Source, expressions_1.Dynamic, "/"), (0, combi_1.opt)(options))));
18681
+ // Need to refactor all this sometime,
18682
+ const ret = (0, combi_1.seq)("WRITE", (0, combi_1.alt)((0, combi_1.seq)("AT /", (0, combi_1.opt)(expressions_1.Source), (0, combi_1.opt)("NO-GAP")), (0, combi_1.seq)((0, combi_1.opt)(expressions_1.WriteOffsetLength), (0, combi_1.alt)(expressions_1.Source, expressions_1.Dynamic, "/"), (0, combi_1.opt)(options))));
18682
18683
  return (0, combi_1.verNot)(version_1.Version.Cloud, ret);
18683
18684
  }
18684
18685
  }
@@ -32881,13 +32882,18 @@ class InsertInternal {
32881
32882
  }
32882
32883
  }
32883
32884
  if (node.findDirectTokenByText("INITIAL") === undefined) {
32884
- if (new _type_utils_1.TypeUtils(input.scope).isAssignableStrict(sourceType, targetType) === false) {
32885
- const message = "Types not compatible";
32886
- input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
32887
- return;
32885
+ let error = false;
32886
+ if (sourceType instanceof basic_1.IntegerType && targetType instanceof basic_1.Integer8Type) {
32887
+ error = true;
32888
+ }
32889
+ else if (new _type_utils_1.TypeUtils(input.scope).isAssignable(sourceType, targetType) === false) {
32890
+ error = true;
32888
32891
  }
32889
32892
  else if (sourceType instanceof basic_1.CharacterType && targetType instanceof basic_1.StringType) {
32890
32893
  // yea, well, INSERT doesnt convert the values automatically, like everything else?
32894
+ error = true;
32895
+ }
32896
+ if (error === true) {
32891
32897
  const message = "Types not compatible";
32892
32898
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
32893
32899
  return;
@@ -42628,8 +42634,22 @@ class DDIC {
42628
42634
  case "XSTRING":
42629
42635
  return Types.XStringType.get({ qualifiedName: qualifiedName || name });
42630
42636
  case "D":
42637
+ /*
42638
+ if (length && length > 0) {
42639
+ throw new Error("Length for type D not possible");
42640
+ } else if (decimals && decimals > 0) {
42641
+ throw new Error("Decimals for type D not possible");
42642
+ }
42643
+ */
42631
42644
  return new Types.DateType({ qualifiedName: qualifiedName || name });
42632
42645
  case "T":
42646
+ /*
42647
+ if (length && length > 0) {
42648
+ throw new Error("Length for type T not possible");
42649
+ } else if (decimals && decimals > 0) {
42650
+ throw new Error("Decimals for type T not possible");
42651
+ }
42652
+ */
42633
42653
  return new Types.TimeType({ qualifiedName: qualifiedName || name });
42634
42654
  case "XSEQUENCE":
42635
42655
  return new Types.XSequenceType({ qualifiedName: qualifiedName });
@@ -42662,6 +42682,13 @@ class DDIC {
42662
42682
  case "INT8": // todo, take version into account
42663
42683
  return new Types.Integer8Type({ qualifiedName: qualifiedName || name });
42664
42684
  case "F":
42685
+ /*
42686
+ if (length && length > 0) {
42687
+ throw new Error("Length for type F not possible");
42688
+ } else if (decimals && decimals > 0) {
42689
+ throw new Error("Decimals for type F not possible");
42690
+ }
42691
+ */
42665
42692
  return new Types.FloatType({ qualifiedName: qualifiedName || name });
42666
42693
  case "P":
42667
42694
  if (length && decimals) {
@@ -52499,15 +52526,39 @@ class RenameICFService {
52499
52526
  this.reg = reg;
52500
52527
  }
52501
52528
  buildEdits(obj, oldName, newName) {
52529
+ var _a, _b, _c, _d;
52502
52530
  if (!(obj instanceof __1.ICFService)) {
52503
52531
  throw new Error("RenameICFService, not a ICF Service");
52504
52532
  }
52533
+ // Preserve GUID suffix from the stored object/file name for the filename rename
52534
+ // SICF files follow pattern: servicename.sicf or servicename {GUID}.sicf
52535
+ const fileNewName = (() => {
52536
+ // Look for pattern: space + GUID (32 hex chars in braces) + optional extension
52537
+ const guidPattern = / \{[0-9A-Fa-f]{16,32}\}/;
52538
+ const match = oldName.match(guidPattern);
52539
+ if (match) {
52540
+ // Extract everything from the GUID onwards (includes .sicf extension if present)
52541
+ const guidIndex = match.index;
52542
+ const suffix = oldName.substring(guidIndex);
52543
+ // Only append suffix if newName doesn't already contain it
52544
+ return newName.includes(suffix) ? newName : newName + suffix;
52545
+ }
52546
+ // Fallback: preserve any suffix after first space (legacy behavior)
52547
+ const space = oldName.indexOf(" ");
52548
+ if (space > -1) {
52549
+ const suffix = oldName.substring(space);
52550
+ return newName.includes(suffix) ? newName : newName + suffix;
52551
+ }
52552
+ return newName;
52553
+ })();
52554
+ const cleanOldName = (_b = (_a = oldName.match(/^[^ ]+/)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : oldName;
52555
+ const cleanNewName = (_d = (_c = newName.match(/^[^ ]+/)) === null || _c === void 0 ? void 0 : _c[0]) !== null && _d !== void 0 ? _d : newName;
52505
52556
  let changes = [];
52506
52557
  const helper = new renamer_helper_1.RenamerHelper(this.reg);
52507
- changes = changes.concat(helper.buildXMLFileEdits(obj, "URL", oldName, newName, true));
52508
- changes = changes.concat(helper.buildXMLFileEdits(obj, "ICF_NAME", oldName, newName));
52509
- changes = changes.concat(helper.buildXMLFileEdits(obj, "ORIG_NAME", oldName, newName, true));
52510
- changes = changes.concat(helper.renameFiles(obj, oldName, newName));
52558
+ changes = changes.concat(helper.buildURLFileEdits(obj, cleanOldName, cleanNewName));
52559
+ changes = changes.concat(helper.buildXMLFileEdits(obj, "ICF_NAME", cleanOldName, cleanNewName));
52560
+ changes = changes.concat(helper.buildXMLFileEdits(obj, "ORIG_NAME", cleanOldName, cleanNewName, true));
52561
+ changes = changes.concat(helper.renameFiles(obj, oldName, fileNewName));
52511
52562
  return {
52512
52563
  documentChanges: changes,
52513
52564
  };
@@ -52684,7 +52735,10 @@ class Renamer {
52684
52735
  /** Builds edits, but does not apply to registry, used by LSP */
52685
52736
  buildEdits(type, oldName, newName) {
52686
52737
  this.reg.parse(); // the registry must be parsed to dermine references
52687
- const obj = this.reg.getObject(type, oldName);
52738
+ let obj = this.reg.getObject(type, oldName);
52739
+ if (obj === undefined && type === "SICF") {
52740
+ obj = Array.from(this.reg.getObjects()).find(o => o.getType() === "SICF" && o.getName().toUpperCase().startsWith(oldName.toUpperCase() + " "));
52741
+ }
52688
52742
  if (obj === undefined) {
52689
52743
  throw new Error("rename, object not found");
52690
52744
  }
@@ -52913,6 +52967,34 @@ class RenamerHelper {
52913
52967
  }
52914
52968
  return changes;
52915
52969
  }
52970
+ buildURLFileEdits(object, oldName, newName) {
52971
+ const changes = [];
52972
+ const xml = object.getXMLFile();
52973
+ if (xml === undefined) {
52974
+ return [];
52975
+ }
52976
+ const oldNameLower = oldName.toLowerCase();
52977
+ const newNameLower = newName.toLowerCase();
52978
+ const rows = xml.getRawRows();
52979
+ for (let i = 0; i < rows.length; i++) {
52980
+ const row = rows[i];
52981
+ const urlTagStart = row.indexOf("<URL>");
52982
+ if (urlTagStart === -1) {
52983
+ continue;
52984
+ }
52985
+ const urlTagEnd = row.indexOf("</URL>");
52986
+ if (urlTagEnd === -1) {
52987
+ continue;
52988
+ }
52989
+ const urlContent = row.substring(urlTagStart + 5, urlTagEnd);
52990
+ const updatedUrl = urlContent.replace(oldNameLower, newNameLower);
52991
+ if (updatedUrl !== urlContent) {
52992
+ const range = vscode_languageserver_types_1.Range.create(i, urlTagStart + 5, i, urlTagEnd);
52993
+ changes.push(vscode_languageserver_types_1.TextDocumentEdit.create({ uri: xml.getFilename(), version: 1 }, [vscode_languageserver_types_1.TextEdit.replace(range, updatedUrl)]));
52994
+ }
52995
+ }
52996
+ return changes;
52997
+ }
52916
52998
  renameFiles(obj, oldName, name) {
52917
52999
  const list = [];
52918
53000
  const newName = name.toLowerCase().replace(/\//g, "#");
@@ -55155,7 +55237,7 @@ class Registry {
55155
55237
  }
55156
55238
  static abaplintVersion() {
55157
55239
  // magic, see build script "version.sh"
55158
- return "2.115.2";
55240
+ return "2.115.4";
55159
55241
  }
55160
55242
  getDDICReferences() {
55161
55243
  return this.ddicReferences;
@@ -68388,7 +68470,7 @@ ENDIF.
68388
68470
  return [];
68389
68471
  }
68390
68472
  for (const cond of structure.findAllExpressionsMulti([Expressions.Cond, Expressions.ComponentCond])) {
68391
- issues.push(...this.analyze(file, cond));
68473
+ issues.push(...this.analyzeCondition(file, cond));
68392
68474
  }
68393
68475
  for (const sub of structure.findAllExpressionsMulti([Expressions.CondSub, Expressions.ComponentCondSub])) {
68394
68476
  let cond = [];
@@ -68442,18 +68524,20 @@ ENDIF.
68442
68524
  }
68443
68525
  analyzeMove(file, m) {
68444
68526
  const issues = [];
68445
- const children = m.getChildren();
68446
- const last = children[children.length - 2];
68447
- const lastChildren = last.getChildren();
68448
- if (lastChildren.length === 3
68449
- && lastChildren[0].getFirstToken().getStr() === "("
68450
- && lastChildren[2].getFirstToken().getStr() === ")") {
68451
- const issue = issue_1.Issue.atToken(file, last.getFirstToken(), "Too many parentheses", this.getMetadata().key, this.conf.severity);
68452
- issues.push(issue);
68527
+ for (const source of m.findAllExpressionsRecursive(Expressions.Source)) {
68528
+ const lastChildren = source.getChildren();
68529
+ if (lastChildren.length === 3
68530
+ && lastChildren[0].getFirstToken().getStr() === "("
68531
+ && lastChildren[1].getChildren().length === 1
68532
+ && lastChildren[1].getFirstToken().getStr().startsWith("-") === false
68533
+ && lastChildren[2].getFirstToken().getStr() === ")") {
68534
+ const issue = issue_1.Issue.atToken(file, lastChildren[0].getFirstToken(), "Too many parentheses", this.getMetadata().key, this.conf.severity);
68535
+ issues.push(issue);
68536
+ }
68453
68537
  }
68454
68538
  return issues;
68455
68539
  }
68456
- analyze(file, cond) {
68540
+ analyzeCondition(file, cond) {
68457
68541
  var _a, _b;
68458
68542
  const issues = [];
68459
68543
  let comparator = "";
@@ -70910,6 +70994,8 @@ class ObsoleteStatementConf extends _basic_rule_config_1.BasicRuleConfig {
70910
70994
  this.fieldGroups = true;
70911
70995
  /** Check for REPLACE INTO */
70912
70996
  this.replaceInto = true;
70997
+ this.loopExtract = true;
70998
+ this.sortExtract = true;
70913
70999
  }
70914
71000
  }
70915
71001
  exports.ObsoleteStatementConf = ObsoleteStatementConf;
@@ -71163,6 +71249,14 @@ ENDIF.`,
71163
71249
  issues.push(issue);
71164
71250
  }
71165
71251
  }
71252
+ if (this.conf.loopExtract && sta instanceof Statements.LoopExtract) {
71253
+ const issue = issue_1.Issue.atStatement(file, staNode, "LOOP extract", this.getMetadata().key, this.conf.severity);
71254
+ issues.push(issue);
71255
+ }
71256
+ if (this.conf.sortExtract && sta instanceof Statements.SortDataset && staNode.getChildren().length === 2) {
71257
+ const issue = issue_1.Issue.atStatement(file, staNode, "SORT extract", this.getMetadata().key, this.conf.severity);
71258
+ issues.push(issue);
71259
+ }
71166
71260
  if (configVersion >= version_1.Version.v754 && this.conf.clientSpecified
71167
71261
  && (sta instanceof Statements.Select
71168
71262
  || sta instanceof Statements.SelectLoop
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/cli",
3
- "version": "2.115.2",
3
+ "version": "2.115.4",
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.115.2",
41
+ "@abaplint/core": "^2.115.4",
42
42
  "@types/chai": "^4.3.20",
43
43
  "@types/minimist": "^1.2.5",
44
44
  "@types/mocha": "^10.0.10",