@abaplint/cli 2.120.10 → 2.120.11

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 +246 -29
  2. package/package.json +2 -2
package/build/cli.js CHANGED
@@ -4970,7 +4970,7 @@ class For extends combi_1.Expression {
4970
4970
  const itera = (0, combi_1.seq)(_1.InlineFieldDefinition, (0, combi_1.opt)(then), whil);
4971
4971
  const groupBy = (0, combi_1.seq)("GROUP BY", (0, combi_1.alt)(field_chain_1.FieldChain, (0, combi_1.seq)("(", (0, combi_1.plus)(_1.LoopGroupByComponent), ")")), (0, combi_1.opt)((0, combi_1.seq)((0, combi_1.alt)("ASCENDING", "DESCENDING"), (0, combi_1.opt)("AS TEXT"))), (0, combi_1.opt)("WITHOUT MEMBERS"));
4972
4972
  const t = (0, combi_1.alt)(_1.TargetField, _1.TargetFieldSymbol);
4973
- const groups = (0, combi_1.ver)(version_1.Release.v740sp08, (0, combi_1.seq)("GROUPS", t, "OF", t, "IN", _1.Source, (0, combi_1.optPrio)(groupBy)));
4973
+ const groups = (0, combi_1.ver)(version_1.Release.v740sp08, (0, combi_1.seq)("GROUPS", t, "OF", t, "IN", _1.Source, (0, combi_1.optPrio)(groupBy)), { also: combi_1.AlsoIn.OpenABAP });
4974
4974
  const f = (0, combi_1.seq)("FOR", (0, combi_1.alt)(itera, inn, groups), (0, combi_1.optPrio)(_1.Let));
4975
4975
  return (0, combi_1.ver)(version_1.Release.v740sp05, f, { also: combi_1.AlsoIn.OpenABAP });
4976
4976
  }
@@ -5653,7 +5653,8 @@ const combi_1 = __webpack_require__(/*! ../combi */ "../core/build/src/abap/2_st
5653
5653
  const _1 = __webpack_require__(/*! . */ "../core/build/src/abap/2_statements/expressions/index.js");
5654
5654
  class InlineFieldDefinition extends combi_1.Expression {
5655
5655
  getRunnable() {
5656
- return (0, combi_1.altPrio)((0, combi_1.seq)(_1.Field, "=", _1.Source), (0, combi_1.seq)(_1.Field, "TYPE", _1.TypeName));
5656
+ const field = (0, combi_1.altPrio)(_1.Field, _1.FieldSymbol);
5657
+ return (0, combi_1.altPrio)((0, combi_1.seq)(field, "=", _1.Source), (0, combi_1.seq)(_1.Field, "TYPE", _1.TypeName));
5657
5658
  }
5658
5659
  }
5659
5660
  exports.InlineFieldDefinition = InlineFieldDefinition;
@@ -7207,7 +7208,7 @@ const tokens_1 = __webpack_require__(/*! ../../1_lexer/tokens */ "../core/build/
7207
7208
  const version_1 = __webpack_require__(/*! ../../../version */ "../core/build/src/version.js");
7208
7209
  class ReduceNext extends combi_1.Expression {
7209
7210
  getRunnable() {
7210
- const calcAssign = (0, combi_1.ver)(version_1.Release.v754, (0, combi_1.alt)((0, combi_1.seq)((0, combi_1.tok)(tokens_1.WPlus), "="), (0, combi_1.seq)((0, combi_1.tok)(tokens_1.WDash), "="), "/=", "*=", "&&="));
7211
+ const calcAssign = (0, combi_1.ver)(version_1.Release.v754, (0, combi_1.alt)((0, combi_1.seq)((0, combi_1.tok)(tokens_1.WPlus), "="), (0, combi_1.seq)((0, combi_1.tok)(tokens_1.WDash), "="), "/=", "*=", "&&="), { also: combi_1.AlsoIn.OpenABAP });
7211
7212
  const fields = (0, combi_1.seq)(_1.SimpleTarget, (0, combi_1.altPrio)("=", calcAssign), _1.Source);
7212
7213
  return (0, combi_1.seq)("NEXT", (0, combi_1.plus)(fields));
7213
7214
  }
@@ -29646,18 +29647,30 @@ exports.ComponentCompare = void 0;
29646
29647
  const Expressions = __importStar(__webpack_require__(/*! ../../2_statements/expressions */ "../core/build/src/abap/2_statements/expressions/index.js"));
29647
29648
  const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "../core/build/src/abap/5_syntax/_syntax_input.js");
29648
29649
  const component_chain_1 = __webpack_require__(/*! ./component_chain */ "../core/build/src/abap/5_syntax/expressions/component_chain.js");
29650
+ const component_name_1 = __webpack_require__(/*! ./component_name */ "../core/build/src/abap/5_syntax/expressions/component_name.js");
29649
29651
  const source_1 = __webpack_require__(/*! ./source */ "../core/build/src/abap/5_syntax/expressions/source.js");
29650
29652
  class ComponentCompare {
29651
- static runSyntax(node, input, type) {
29653
+ static runSyntax(node, input, leftType, rightType) {
29652
29654
  const chain = node.findDirectExpression(Expressions.ComponentChainSimple);
29653
29655
  if (chain === undefined) {
29654
29656
  const message = "ComponentCompare, chain not found";
29655
29657
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
29656
29658
  return;
29657
29659
  }
29658
- const fieldType = component_chain_1.ComponentChain.runSyntax(type, chain, input);
29660
+ const fieldType = component_chain_1.ComponentChain.runSyntax(leftType, chain, input);
29659
29661
  for (const s of node.findDirectExpressions(Expressions.Source)) {
29660
- source_1.Source.runSyntax(s, input, fieldType);
29662
+ const fieldChain = s.findDirectExpression(Expressions.FieldChain);
29663
+ const first = fieldChain === null || fieldChain === void 0 ? void 0 : fieldChain.getFirstChild();
29664
+ if (rightType && fieldChain && first) {
29665
+ let sourceType = rightType;
29666
+ if (first.concatTokens().toUpperCase() !== "TABLE_LINE") {
29667
+ sourceType = component_name_1.ComponentName.runSyntax(sourceType, first, input);
29668
+ }
29669
+ component_chain_1.ComponentChain.runSyntax(sourceType, fieldChain, input);
29670
+ }
29671
+ else {
29672
+ source_1.Source.runSyntax(s, input, fieldType);
29673
+ }
29661
29674
  }
29662
29675
  }
29663
29676
  }
@@ -29796,15 +29809,15 @@ exports.ComponentCond = void 0;
29796
29809
  const Expressions = __importStar(__webpack_require__(/*! ../../2_statements/expressions */ "../core/build/src/abap/2_statements/expressions/index.js"));
29797
29810
  const component_compare_1 = __webpack_require__(/*! ./component_compare */ "../core/build/src/abap/5_syntax/expressions/component_compare.js");
29798
29811
  class ComponentCond {
29799
- static runSyntax(node, input, type) {
29812
+ static runSyntax(node, input, leftType, rightType) {
29800
29813
  for (const t of node.findDirectExpressions(Expressions.ComponentCondSub)) {
29801
29814
  const c = t.findDirectExpression(Expressions.ComponentCond);
29802
29815
  if (c) {
29803
- ComponentCond.runSyntax(c, input, type);
29816
+ ComponentCond.runSyntax(c, input, leftType, rightType);
29804
29817
  }
29805
29818
  }
29806
29819
  for (const t of node.findDirectExpressions(Expressions.ComponentCompare)) {
29807
- component_compare_1.ComponentCompare.runSyntax(t, input, type);
29820
+ component_compare_1.ComponentCompare.runSyntax(t, input, leftType, rightType);
29808
29821
  }
29809
29822
  }
29810
29823
  }
@@ -31022,21 +31035,14 @@ class FilterBody {
31022
31035
  if (node === undefined) {
31023
31036
  return targetType;
31024
31037
  }
31025
- let type = undefined;
31038
+ const types = [];
31026
31039
  for (const s of node.findDirectExpressions(Expressions.Source)) {
31027
- if (type === undefined) {
31028
- type = source_1.Source.runSyntax(s, input);
31029
- }
31030
- else {
31031
- source_1.Source.runSyntax(s, input);
31032
- }
31033
- }
31034
- // todo
31035
- if (node.findDirectTokenByText("EXCEPT") === undefined) {
31036
- const rowType = type instanceof basic_1.TableType ? type.getRowType() : undefined;
31037
- component_cond_1.ComponentCond.runSyntax(node.findDirectExpression(Expressions.ComponentCond), input, rowType);
31040
+ types.push(source_1.Source.runSyntax(s, input));
31038
31041
  }
31039
- return type ? type : targetType;
31042
+ const inputRowType = types[0] instanceof basic_1.TableType ? types[0].getRowType() : undefined;
31043
+ const filterRowType = types[1] instanceof basic_1.TableType ? types[1].getRowType() : undefined;
31044
+ component_cond_1.ComponentCond.runSyntax(node.findDirectExpression(Expressions.ComponentCond), input, inputRowType, filterRowType);
31045
+ return types[0] ? types[0] : targetType;
31040
31046
  }
31041
31047
  }
31042
31048
  exports.FilterBody = FilterBody;
@@ -31527,7 +31533,8 @@ class InlineFieldDefinition {
31527
31533
  static runSyntax(node, input, targetType) {
31528
31534
  var _a;
31529
31535
  let type = undefined;
31530
- const field = (_a = node.findDirectExpression(Expressions.Field)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
31536
+ const field = (_a = (node.findDirectExpression(Expressions.Field)
31537
+ || node.findDirectExpression(Expressions.FieldSymbol))) === null || _a === void 0 ? void 0 : _a.getFirstToken();
31531
31538
  if (field === undefined) {
31532
31539
  return undefined;
31533
31540
  }
@@ -51514,6 +51521,7 @@ class ClassDefinition extends _identifier_1.Identifier {
51514
51521
  // perform checks after everything has been initialized
51515
51522
  this.checkInterfaceVisibility(input, node);
51516
51523
  this.checkMethodsFromSuperClasses(input);
51524
+ this.checkClassNameLength(input);
51517
51525
  this.checkMethodNameLength(input);
51518
51526
  this.checkClassConstructorStatic(input);
51519
51527
  }
@@ -51564,6 +51572,12 @@ class ClassDefinition extends _identifier_1.Identifier {
51564
51572
  }
51565
51573
  */
51566
51574
  ///////////////////
51575
+ checkClassNameLength(input) {
51576
+ if (this.getName().length > 30) {
51577
+ const message = `Class name "${this.getName()}" is too long, maximum length is 30 characters`;
51578
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, this.getToken(), message));
51579
+ }
51580
+ }
51567
51581
  findSuper(def, input) {
51568
51582
  var _a;
51569
51583
  const token = (_a = def === null || def === void 0 ? void 0 : def.findDirectExpression(expressions_1.SuperClassName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
@@ -56040,7 +56054,7 @@ exports.DDLAspect = DDLAspect;
56040
56054
  "use strict";
56041
56055
 
56042
56056
  Object.defineProperty(exports, "__esModule", ({ value: true }));
56043
- exports.DDLValueHelp = exports.DDLForeignKey = exports.DDLForeignKeyTarget = void 0;
56057
+ exports.DDLReference = exports.DDLValueHelp = exports.DDLForeignKey = exports.DDLForeignKeyTarget = void 0;
56044
56058
  const combi_1 = __webpack_require__(/*! ../../abap/2_statements/combi */ "../core/build/src/abap/2_statements/combi.js");
56045
56059
  const ddl_literal_1 = __webpack_require__(/*! ./ddl_literal */ "../core/build/src/ddl/expressions/ddl_literal.js");
56046
56060
  const ddl_name_1 = __webpack_require__(/*! ./ddl_name */ "../core/build/src/ddl/expressions/ddl_name.js");
@@ -56064,6 +56078,12 @@ class DDLValueHelp extends combi_1.Expression {
56064
56078
  }
56065
56079
  }
56066
56080
  exports.DDLValueHelp = DDLValueHelp;
56081
+ class DDLReference extends combi_1.Expression {
56082
+ getRunnable() {
56083
+ return (0, combi_1.seq)("WITH", "REFERENCE", "TABLE", ddl_name_1.DDLName, "AND", "REFERENCE", "FIELD", ddl_name_1.DDLName);
56084
+ }
56085
+ }
56086
+ exports.DDLReference = DDLReference;
56067
56087
  //# sourceMappingURL=ddl_clauses.js.map
56068
56088
 
56069
56089
  /***/ },
@@ -56339,7 +56359,7 @@ const ddl_name_1 = __webpack_require__(/*! ./ddl_name */ "../core/build/src/ddl/
56339
56359
  const ddl_type_1 = __webpack_require__(/*! ./ddl_type */ "../core/build/src/ddl/expressions/ddl_type.js");
56340
56360
  class DDLTableField extends combi_1.Expression {
56341
56361
  getRunnable() {
56342
- const trailingClause = (0, combi_1.alt)(ddl_clauses_1.DDLForeignKey, ddl_clauses_1.DDLValueHelp);
56362
+ const trailingClause = (0, combi_1.alt)(ddl_clauses_1.DDLForeignKey, ddl_clauses_1.DDLReference, ddl_clauses_1.DDLValueHelp);
56343
56363
  return (0, combi_1.seq)((0, combi_1.star)(expressions_1.CDSAnnotation), (0, combi_1.optPrio)("KEY"), ddl_name_1.DDLName, ":", ddl_type_1.DDLType, (0, combi_1.optPrio)("NOT NULL"), (0, combi_1.star)(trailingClause), ";");
56344
56364
  }
56345
56365
  }
@@ -67561,6 +67581,13 @@ class Table extends _abstract_object_1.AbstractObject {
67561
67581
  }
67562
67582
  return (_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.secondaryIndexes;
67563
67583
  }
67584
+ getFields() {
67585
+ var _a;
67586
+ if (this.parsedData === undefined) {
67587
+ this.parseXML();
67588
+ }
67589
+ return (_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.fields;
67590
+ }
67564
67591
  getAllowedNaming() {
67565
67592
  let length = 30;
67566
67593
  const regex = /^((\/[A-Z_\d]{3,8}\/)|[a-zA-Z0-9]{3}|CI_)\w+$/;
@@ -67613,9 +67640,13 @@ class Table extends _abstract_object_1.AbstractObject {
67613
67640
  && this.parsedData.dataClass === "USER3") {
67614
67641
  return new Types.UnknownType("Data class = USER3 not allowed in cloud");
67615
67642
  }
67616
- if (this.getTableCategory() === TableCategory.Transparent
67617
- && this.listKeys(reg).length === 0) {
67618
- return new Types.UnknownType("Table " + this.getName() + " has no key fields");
67643
+ if (this.getTableCategory() === TableCategory.Transparent) {
67644
+ if (this.listKeys(reg).length === 0) {
67645
+ return new Types.UnknownType("Table " + this.getName() + " has no key fields");
67646
+ }
67647
+ else if (this.keyFieldsNotFirst()) {
67648
+ return new Types.UnknownType("Table " + this.getName() + " key fields must be first");
67649
+ }
67619
67650
  }
67620
67651
  if (this.parsedType) {
67621
67652
  return this.parsedType;
@@ -67791,6 +67822,21 @@ class Table extends _abstract_object_1.AbstractObject {
67791
67822
  return this.parsedData.enhancementCategory;
67792
67823
  }
67793
67824
  ///////////////
67825
+ keyFieldsNotFirst() {
67826
+ var _a;
67827
+ let seenNonKey = false;
67828
+ for (const field of ((_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.fields) || []) {
67829
+ if (field.KEYFLAG === "X") {
67830
+ if (seenNonKey === true) {
67831
+ return true;
67832
+ }
67833
+ }
67834
+ else {
67835
+ seenNonKey = true;
67836
+ }
67837
+ }
67838
+ return false;
67839
+ }
67794
67840
  parseXML() {
67795
67841
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
67796
67842
  const parsed = super.parseRaw2();
@@ -67827,6 +67873,8 @@ class Table extends _abstract_object_1.AbstractObject {
67827
67873
  KEYFLAG: field.KEYFLAG,
67828
67874
  GROUPNAME: field.GROUPNAME,
67829
67875
  CHECKTABLE: field.CHECKTABLE,
67876
+ REFTABLE: field.REFTABLE,
67877
+ REFFIELD: field.REFFIELD,
67830
67878
  REFTYPE: field.REFTYPE,
67831
67879
  DDTEXT: field.DDTEXT,
67832
67880
  });
@@ -69365,7 +69413,7 @@ class Registry {
69365
69413
  }
69366
69414
  static abaplintVersion() {
69367
69415
  // magic, see build script "version.js"
69368
- return "2.120.10";
69416
+ return "2.120.11";
69369
69417
  }
69370
69418
  getDDICReferences() {
69371
69419
  return this.ddicReferences;
@@ -83165,6 +83213,7 @@ __exportStar(__webpack_require__(/*! ./no_comments_between_methods */ "../core/b
83165
83213
  __exportStar(__webpack_require__(/*! ./no_external_form_calls */ "../core/build/src/rules/no_external_form_calls.js"), exports);
83166
83214
  __exportStar(__webpack_require__(/*! ./no_inline_in_optional_branches */ "../core/build/src/rules/no_inline_in_optional_branches.js"), exports);
83167
83215
  __exportStar(__webpack_require__(/*! ./no_macros */ "../core/build/src/rules/no_macros.js"), exports);
83216
+ __exportStar(__webpack_require__(/*! ./no_mandt_in_database_operations */ "../core/build/src/rules/no_mandt_in_database_operations.js"), exports);
83168
83217
  __exportStar(__webpack_require__(/*! ./no_prefixes */ "../core/build/src/rules/no_prefixes.js"), exports);
83169
83218
  __exportStar(__webpack_require__(/*! ./no_public_attributes */ "../core/build/src/rules/no_public_attributes.js"), exports);
83170
83219
  __exportStar(__webpack_require__(/*! ./no_yoda_conditions */ "../core/build/src/rules/no_yoda_conditions.js"), exports);
@@ -87642,6 +87691,149 @@ exports.NoMacros = NoMacros;
87642
87691
 
87643
87692
  /***/ },
87644
87693
 
87694
+ /***/ "../core/build/src/rules/no_mandt_in_database_operations.js"
87695
+ /*!******************************************************************!*\
87696
+ !*** ../core/build/src/rules/no_mandt_in_database_operations.js ***!
87697
+ \******************************************************************/
87698
+ (__unused_webpack_module, exports, __webpack_require__) {
87699
+
87700
+ "use strict";
87701
+
87702
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
87703
+ if (k2 === undefined) k2 = k;
87704
+ var desc = Object.getOwnPropertyDescriptor(m, k);
87705
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
87706
+ desc = { enumerable: true, get: function() { return m[k]; } };
87707
+ }
87708
+ Object.defineProperty(o, k2, desc);
87709
+ }) : (function(o, m, k, k2) {
87710
+ if (k2 === undefined) k2 = k;
87711
+ o[k2] = m[k];
87712
+ }));
87713
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
87714
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
87715
+ }) : function(o, v) {
87716
+ o["default"] = v;
87717
+ });
87718
+ var __importStar = (this && this.__importStar) || (function () {
87719
+ var ownKeys = function(o) {
87720
+ ownKeys = Object.getOwnPropertyNames || function (o) {
87721
+ var ar = [];
87722
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
87723
+ return ar;
87724
+ };
87725
+ return ownKeys(o);
87726
+ };
87727
+ return function (mod) {
87728
+ if (mod && mod.__esModule) return mod;
87729
+ var result = {};
87730
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
87731
+ __setModuleDefault(result, mod);
87732
+ return result;
87733
+ };
87734
+ })();
87735
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
87736
+ exports.NoMandtInDatabaseOperations = exports.NoMandtInDatabaseOperationsConf = void 0;
87737
+ const Expressions = __importStar(__webpack_require__(/*! ../abap/2_statements/expressions */ "../core/build/src/abap/2_statements/expressions/index.js"));
87738
+ const Statements = __importStar(__webpack_require__(/*! ../abap/2_statements/statements */ "../core/build/src/abap/2_statements/statements/index.js"));
87739
+ const issue_1 = __webpack_require__(/*! ../issue */ "../core/build/src/issue.js");
87740
+ const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "../core/build/src/rules/_abap_rule.js");
87741
+ const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "../core/build/src/rules/_basic_rule_config.js");
87742
+ const _irule_1 = __webpack_require__(/*! ./_irule */ "../core/build/src/rules/_irule.js");
87743
+ class NoMandtInDatabaseOperationsConf extends _basic_rule_config_1.BasicRuleConfig {
87744
+ }
87745
+ exports.NoMandtInDatabaseOperationsConf = NoMandtInDatabaseOperationsConf;
87746
+ class NoMandtInDatabaseOperations extends _abap_rule_1.ABAPRule {
87747
+ constructor() {
87748
+ super(...arguments);
87749
+ this.conf = new NoMandtInDatabaseOperationsConf();
87750
+ }
87751
+ getMetadata() {
87752
+ return {
87753
+ key: "no_mandt_in_database_operations",
87754
+ title: "No MANDT in database operations",
87755
+ shortDescription: "Do not specify the client in database operations; the ABAP runtime handles it automatically.",
87756
+ extendedInformation: "Only check for the name MANDT, not for the field type. The rule does not check for dynamic SQL.",
87757
+ tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Syntax],
87758
+ badExample: `SELECT * FROM zcustomers
87759
+ CLIENT SPECIFIED
87760
+ WHERE mandt = @sy-mandt
87761
+ INTO TABLE @DATA(customers).`,
87762
+ goodExample: `SELECT * FROM zcustomers
87763
+ INTO TABLE @DATA(customers).`,
87764
+ };
87765
+ }
87766
+ getConfig() {
87767
+ return this.conf;
87768
+ }
87769
+ setConfig(conf) {
87770
+ this.conf = conf;
87771
+ }
87772
+ runParsed(file) {
87773
+ const issues = [];
87774
+ for (const statement of file.getStatements()) {
87775
+ if (this.isDatabaseOperation(statement) === false) {
87776
+ continue;
87777
+ }
87778
+ const mandt = this.findMandtInCondition(statement);
87779
+ if (mandt !== undefined) {
87780
+ const issue = issue_1.Issue.atToken(file, mandt.getFirstToken(), this.getMetadata().title, this.getMetadata().key, this.conf.severity);
87781
+ issues.push(issue);
87782
+ continue;
87783
+ }
87784
+ const explicitClient = this.findExplicitClient(statement);
87785
+ if (explicitClient !== undefined) {
87786
+ const issue = issue_1.Issue.atToken(file, explicitClient, this.getMetadata().title, this.getMetadata().key, this.conf.severity);
87787
+ issues.push(issue);
87788
+ }
87789
+ }
87790
+ return issues;
87791
+ }
87792
+ isDatabaseOperation(statement) {
87793
+ const type = statement.get();
87794
+ return type instanceof Statements.DeleteDatabase
87795
+ || type instanceof Statements.InsertDatabase
87796
+ || type instanceof Statements.MergeDatabase
87797
+ || type instanceof Statements.ModifyDatabase
87798
+ || type instanceof Statements.OpenCursor
87799
+ || type instanceof Statements.Select
87800
+ || type instanceof Statements.SelectLoop
87801
+ || type instanceof Statements.UpdateDatabase
87802
+ || type instanceof Statements.With
87803
+ || type instanceof Statements.WithLoop;
87804
+ }
87805
+ findMandtInCondition(statement) {
87806
+ for (const condition of statement.findAllExpressions(Expressions.SQLCond)) {
87807
+ for (const field of condition.findAllExpressions(Expressions.SQLFieldName)) {
87808
+ const name = field.concatTokens().toUpperCase();
87809
+ if (name === "MANDT" || name.endsWith("~MANDT")) {
87810
+ return field;
87811
+ }
87812
+ }
87813
+ }
87814
+ return undefined;
87815
+ }
87816
+ findExplicitClient(statement) {
87817
+ var _a, _b;
87818
+ const tokens = statement.getTokens();
87819
+ for (let index = 0; index < tokens.length; index++) {
87820
+ const current = tokens[index].getStr().toUpperCase();
87821
+ const next = (_a = tokens[index + 1]) === null || _a === void 0 ? void 0 : _a.getStr().toUpperCase();
87822
+ const afterNext = (_b = tokens[index + 2]) === null || _b === void 0 ? void 0 : _b.getStr().toUpperCase();
87823
+ if ((current === "CLIENT" && next === "SPECIFIED")
87824
+ || (current === "USING" && (next === "CLIENT" || next === "CLIENTS"))
87825
+ || (current === "USING" && next === "ALL" && afterNext === "CLIENTS")) {
87826
+ return current === "CLIENT" ? tokens[index] : tokens[index + (next === "ALL" ? 2 : 1)];
87827
+ }
87828
+ }
87829
+ return undefined;
87830
+ }
87831
+ }
87832
+ exports.NoMandtInDatabaseOperations = NoMandtInDatabaseOperations;
87833
+ //# sourceMappingURL=no_mandt_in_database_operations.js.map
87834
+
87835
+ /***/ },
87836
+
87645
87837
  /***/ "../core/build/src/rules/no_prefixes.js"
87646
87838
  /*!**********************************************!*\
87647
87839
  !*** ../core/build/src/rules/no_prefixes.js ***!
@@ -98382,6 +98574,7 @@ class XMLConsistency {
98382
98574
  extendedInformation: `Checks:
98383
98575
  * XML is well-formed and parseable
98384
98576
  * Naming for CLAS and INTF objects
98577
+ * QUAN fields in TABL objects have reference table and field values
98385
98578
  * Texts and translations do not exceed maximum allowed length.`,
98386
98579
  tags: [_irule_1.RuleTag.Naming, _irule_1.RuleTag.Syntax],
98387
98580
  };
@@ -98396,6 +98589,7 @@ class XMLConsistency {
98396
98589
  return this;
98397
98590
  }
98398
98591
  run(obj) {
98592
+ var _a;
98399
98593
  const issues = [];
98400
98594
  const file = obj.getXMLFile();
98401
98595
  if (file === undefined) {
@@ -98407,6 +98601,14 @@ class XMLConsistency {
98407
98601
  if (res !== true) {
98408
98602
  issues.push(issue_1.Issue.atRow(file, 1, "XML parser error: " + res.err.msg, this.getMetadata().key, this.conf.severity));
98409
98603
  }
98604
+ else {
98605
+ for (const attribute of ["version", "serializer_version"]) {
98606
+ const value = (_a = xml.match(new RegExp(`<abapGit\\b[^>]*\\b${attribute}="([^"]+)"`))) === null || _a === void 0 ? void 0 : _a[1];
98607
+ if (value !== undefined && value.match(/^v\d\.\d\.\d$/) === null) {
98608
+ issues.push(issue_1.Issue.atRow(file, 1, `Unexpected abapGit ${attribute} "${value}"`, this.getMetadata().key, this.conf.severity));
98609
+ }
98610
+ }
98611
+ }
98410
98612
  }
98411
98613
  // todo, have some XML validation in each object?
98412
98614
  if (obj instanceof Objects.Class) {
@@ -98427,6 +98629,9 @@ class XMLConsistency {
98427
98629
  else if (obj instanceof Objects.MessageClass) {
98428
98630
  issues.push(...this.runMessageClass(obj, file));
98429
98631
  }
98632
+ else if (obj instanceof Objects.Table) {
98633
+ issues.push(...this.runTable(obj, file));
98634
+ }
98430
98635
  if (obj instanceof _abap_object_1.ABAPObject) {
98431
98636
  issues.push(...this.runTextPool(obj, file));
98432
98637
  }
@@ -98570,6 +98775,18 @@ class XMLConsistency {
98570
98775
  }
98571
98776
  return issues;
98572
98777
  }
98778
+ runTable(obj, file) {
98779
+ var _a, _b;
98780
+ var _c;
98781
+ const issues = [];
98782
+ for (const field of (_c = obj.getFields()) !== null && _c !== void 0 ? _c : []) {
98783
+ if (field.DATATYPE === "QUAN" && (!((_a = field.REFTABLE) === null || _a === void 0 ? void 0 : _a.trim()) || !((_b = field.REFFIELD) === null || _b === void 0 ? void 0 : _b.trim()))) {
98784
+ const message = `QUAN field ${field.FIELDNAME} must have REFTABLE and REFFIELD set`;
98785
+ issues.push(issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.conf.severity));
98786
+ }
98787
+ }
98788
+ return issues;
98789
+ }
98573
98790
  }
98574
98791
  exports.XMLConsistency = XMLConsistency;
98575
98792
  //# sourceMappingURL=xml_consistency.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/cli",
3
- "version": "2.120.10",
3
+ "version": "2.120.11",
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.10",
42
+ "@abaplint/core": "^2.120.11",
43
43
  "@types/chai": "^4.3.20",
44
44
  "@types/minimist": "^1.2.5",
45
45
  "@types/mocha": "^10.0.10",