@abaplint/transpiler-cli 2.14.13 → 2.14.15

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 +367 -13
  2. package/package.json +3 -3
package/build/bundle.js CHANGED
@@ -33291,6 +33291,7 @@ class FieldChain {
33291
33291
  const children = node.getChildren();
33292
33292
  context = this.findTop(children[0], input, refType);
33293
33293
  let prev = children[0].concatTokens();
33294
+ let afterTableExpression = false;
33294
33295
  for (let i = 1; i < children.length; i++) {
33295
33296
  const current = children[i];
33296
33297
  if (current === undefined) {
@@ -33338,6 +33339,9 @@ class FieldChain {
33338
33339
  }
33339
33340
  }
33340
33341
  else if (current.get() instanceof tokens_1.InstanceArrow) {
33342
+ if (afterTableExpression && table_expression_1.TableExpression.checkArrowAfter(input, current.getFirstToken())) {
33343
+ return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
33344
+ }
33341
33345
  if (!(context instanceof basic_1.ObjectReferenceType)
33342
33346
  && !(context instanceof basic_1.DataReference)
33343
33347
  && !(context instanceof basic_1.VoidType)) {
@@ -33370,6 +33374,7 @@ class FieldChain {
33370
33374
  return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
33371
33375
  }
33372
33376
  table_expression_1.TableExpression.runSyntax(current, input, context);
33377
+ afterTableExpression = true;
33373
33378
  if (!(context instanceof basic_1.VoidType) && !(context instanceof basic_1.UnknownType)) {
33374
33379
  context = context.getRowType();
33375
33380
  }
@@ -34725,6 +34730,7 @@ const method_call_param_1 = __webpack_require__(/*! ./method_call_param */ "./no
34725
34730
  const _reference_1 = __webpack_require__(/*! ../_reference */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_reference.js");
34726
34731
  const component_name_1 = __webpack_require__(/*! ./component_name */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/component_name.js");
34727
34732
  const attribute_name_1 = __webpack_require__(/*! ./attribute_name */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/attribute_name.js");
34733
+ const table_expression_1 = __webpack_require__(/*! ./table_expression */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/table_expression.js");
34728
34734
  const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
34729
34735
  class MethodCallChain {
34730
34736
  static runSyntax(node, input, targetType) {
@@ -34737,6 +34743,13 @@ class MethodCallChain {
34737
34743
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
34738
34744
  return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
34739
34745
  }
34746
+ // the field chain is followed by "->", eg. "itab[ 1 ]-ref->meth( )"
34747
+ if (first instanceof nodes_1.ExpressionNode
34748
+ && first.get() instanceof Expressions.FieldChain
34749
+ && first.findDirectExpression(Expressions.TableExpression) !== undefined
34750
+ && table_expression_1.TableExpression.checkArrowAfter(input, children[1].getFirstToken())) {
34751
+ return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
34752
+ }
34740
34753
  let currentIndex = 1;
34741
34754
  let context = this.findTop(first, input, targetType);
34742
34755
  if (first.get() instanceof Expressions.MethodCall) {
@@ -35883,6 +35896,8 @@ class NewObject {
35883
35896
  }
35884
35897
  }
35885
35898
  else if (typeName === "#" && targetType) {
35899
+ const tid = new _typed_identifier_1.TypedIdentifier(typeToken, input.filename, targetType);
35900
+ input.scope.addReference(typeToken, tid, _reference_1.ReferenceType.InferredType, input.filename);
35886
35901
  ret = targetType;
35887
35902
  }
35888
35903
  else if (typeName === "#") {
@@ -38146,9 +38161,23 @@ exports.TableExpression = void 0;
38146
38161
  const nodes_1 = __webpack_require__(/*! ../../nodes */ "./node_modules/@abaplint/core/build/src/abap/nodes/index.js");
38147
38162
  const Expressions = __importStar(__webpack_require__(/*! ../../2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js"));
38148
38163
  const source_1 = __webpack_require__(/*! ./source */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/source.js");
38164
+ const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
38149
38165
  const basic_1 = __webpack_require__(/*! ../../types/basic */ "./node_modules/@abaplint/core/build/src/abap/types/basic/index.js");
38150
38166
  const component_chain_1 = __webpack_require__(/*! ./component_chain */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/component_chain.js");
38167
+ const version_1 = __webpack_require__(/*! ../../../version */ "./node_modules/@abaplint/core/build/src/version.js");
38151
38168
  class TableExpression {
38169
+ /** below v750 the object component selector "->" cannot follow a table expression, eg. "itab[ 1 ]-ref->meth( )",
38170
+ * returns true and adds an issue if not allowed */
38171
+ static checkArrowAfter(input, arrow) {
38172
+ if ((0, version_1.releaseAtLeast)(input.scope.getRelease(), version_1.Release.v750)
38173
+ || input.scope.getLanguageVersion() === version_1.LanguageVersion.Cloud
38174
+ || input.scope.getOpenABAP()) {
38175
+ return false;
38176
+ }
38177
+ const message = "Object component selector \"->\" after table expression not possible below v750";
38178
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, arrow, message));
38179
+ return true;
38180
+ }
38152
38181
  static runSyntax(node, input, rowType) {
38153
38182
  if (node === undefined) {
38154
38183
  return;
@@ -38265,6 +38294,7 @@ class Target {
38265
38294
  return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
38266
38295
  }
38267
38296
  let currentIndex = 1;
38297
+ let afterTableExpression = false;
38268
38298
  while (currentIndex <= children.length) {
38269
38299
  const current = children[currentIndex];
38270
38300
  if (current === undefined) {
@@ -38290,6 +38320,9 @@ class Target {
38290
38320
  }
38291
38321
  }
38292
38322
  else if (current.get() instanceof tokens_1.InstanceArrow) {
38323
+ if (afterTableExpression && table_expression_1.TableExpression.checkArrowAfter(input, current.getFirstToken())) {
38324
+ return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
38325
+ }
38293
38326
  if (!(context instanceof basic_1.ObjectReferenceType)
38294
38327
  && !(context instanceof basic_1.DataReference)
38295
38328
  && !(context instanceof basic_1.VoidType)) {
@@ -38338,6 +38371,7 @@ class Target {
38338
38371
  return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
38339
38372
  }
38340
38373
  table_expression_1.TableExpression.runSyntax(current, input, context);
38374
+ afterTableExpression = true;
38341
38375
  if (!(context instanceof basic_1.VoidType) && !(context instanceof unknown_type_1.UnknownType)) {
38342
38376
  context = context.getRowType();
38343
38377
  }
@@ -66520,8 +66554,12 @@ exports.DataControl = DataControl;
66520
66554
 
66521
66555
  Object.defineProperty(exports, "__esModule", ({ value: true }));
66522
66556
  exports.DataDefinition = void 0;
66557
+ const tokens_1 = __webpack_require__(/*! ../abap/1_lexer/tokens */ "./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/index.js");
66558
+ const combi_1 = __webpack_require__(/*! ../abap/2_statements/combi */ "./node_modules/@abaplint/core/build/src/abap/2_statements/combi.js");
66523
66559
  const nodes_1 = __webpack_require__(/*! ../abap/nodes */ "./node_modules/@abaplint/core/build/src/abap/nodes/index.js");
66524
66560
  const cds_determine_types_1 = __webpack_require__(/*! ../cds/cds_determine_types */ "./node_modules/@abaplint/core/build/src/cds/cds_determine_types.js");
66561
+ const cds_lexer_1 = __webpack_require__(/*! ../cds/cds_lexer */ "./node_modules/@abaplint/core/build/src/cds/cds_lexer.js");
66562
+ const version_1 = __webpack_require__(/*! ../version */ "./node_modules/@abaplint/core/build/src/version.js");
66525
66563
  const cds_parser_1 = __webpack_require__(/*! ../cds/cds_parser */ "./node_modules/@abaplint/core/build/src/cds/cds_parser.js");
66526
66564
  const expressions_1 = __webpack_require__(/*! ../cds/expressions */ "./node_modules/@abaplint/core/build/src/cds/expressions/index.js");
66527
66565
  const _abstract_object_1 = __webpack_require__(/*! ./_abstract_object */ "./node_modules/@abaplint/core/build/src/objects/_abstract_object.js");
@@ -66613,8 +66651,8 @@ class DataDefinition extends _abstract_object_1.AbstractObject {
66613
66651
  associations: [],
66614
66652
  tree: undefined,
66615
66653
  };
66616
- this.findSQLViewName();
66617
66654
  this.parsedData.tree = new cds_parser_1.CDSParser().parse(this.findSourceFile());
66655
+ this.findSQLViewName(this.parsedData.tree);
66618
66656
  if (this.parsedData.tree) {
66619
66657
  for (const c of ((_a = this.parsedData.tree) === null || _a === void 0 ? void 0 : _a.getChildren()) || []) {
66620
66658
  if (c.get() instanceof expressions_1.CDSAnnotation) {
@@ -66639,11 +66677,30 @@ class DataDefinition extends _abstract_object_1.AbstractObject {
66639
66677
  return (_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.tree;
66640
66678
  }
66641
66679
  //////////
66642
- findSQLViewName() {
66680
+ findSQLViewName(tree) {
66643
66681
  var _a;
66644
- const match = (_a = this.findSourceFile()) === null || _a === void 0 ? void 0 : _a.getRaw().match(/@AbapCatalog\.sqlViewName: '([\w/]+)'/);
66645
- if (match) {
66646
- this.parsedData.sqlViewName = match[1].toUpperCase();
66682
+ let annotations = tree === null || tree === void 0 ? void 0 : tree.findDirectExpressions(expressions_1.CDSAnnotation);
66683
+ if (annotations === undefined) {
66684
+ const file = this.findSourceFile();
66685
+ if (file === undefined) {
66686
+ return;
66687
+ }
66688
+ // Keep SQL view lookup available even when the view body cannot be parsed.
66689
+ const tokens = cds_lexer_1.CDSLexer.run(file).filter(t => !(t instanceof tokens_1.Comment));
66690
+ const leadingAnnotations = (0, combi_1.seq)((0, combi_1.starPrio)(expressions_1.CDSAnnotation), (0, combi_1.starPrio)((0, combi_1.regex)(/.*/)));
66691
+ annotations = (_a = combi_1.Combi.run(leadingAnnotations, tokens, version_1.defaultRelease)) === null || _a === void 0 ? void 0 : _a.filter((n) => n instanceof nodes_1.ExpressionNode && n.get() instanceof expressions_1.CDSAnnotation);
66692
+ }
66693
+ for (const annotation of annotations || []) {
66694
+ const tokens = annotation.getTokens().map(t => t.getStr());
66695
+ const colon = tokens.indexOf(":");
66696
+ if (tokens.slice(0, colon).join("") !== "@AbapCatalog.sqlViewName") {
66697
+ continue;
66698
+ }
66699
+ const match = tokens.slice(colon + 1).join(" ").match(/^'([\w/]+)'$/);
66700
+ if (match) {
66701
+ this.parsedData.sqlViewName = match[1].toUpperCase();
66702
+ return;
66703
+ }
66647
66704
  }
66648
66705
  }
66649
66706
  findDescription() {
@@ -73861,7 +73918,7 @@ class Registry {
73861
73918
  }
73862
73919
  static abaplintVersion() {
73863
73920
  // magic, see build script "version.js"
73864
- return "2.120.89";
73921
+ return "2.120.91";
73865
73922
  }
73866
73923
  getDDICReferences() {
73867
73924
  return this.ddicReferences;
@@ -76518,6 +76575,149 @@ exports.AbapdocParameterNames = AbapdocParameterNames;
76518
76575
 
76519
76576
  /***/ },
76520
76577
 
76578
+ /***/ "./node_modules/@abaplint/core/build/src/rules/abapdoc_short_link.js"
76579
+ /*!***************************************************************************!*\
76580
+ !*** ./node_modules/@abaplint/core/build/src/rules/abapdoc_short_link.js ***!
76581
+ \***************************************************************************/
76582
+ (__unused_webpack_module, exports, __webpack_require__) {
76583
+
76584
+ "use strict";
76585
+
76586
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
76587
+ if (k2 === undefined) k2 = k;
76588
+ var desc = Object.getOwnPropertyDescriptor(m, k);
76589
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
76590
+ desc = { enumerable: true, get: function() { return m[k]; } };
76591
+ }
76592
+ Object.defineProperty(o, k2, desc);
76593
+ }) : (function(o, m, k, k2) {
76594
+ if (k2 === undefined) k2 = k;
76595
+ o[k2] = m[k];
76596
+ }));
76597
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
76598
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
76599
+ }) : function(o, v) {
76600
+ o["default"] = v;
76601
+ });
76602
+ var __importStar = (this && this.__importStar) || (function () {
76603
+ var ownKeys = function(o) {
76604
+ ownKeys = Object.getOwnPropertyNames || function (o) {
76605
+ var ar = [];
76606
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
76607
+ return ar;
76608
+ };
76609
+ return ownKeys(o);
76610
+ };
76611
+ return function (mod) {
76612
+ if (mod && mod.__esModule) return mod;
76613
+ var result = {};
76614
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
76615
+ __setModuleDefault(result, mod);
76616
+ return result;
76617
+ };
76618
+ })();
76619
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
76620
+ exports.AbapdocShortLink = exports.AbapdocShortLinkConf = void 0;
76621
+ const Statements = __importStar(__webpack_require__(/*! ../abap/2_statements/statements */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/index.js"));
76622
+ const Expressions = __importStar(__webpack_require__(/*! ../abap/2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js"));
76623
+ const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
76624
+ const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "./node_modules/@abaplint/core/build/src/rules/_abap_rule.js");
76625
+ const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
76626
+ const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
76627
+ const _statement_1 = __webpack_require__(/*! ../abap/2_statements/statements/_statement */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/_statement.js");
76628
+ const position_1 = __webpack_require__(/*! ../position */ "./node_modules/@abaplint/core/build/src/position.js");
76629
+ const edit_helper_1 = __webpack_require__(/*! ../edit_helper */ "./node_modules/@abaplint/core/build/src/edit_helper.js");
76630
+ class AbapdocShortLinkConf extends _basic_rule_config_1.BasicRuleConfig {
76631
+ }
76632
+ exports.AbapdocShortLinkConf = AbapdocShortLinkConf;
76633
+ class AbapdocShortLink extends _abap_rule_1.ABAPRule {
76634
+ constructor() {
76635
+ super(...arguments);
76636
+ this.conf = new AbapdocShortLinkConf();
76637
+ }
76638
+ getMetadata() {
76639
+ return {
76640
+ key: "abapdoc_short_link",
76641
+ title: "Use short form of ABAP Doc links",
76642
+ shortDescription: `Reports ABAP Doc links to components of the current global class or interface which repeat the object name.`,
76643
+ extendedInformation: `Links to components of the same repository object can omit the object name and start with a period,
76644
+ {@link zif_foo.data:field} can be written as {@link .data:field}.
76645
+
76646
+ Only checks ABAP Doc inside the definition of the global class or interface.
76647
+
76648
+ https://github.com/SAP/abap-file-formats/issues/880`,
76649
+ tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Quickfix],
76650
+ badExample: `INTERFACE zif_foo PUBLIC.
76651
+ "! Same as {@link zif_foo.data:bar}
76652
+ DATA foo TYPE string.
76653
+ DATA bar TYPE string.
76654
+ ENDINTERFACE.`,
76655
+ goodExample: `INTERFACE zif_foo PUBLIC.
76656
+ "! Same as {@link .data:bar}
76657
+ DATA foo TYPE string.
76658
+ DATA bar TYPE string.
76659
+ ENDINTERFACE.`,
76660
+ };
76661
+ }
76662
+ getConfig() {
76663
+ return this.conf;
76664
+ }
76665
+ setConfig(conf) {
76666
+ this.conf = conf;
76667
+ }
76668
+ runParsed(file, obj) {
76669
+ var _a;
76670
+ const issues = [];
76671
+ const objectType = obj.getType();
76672
+ if (objectType !== "CLAS" && objectType !== "INTF") {
76673
+ return [];
76674
+ }
76675
+ const objectName = obj.getName().toLowerCase();
76676
+ let definition = false;
76677
+ for (const statement of file.getStatements()) {
76678
+ const type = statement.get();
76679
+ if (type instanceof Statements.ClassDefinition || type instanceof Statements.Interface) {
76680
+ const name = (_a = statement.findFirstExpression(Expressions.ClassName)) !== null && _a !== void 0 ? _a : statement.findFirstExpression(Expressions.InterfaceName);
76681
+ definition = (name === null || name === void 0 ? void 0 : name.getFirstToken().getStr().toLowerCase()) === objectName;
76682
+ continue;
76683
+ }
76684
+ else if (type instanceof Statements.EndClass || type instanceof Statements.EndInterface) {
76685
+ definition = false;
76686
+ continue;
76687
+ }
76688
+ else if (definition === false || !(type instanceof _statement_1.Comment)) {
76689
+ continue;
76690
+ }
76691
+ const token = statement.getFirstToken();
76692
+ const str = token.getStr();
76693
+ if (str.startsWith(`"!`) === false) {
76694
+ continue;
76695
+ }
76696
+ const regex = /\{@link\s+((?:(\w+):)?([\w/]+))\./gi;
76697
+ let match;
76698
+ while ((match = regex.exec(str)) !== null) {
76699
+ const kind = match[2];
76700
+ if (match[3].toLowerCase() !== objectName
76701
+ || (kind !== undefined && kind.toLowerCase() !== objectType.toLowerCase())) {
76702
+ continue;
76703
+ }
76704
+ const row = token.getStart().getRow();
76705
+ const col = token.getStart().getCol() + match.index + match[0].length - 1 - match[1].length;
76706
+ const start = new position_1.Position(row, col);
76707
+ const end = new position_1.Position(row, col + match[1].length);
76708
+ const fix = edit_helper_1.EditHelper.deleteRange(file, start, end);
76709
+ const message = `Use short form of ABAP Doc link, remove "${match[1]}"`;
76710
+ issues.push(issue_1.Issue.atRange(file, start, end, message, this.getMetadata().key, this.conf.severity, fix));
76711
+ }
76712
+ }
76713
+ return issues;
76714
+ }
76715
+ }
76716
+ exports.AbapdocShortLink = AbapdocShortLink;
76717
+ //# sourceMappingURL=abapdoc_short_link.js.map
76718
+
76719
+ /***/ },
76720
+
76521
76721
  /***/ "./node_modules/@abaplint/core/build/src/rules/abapdoc_shorttext_length.js"
76522
76722
  /*!*********************************************************************************!*\
76523
76723
  !*** ./node_modules/@abaplint/core/build/src/rules/abapdoc_shorttext_length.js ***!
@@ -88699,12 +88899,9 @@ ${indentation} output = ${uniqueName}.\n`;
88699
88899
  }
88700
88900
  }
88701
88901
  /** NEW into a data reference creates data, CREATE OBJECT cannot: "target = NEW #|type( [value] )"
88702
- * with a variable typed REF TO a data type becomes CREATE DATA plus the assignment of the value */
88902
+ * with a target typed REF TO a data type becomes CREATE DATA plus the assignment of the value */
88703
88903
  newDataReference(high, target, found, lowFile, highSyntax) {
88704
88904
  var _a, _b, _c;
88705
- if (target.getChildren().length !== 1 || !(((_a = target.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.TargetField)) {
88706
- return undefined;
88707
- }
88708
88905
  const children = found.getChildren();
88709
88906
  const value = found.findDirectExpression(Expressions.Source);
88710
88907
  // NEW, the type, "(", optionally one value, ")"
@@ -88712,12 +88909,23 @@ ${indentation} output = ${uniqueName}.\n`;
88712
88909
  return undefined;
88713
88910
  }
88714
88911
  const name = target.concatTokens();
88912
+ const typeExpr = found.findDirectExpression(Expressions.TypeNameOrInfer);
88913
+ const typeName = typeExpr === null || typeExpr === void 0 ? void 0 : typeExpr.concatTokens();
88715
88914
  const spag = highSyntax.spaghetti.lookupPosition(high.getFirstToken().getStart(), lowFile.getFilename());
88716
- const type = (_b = spag === null || spag === void 0 ? void 0 : spag.findVariable(name)) === null || _b === void 0 ? void 0 : _b.getType();
88915
+ let type = undefined;
88916
+ if (typeName === "#") {
88917
+ // the type of the target, as inferred by the syntax check
88918
+ const typeToken = typeExpr.getFirstToken();
88919
+ const resolved = (_a = spag === null || spag === void 0 ? void 0 : spag.getData().references.find(r => r.referenceType === _reference_1.ReferenceType.InferredType
88920
+ && r.position.getStart().equals(typeToken.getStart()))) === null || _a === void 0 ? void 0 : _a.resolved;
88921
+ type = resolved instanceof _typed_identifier_1.TypedIdentifier ? resolved.getType() : undefined;
88922
+ }
88923
+ else if (target.getChildren().length === 1 && ((_b = target.getFirstChild()) === null || _b === void 0 ? void 0 : _b.get()) instanceof Expressions.TargetField) {
88924
+ type = (_c = spag === null || spag === void 0 ? void 0 : spag.findVariable(name)) === null || _c === void 0 ? void 0 : _c.getType();
88925
+ }
88717
88926
  if (!(type instanceof basic_1.DataReference)) {
88718
88927
  return undefined;
88719
88928
  }
88720
- const typeName = (_c = found.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _c === void 0 ? void 0 : _c.concatTokens();
88721
88929
  const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
88722
88930
  let abap = `CREATE DATA ${name}` + (typeName === "#" ? "" : ` TYPE ${typeName}`) + ".";
88723
88931
  if (value === undefined) {
@@ -88765,7 +88973,7 @@ ${indentation} output = ${uniqueName}.\n`;
88765
88973
  }
88766
88974
  }
88767
88975
  else {
88768
- throw new Error("newParameters, downport, unexpected");
88976
+ return undefined; // not an object, CREATE OBJECT does not apply
88769
88977
  }
88770
88978
  }
88771
88979
  if (cdef && cdef.getMethodDefinitions === undefined) {
@@ -90272,6 +90480,121 @@ exports.ForbiddenIdentifier = ForbiddenIdentifier;
90272
90480
 
90273
90481
  /***/ },
90274
90482
 
90483
+ /***/ "./node_modules/@abaplint/core/build/src/rules/forbidden_kernel_write.js"
90484
+ /*!*******************************************************************************!*\
90485
+ !*** ./node_modules/@abaplint/core/build/src/rules/forbidden_kernel_write.js ***!
90486
+ \*******************************************************************************/
90487
+ (__unused_webpack_module, exports, __webpack_require__) {
90488
+
90489
+ "use strict";
90490
+
90491
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
90492
+ if (k2 === undefined) k2 = k;
90493
+ var desc = Object.getOwnPropertyDescriptor(m, k);
90494
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
90495
+ desc = { enumerable: true, get: function() { return m[k]; } };
90496
+ }
90497
+ Object.defineProperty(o, k2, desc);
90498
+ }) : (function(o, m, k, k2) {
90499
+ if (k2 === undefined) k2 = k;
90500
+ o[k2] = m[k];
90501
+ }));
90502
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
90503
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
90504
+ }) : function(o, v) {
90505
+ o["default"] = v;
90506
+ });
90507
+ var __importStar = (this && this.__importStar) || (function () {
90508
+ var ownKeys = function(o) {
90509
+ ownKeys = Object.getOwnPropertyNames || function (o) {
90510
+ var ar = [];
90511
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
90512
+ return ar;
90513
+ };
90514
+ return ownKeys(o);
90515
+ };
90516
+ return function (mod) {
90517
+ if (mod && mod.__esModule) return mod;
90518
+ var result = {};
90519
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
90520
+ __setModuleDefault(result, mod);
90521
+ return result;
90522
+ };
90523
+ })();
90524
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
90525
+ exports.ForbiddenKernelWrite = exports.ForbiddenKernelWriteConf = void 0;
90526
+ const Expressions = __importStar(__webpack_require__(/*! ../abap/2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js"));
90527
+ const Statements = __importStar(__webpack_require__(/*! ../abap/2_statements/statements */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/index.js"));
90528
+ const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "./node_modules/@abaplint/core/build/src/rules/_abap_rule.js");
90529
+ const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
90530
+ const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
90531
+ const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
90532
+ class ForbiddenKernelWriteConf extends _basic_rule_config_1.BasicRuleConfig {
90533
+ constructor() {
90534
+ super(...arguments);
90535
+ /** Objects allowed to use WRITE '@KERNEL', array of string regex matched against the object name.
90536
+ * Empty, the default, allows every object
90537
+ * @uniqueItems true
90538
+ */
90539
+ this.allow = [];
90540
+ }
90541
+ }
90542
+ exports.ForbiddenKernelWriteConf = ForbiddenKernelWriteConf;
90543
+ class ForbiddenKernelWrite extends _abap_rule_1.ABAPRule {
90544
+ constructor() {
90545
+ super(...arguments);
90546
+ this.conf = new ForbiddenKernelWriteConf();
90547
+ this.allow = [];
90548
+ }
90549
+ getMetadata() {
90550
+ return {
90551
+ key: "forbidden_kernel_write",
90552
+ title: "Forbidden kernel WRITE",
90553
+ shortDescription: `Forbid WRITE '@KERNEL' outside the listed objects`,
90554
+ extendedInformation: `The transpiler emits the literal of WRITE '@KERNEL ...' as raw JavaScript,
90555
+ which runs with the privileges of the host. Open-abap uses this for its kernel classes, code compiled by a host it did not write should not.
90556
+
90557
+ allow is a list of regex, case insensitive, matched against the object name, eg. ["^CL_", "^KERNEL_"].
90558
+ An empty list, the default, allows every object. To forbid WRITE '@KERNEL' everywhere use a regex matching no name, eg. ["^$"].`,
90559
+ tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Security],
90560
+ badExample: `WRITE '@KERNEL process.exit(1);'.`,
90561
+ };
90562
+ }
90563
+ getConfig() {
90564
+ return this.conf;
90565
+ }
90566
+ setConfig(conf) {
90567
+ this.conf = conf;
90568
+ if (this.conf.allow === undefined) {
90569
+ this.conf.allow = [];
90570
+ }
90571
+ this.allow = this.conf.allow.map(a => new RegExp(a, "i"));
90572
+ }
90573
+ runParsed(file, obj) {
90574
+ var _a;
90575
+ if (this.allow.length === 0 || this.allow.some(a => a.test(obj.getName()))) {
90576
+ return [];
90577
+ }
90578
+ const ret = [];
90579
+ for (const s of file.getStatements()) {
90580
+ if (!(s.get() instanceof Statements.Write)) {
90581
+ continue;
90582
+ }
90583
+ // same check as the transpiler, statements/write.ts
90584
+ const source = (_a = s.findDirectExpression(Expressions.Source)) === null || _a === void 0 ? void 0 : _a.concatTokens();
90585
+ if ((source === null || source === void 0 ? void 0 : source.startsWith("'@KERNEL ")) === true) {
90586
+ const message = "WRITE '@KERNEL' not allowed in " + obj.getName();
90587
+ ret.push(issue_1.Issue.atStatement(file, s, message, this.getMetadata().key, this.conf.severity));
90588
+ }
90589
+ }
90590
+ return ret;
90591
+ }
90592
+ }
90593
+ exports.ForbiddenKernelWrite = ForbiddenKernelWrite;
90594
+ //# sourceMappingURL=forbidden_kernel_write.js.map
90595
+
90596
+ /***/ },
90597
+
90275
90598
  /***/ "./node_modules/@abaplint/core/build/src/rules/forbidden_pseudo_and_pragma.js"
90276
90599
  /*!************************************************************************************!*\
90277
90600
  !*** ./node_modules/@abaplint/core/build/src/rules/forbidden_pseudo_and_pragma.js ***!
@@ -93168,6 +93491,7 @@ __exportStar(__webpack_require__(/*! ./abapdoc */ "./node_modules/@abaplint/core
93168
93491
  __exportStar(__webpack_require__(/*! ./abapdoc_html_tag */ "./node_modules/@abaplint/core/build/src/rules/abapdoc_html_tag.js"), exports);
93169
93492
  __exportStar(__webpack_require__(/*! ./abapdoc_leading_at */ "./node_modules/@abaplint/core/build/src/rules/abapdoc_leading_at.js"), exports);
93170
93493
  __exportStar(__webpack_require__(/*! ./abapdoc_parameter_names */ "./node_modules/@abaplint/core/build/src/rules/abapdoc_parameter_names.js"), exports);
93494
+ __exportStar(__webpack_require__(/*! ./abapdoc_short_link */ "./node_modules/@abaplint/core/build/src/rules/abapdoc_short_link.js"), exports);
93171
93495
  __exportStar(__webpack_require__(/*! ./abapdoc_shorttext_length */ "./node_modules/@abaplint/core/build/src/rules/abapdoc_shorttext_length.js"), exports);
93172
93496
  __exportStar(__webpack_require__(/*! ./add_test_attributes */ "./node_modules/@abaplint/core/build/src/rules/add_test_attributes.js"), exports);
93173
93497
  __exportStar(__webpack_require__(/*! ./aff_and_xml */ "./node_modules/@abaplint/core/build/src/rules/aff_and_xml.js"), exports);
@@ -93242,6 +93566,7 @@ __exportStar(__webpack_require__(/*! ./exporting */ "./node_modules/@abaplint/co
93242
93566
  __exportStar(__webpack_require__(/*! ./final_newline */ "./node_modules/@abaplint/core/build/src/rules/final_newline.js"), exports);
93243
93567
  __exportStar(__webpack_require__(/*! ./fm_global_parameters_obsolete */ "./node_modules/@abaplint/core/build/src/rules/fm_global_parameters_obsolete.js"), exports);
93244
93568
  __exportStar(__webpack_require__(/*! ./forbidden_identifier */ "./node_modules/@abaplint/core/build/src/rules/forbidden_identifier.js"), exports);
93569
+ __exportStar(__webpack_require__(/*! ./forbidden_kernel_write */ "./node_modules/@abaplint/core/build/src/rules/forbidden_kernel_write.js"), exports);
93245
93570
  __exportStar(__webpack_require__(/*! ./forbidden_pseudo_and_pragma */ "./node_modules/@abaplint/core/build/src/rules/forbidden_pseudo_and_pragma.js"), exports);
93246
93571
  __exportStar(__webpack_require__(/*! ./forbidden_void_type */ "./node_modules/@abaplint/core/build/src/rules/forbidden_void_type.js"), exports);
93247
93572
  __exportStar(__webpack_require__(/*! ./form_tables_obsolete */ "./node_modules/@abaplint/core/build/src/rules/form_tables_obsolete.js"), exports);
@@ -113288,6 +113613,7 @@ class XMLConsistency {
113288
113613
  extendedInformation: `Checks:
113289
113614
  * XML is well-formed and parseable
113290
113615
  * Naming for CLAS and INTF objects
113616
+ * CLAS and INTF objects do not contain fields that abapGit clears, eg. AUTHOR, CREATEDON and VERSION
113291
113617
  * QUAN fields in TABL objects have reference table and field values
113292
113618
  * Transparent TABL objects have delivery class and size category set
113293
113619
  * TABL fields with a built-in type carry the INTTYPE abapGit serializes for it, for the confirmed pairs
@@ -113373,6 +113699,22 @@ class XMLConsistency {
113373
113699
  else if (((_a = obj.getMainABAPFile()) === null || _a === void 0 ? void 0 : _a.getStructure()) !== undefined && obj.getClassDefinition() === undefined) {
113374
113700
  issues.push(issue_1.Issue.atRow(file, 1, "Class matching XML name not found in ABAP file", this.getMetadata().key, this.conf.severity));
113375
113701
  }
113702
+ issues.push(...this.checkClearedFields(obj, file, "VSEOCLASS", XMLConsistency.clearedClassFields));
113703
+ return issues;
113704
+ }
113705
+ checkClearedFields(obj, file, structure, fields) {
113706
+ var _a, _b;
113707
+ const issues = [];
113708
+ const block = (_b = (_a = obj.getXML()) === null || _a === void 0 ? void 0 : _a.match(new RegExp(`<${structure}>([\\s\\S]*?)</${structure}>`))) === null || _b === void 0 ? void 0 : _b[1];
113709
+ if (block === undefined) {
113710
+ return issues;
113711
+ }
113712
+ for (const field of fields) {
113713
+ if (block.match(new RegExp(`<${field}[\\s/>]`)) !== null) {
113714
+ const message = `Field ${field} in ${structure} is cleared by abapGit and should not be in the XML`;
113715
+ issues.push(issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.conf.severity));
113716
+ }
113717
+ }
113376
113718
  return issues;
113377
113719
  }
113378
113720
  runTextPool(obj, file) {
@@ -113406,6 +113748,7 @@ class XMLConsistency {
113406
113748
  else if (obj.getDefinition() !== undefined && ((_a = obj.getDefinition()) === null || _a === void 0 ? void 0 : _a.getName().toUpperCase()) !== name.toUpperCase()) {
113407
113749
  issues.push(issue_1.Issue.atRow(file, 1, "Interface matching XML name not found in ABAP file", this.getMetadata().key, this.conf.severity));
113408
113750
  }
113751
+ issues.push(...this.checkClearedFields(obj, file, "VSEOINTERF", XMLConsistency.clearedInterfaceFields));
113409
113752
  return issues;
113410
113753
  }
113411
113754
  checkTextLength(file, fieldName, text, maxLength, lang) {
@@ -113586,6 +113929,14 @@ class XMLConsistency {
113586
113929
  }
113587
113930
  }
113588
113931
  exports.XMLConsistency = XMLConsistency;
113932
+ // fields abapGit clears before serializing, see ZCL_ABAPGIT_OO_CLASS and ZCL_ABAPGIT_OO_INTERFACE;
113933
+ // abapGit omits initial fields, so any occurrence shows as a diff on every pull
113934
+ XMLConsistency.clearedInterfaceFields = [
113935
+ "UUID", "AUTHOR", "CREATEDON", "CHANGEDBY", "CHANGEDON", "CHGDANYBY", "CHGDANYON", "R3RELEASE", "VERSION",
113936
+ ];
113937
+ XMLConsistency.clearedClassFields = [
113938
+ ...XMLConsistency.clearedInterfaceFields, "CLSFINAL", "CLSABSTRCT", "EXPOSURE",
113939
+ ];
113589
113940
  // INTTYPE that abapGit serializes for a built-in DATATYPE, confirmed by exported tables;
113590
113941
  // a different value activates, but shows as a diff on every pull
113591
113942
  XMLConsistency.intTypes = {
@@ -132634,6 +132985,9 @@ class SelectTranspiler {
132634
132985
  else if (node.findDirectTokenByText("DISTINCT") !== undefined) {
132635
132986
  throw new Error("SelectTranspiler, UNION DISTINCT todo");
132636
132987
  }
132988
+ else if (node.findDirectExpression(abaplint.Expressions.Select)?.findDirectTokenByText("UPDATE") !== undefined) {
132989
+ return new chunk_1.Chunk(`throw new Error("SELECT SINGLE FOR UPDATE, not supported, transpiler");`);
132990
+ }
132637
132991
  let target = "undefined";
132638
132992
  let intoCorrespondingStructure = false;
132639
132993
  if (targetOverride) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/transpiler-cli",
3
- "version": "2.14.13",
3
+ "version": "2.14.15",
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.89",
31
- "@abaplint/transpiler": "^2.14.13",
30
+ "@abaplint/core": "^2.120.91",
31
+ "@abaplint/transpiler": "^2.14.15",
32
32
  "@types/glob": "^9.0.0",
33
33
  "@types/node": "^26.6.5",
34
34
  "@types/progress": "^2.0.7",