@abaplint/cli 2.120.45 → 2.120.47

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 +139 -6
  2. package/package.json +2 -2
package/build/cli.js CHANGED
@@ -31834,6 +31834,17 @@ var __importStar = (this && this.__importStar) || (function () {
31834
31834
  return result;
31835
31835
  };
31836
31836
  })();
31837
+ var __rest = (this && this.__rest) || function (s, e) {
31838
+ var t = {};
31839
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
31840
+ t[p] = s[p];
31841
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
31842
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
31843
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
31844
+ t[p[i]] = s[p[i]];
31845
+ }
31846
+ return t;
31847
+ };
31837
31848
  Object.defineProperty(exports, "__esModule", ({ value: true }));
31838
31849
  exports.InlineData = void 0;
31839
31850
  const Expressions = __importStar(__webpack_require__(/*! ../../2_statements/expressions */ "../core/build/src/abap/2_statements/expressions/index.js"));
@@ -31866,7 +31877,7 @@ class InlineData {
31866
31877
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
31867
31878
  type = basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
31868
31879
  }
31869
- const identifier = new _typed_identifier_1.TypedIdentifier(token, input.filename, type, ["inline" /* IdentifierMeta.InlineDefinition */]);
31880
+ const identifier = new _typed_identifier_1.TypedIdentifier(token, input.filename, this.stripDerivedFromConstant(type), ["inline" /* IdentifierMeta.InlineDefinition */]);
31870
31881
  input.scope.addIdentifier(identifier);
31871
31882
  input.scope.addReference(token, identifier, _reference_1.ReferenceType.DataWriteReference, input.filename);
31872
31883
  }
@@ -31877,6 +31888,26 @@ class InlineData {
31877
31888
  input.scope.addReference(token, identifier, _reference_1.ReferenceType.DataWriteReference, input.filename);
31878
31889
  }
31879
31890
  }
31891
+ // The inferred type is taken from the source expression, which might be a literal.
31892
+ // The variable itself is not a constant, so the relaxations that apply to literals
31893
+ // must not be inherited, eg. a "c" variable is not assignable to a "string" parameter
31894
+ static stripDerivedFromConstant(type) {
31895
+ const data = type.getAbstractTypeData();
31896
+ if ((data === null || data === void 0 ? void 0 : data.derivedFromConstant) !== true) {
31897
+ return type;
31898
+ }
31899
+ const { derivedFromConstant } = data, rest = __rest(data, ["derivedFromConstant"]);
31900
+ if (type instanceof basic_1.CharacterType) {
31901
+ return new basic_1.CharacterType(type.getLength(), rest);
31902
+ }
31903
+ else if (type instanceof basic_1.IntegerType) {
31904
+ return basic_1.IntegerType.get(rest);
31905
+ }
31906
+ else if (type instanceof basic_1.StringType) {
31907
+ return basic_1.StringType.get(rest);
31908
+ }
31909
+ return type;
31910
+ }
31880
31911
  }
31881
31912
  exports.InlineData = InlineData;
31882
31913
  //# sourceMappingURL=inline_data.js.map
@@ -41565,17 +41596,35 @@ const Expressions = __importStar(__webpack_require__(/*! ../../2_statements/expr
41565
41596
  const inline_data_1 = __webpack_require__(/*! ../expressions/inline_data */ "../core/build/src/abap/5_syntax/expressions/inline_data.js");
41566
41597
  const basic_1 = __webpack_require__(/*! ../../types/basic */ "../core/build/src/abap/types/basic/index.js");
41567
41598
  const target_1 = __webpack_require__(/*! ../expressions/target */ "../core/build/src/abap/5_syntax/expressions/target.js");
41599
+ const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "../core/build/src/abap/5_syntax/_syntax_input.js");
41568
41600
  class GetTime {
41569
41601
  runSyntax(node, input) {
41570
41602
  const target = node.findDirectExpression(Expressions.Target);
41603
+ const stamp = node.findDirectTokenByText("STAMP") !== undefined;
41571
41604
  const inline = target === null || target === void 0 ? void 0 : target.findDirectExpression(Expressions.InlineData);
41572
41605
  if (inline) {
41573
41606
  inline_data_1.InlineData.runSyntax(inline, input, new basic_1.PackedType(8, 0));
41574
41607
  }
41575
41608
  else if (target) {
41576
- target_1.Target.runSyntax(target, input);
41609
+ const type = target_1.Target.runSyntax(target, input);
41610
+ if (stamp === true && this.compatibleTimeStamp(type) === false) {
41611
+ const message = "GET TIME STAMP FIELD, target type not compatible";
41612
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
41613
+ return;
41614
+ }
41577
41615
  }
41578
41616
  }
41617
+ // the target must be a timestamp, ie. packed(timestamp and timestampl) or utclong
41618
+ compatibleTimeStamp(type) {
41619
+ return type === undefined
41620
+ || type instanceof basic_1.PackedType
41621
+ || type instanceof basic_1.UTCLongType
41622
+ || type instanceof basic_1.VoidType
41623
+ || type instanceof basic_1.AnyType
41624
+ || type instanceof basic_1.DataType
41625
+ || type instanceof basic_1.UnknownType
41626
+ || type.isGeneric();
41627
+ }
41579
41628
  }
41580
41629
  exports.GetTime = GetTime;
41581
41630
  //# sourceMappingURL=get_time.js.map
@@ -70343,7 +70392,7 @@ class Registry {
70343
70392
  }
70344
70393
  static abaplintVersion() {
70345
70394
  // magic, see build script "version.js"
70346
- return "2.120.45";
70395
+ return "2.120.47";
70347
70396
  }
70348
70397
  getDDICReferences() {
70349
70398
  return this.ddicReferences;
@@ -71974,7 +72023,7 @@ class AllowedObjectNaming {
71974
72023
  key: "allowed_object_naming",
71975
72024
  title: "Allowed object naming",
71976
72025
  shortDescription: `Enforces basic name length and namespace restrictions, see note SAP 104010`,
71977
- tags: [_irule_1.RuleTag.Naming, _irule_1.RuleTag.SingleFile],
72026
+ tags: [_irule_1.RuleTag.Naming, _irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Syntax],
71978
72027
  };
71979
72028
  }
71980
72029
  initialize(_reg) {
@@ -77831,6 +77880,10 @@ Make sure to test the downported code, it might not always be completely correct
77831
77880
  if (found) {
77832
77881
  return found;
77833
77882
  }
77883
+ found = this.outlineTableExpressionKeyBuiltin(low, high, lowFile, highSyntax);
77884
+ if (found) {
77885
+ return found;
77886
+ }
77834
77887
  found = this.assignWithTable(low, high, lowFile);
77835
77888
  if (found) {
77836
77889
  return found;
@@ -78528,6 +78581,69 @@ ${indentation}`);
78528
78581
  }
78529
78582
  return condition;
78530
78583
  }
78584
+ /** A built-in function is only recognized as one in an operand position that admits an
78585
+ * expression, and "WITH KEY comp = ..." does not become such a position until v740. The
78586
+ * table expression rewrites carry the key operand over verbatim, so
78587
+ * "tab[ comp = to_upper( x ) ]" downports to a READ TABLE that a 702 or 731 compiler can
78588
+ * only read as a functional method call - "method TO_UPPER is unknown", reported as a
78589
+ * SYNTAX_ERROR of the whole class pool. Hoist the call into a variable first, an
78590
+ * assignment IS an expression position at 702.
78591
+ *
78592
+ * Built-ins that predate 702 (lines, strlen, numofchar, ...) carry no release in
78593
+ * BuiltIn.methods; they are accepted in the operand as they are and stay untouched. So do
78594
+ * functional method calls, which are exactly the reading that makes the built-in fail, and
78595
+ * the INDEX operand of "tab[ 1 ]", which is not a key operand. */
78596
+ outlineTableExpressionKeyBuiltin(low, high, lowFile, highSyntax) {
78597
+ if (!(low.get() instanceof _statement_1.Unknown)) {
78598
+ return undefined;
78599
+ }
78600
+ for (const tableExpression of high.findAllExpressionsRecursive(Expressions.TableExpression)) {
78601
+ let afterComponent = false;
78602
+ for (const child of tableExpression.getChildren()) {
78603
+ if (child.get() instanceof Expressions.ComponentChainSimple) {
78604
+ afterComponent = true;
78605
+ continue;
78606
+ }
78607
+ else if (afterComponent === false
78608
+ || !(child.get() instanceof Expressions.Source)
78609
+ || !(child instanceof nodes_1.ExpressionNode)) {
78610
+ continue;
78611
+ }
78612
+ const type = this.builtinReturnType(child, lowFile, highSyntax);
78613
+ if (type === undefined) {
78614
+ continue;
78615
+ }
78616
+ const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
78617
+ const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
78618
+ const code = `DATA ${uniqueName} TYPE ${type}.\n` +
78619
+ indentation + `${uniqueName} = ${child.concatTokens()}.\n` +
78620
+ indentation;
78621
+ const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getFirstToken().getStart(), code);
78622
+ const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, child.getFirstToken().getStart(), child.getLastToken().getEnd(), uniqueName);
78623
+ const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
78624
+ return issue_1.Issue.atToken(lowFile, child.getFirstToken(), "Outline built-in function in table expression key", this.getMetadata().key, this.conf.severity, fix);
78625
+ }
78626
+ }
78627
+ return undefined;
78628
+ }
78629
+ /** the ABAP type returned by the built-in function this Source starts with, or undefined
78630
+ * if it does not start with one, or with one that predates 702 */
78631
+ builtinReturnType(source, lowFile, highSyntax) {
78632
+ var _a, _b, _c;
78633
+ const spag = highSyntax.spaghetti.lookupPosition(source.getFirstToken().getStart(), lowFile.getFilename());
78634
+ for (const r of (spag === null || spag === void 0 ? void 0 : spag.getData().references) || []) {
78635
+ if (r.referenceType !== _reference_1.ReferenceType.BuiltinMethodReference
78636
+ || r.position.getStart().equals(source.getFirstToken().getStart()) === false) {
78637
+ continue;
78638
+ }
78639
+ const name = r.position.getName().toUpperCase();
78640
+ if (((_a = _builtin_1.BuiltIn.methods[name]) === null || _a === void 0 ? void 0 : _a.release) === undefined) {
78641
+ return undefined;
78642
+ }
78643
+ return (_c = (_b = _builtin_1.BuiltIn.searchBuiltin(name)) === null || _b === void 0 ? void 0 : _b.getParameters().getReturning()) === null || _c === void 0 ? void 0 : _c.getType().toABAP();
78644
+ }
78645
+ return undefined;
78646
+ }
78531
78647
  outlineCatchSimple(node, lowFile) {
78532
78648
  // outlines "CATCH cx_bcs INTO DATA(lx_bcs_excep).", note that this does not need to look at types
78533
78649
  var _a, _b;
@@ -80138,9 +80254,13 @@ ${indentation} output = ${uniqueName}.\n`;
80138
80254
  continue;
80139
80255
  }
80140
80256
  const uniqueName = this.uniqueName(i.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
80141
- const type = this.findType(i, lowFile, highSyntax);
80142
80257
  const indent = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
80143
- const abap = `DATA ${uniqueName} TYPE ${type}.\n` +
80258
+ // the CONV type might just be a component of the row type, so prefer the row type
80259
+ const rowOf = this.findRowTypeOf(high, i);
80260
+ const declaration = rowOf === undefined
80261
+ ? `DATA ${uniqueName} TYPE ${this.findType(i, lowFile, highSyntax)}.`
80262
+ : `DATA ${uniqueName} LIKE LINE OF ${rowOf}.`;
80263
+ const abap = declaration + "\n" +
80144
80264
  indent + `${uniqueName} = ${body}.\n` +
80145
80265
  indent;
80146
80266
  const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getFirstToken().getStart(), abap);
@@ -80150,6 +80270,19 @@ ${indentation} output = ${uniqueName}.\n`;
80150
80270
  }
80151
80271
  return undefined;
80152
80272
  }
80273
+ /** if the source expression is the complete source of an INSERT or APPEND statement, then the
80274
+ * outlined variable must be typed via the row type of the table, returns the table name */
80275
+ findRowTypeOf(high, source) {
80276
+ var _a;
80277
+ if (!(high.get() instanceof Statements.InsertInternal)
80278
+ && !(high.get() instanceof Statements.Append)) {
80279
+ return undefined;
80280
+ }
80281
+ else if (high.getChildren()[1] !== source) {
80282
+ return undefined;
80283
+ }
80284
+ return (_a = high.findDirectExpression(Expressions.Target)) === null || _a === void 0 ? void 0 : _a.concatTokens();
80285
+ }
80153
80286
  // "CAST" to "?="
80154
80287
  outlineCast(low, high, lowFile, highSyntax) {
80155
80288
  var _a;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/cli",
3
- "version": "2.120.45",
3
+ "version": "2.120.47",
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.45",
42
+ "@abaplint/core": "^2.120.47",
43
43
  "@types/chai": "^4.3.20",
44
44
  "@types/minimist": "^1.2.5",
45
45
  "@types/mocha": "^10.0.10",