@abaplint/core 2.91.2 → 2.91.5

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.
@@ -2741,9 +2741,9 @@ declare interface IFunctionModuleParameter {
2741
2741
  declare interface IGlobalConfig {
2742
2742
  /** input files, glob format */
2743
2743
  files: string;
2744
- skipGeneratedGatewayClasses: boolean;
2745
- skipGeneratedPersistentClasses: boolean;
2746
- skipGeneratedFunctionGroups: boolean;
2744
+ skipGeneratedGatewayClasses?: boolean;
2745
+ skipGeneratedPersistentClasses?: boolean;
2746
+ skipGeneratedFunctionGroups?: boolean;
2747
2747
  /** Clone and parse dependencies specified in .apack-manifest.xml if it is present */
2748
2748
  useApackDependencies?: boolean;
2749
2749
  /** Do not report any issues for includes without main programs */
@@ -14,10 +14,9 @@ class Select extends combi_1.Expression {
14
14
  const into = (0, combi_1.altPrio)(_1.SQLIntoTable, sql_into_structure_1.SQLIntoStructure);
15
15
  const where = (0, combi_1.seq)("WHERE", _1.SQLCond);
16
16
  const offset = (0, combi_1.ver)(version_1.Version.v751, (0, combi_1.seq)("OFFSET", _1.SQLSource));
17
- const client = (0, combi_1.str)("CLIENT SPECIFIED");
18
17
  const bypass = (0, combi_1.str)("BYPASSING BUFFER");
19
18
  const fields = (0, combi_1.seq)("FIELDS", _1.SQLFieldList);
20
- const perm = (0, combi_1.per)(_1.SQLFrom, into, _1.SQLForAllEntries, where, _1.SQLOrderBy, sql_up_to_1.SQLUpTo, offset, client, _1.SQLHaving, bypass, sql_group_by_1.SQLGroupBy, fields, _1.DatabaseConnection);
19
+ const perm = (0, combi_1.per)(_1.SQLFrom, into, _1.SQLForAllEntries, where, _1.SQLOrderBy, sql_up_to_1.SQLUpTo, offset, _1.SQLClient, _1.SQLHaving, bypass, sql_group_by_1.SQLGroupBy, fields, _1.DatabaseConnection);
21
20
  const paren = (0, combi_1.seq)((0, combi_1.tok)(tokens_1.WParenLeftW), sql_field_name_1.SQLFieldName, (0, combi_1.tok)(tokens_1.WParenRightW));
22
21
  const ret = (0, combi_1.seq)("SELECT", (0, combi_1.altPrio)("DISTINCT", (0, combi_1.optPrio)((0, combi_1.seq)("SINGLE", (0, combi_1.optPrio)("FOR UPDATE")))), (0, combi_1.optPrio)((0, combi_1.altPrio)(_1.SQLFieldList, paren)), perm, (0, combi_1.optPrio)(_1.SQLHints));
23
22
  return ret;
@@ -13,11 +13,10 @@ const sql_up_to_1 = require("./sql_up_to");
13
13
  class SelectLoop extends combi_1.Expression {
14
14
  getRunnable() {
15
15
  const where = (0, combi_1.seq)("WHERE", _1.SQLCond);
16
- const client = "CLIENT SPECIFIED";
17
16
  const bypass = "BYPASSING BUFFER";
18
17
  const pack = (0, combi_1.seq)("PACKAGE SIZE", _1.SQLSource);
19
18
  const tab = (0, combi_1.seq)(_1.SQLIntoTable, (0, combi_1.alt)(pack, (0, combi_1.seq)(_1.SQLFrom, pack), (0, combi_1.seq)(pack, _1.SQLFrom)));
20
- const perm = (0, combi_1.per)(_1.SQLFrom, where, sql_up_to_1.SQLUpTo, sql_order_by_1.SQLOrderBy, sql_having_1.SQLHaving, client, bypass, _1.SQLGroupBy, _1.SQLForAllEntries, (0, combi_1.alt)(tab, sql_into_structure_1.SQLIntoStructure));
19
+ const perm = (0, combi_1.per)(_1.SQLFrom, where, sql_up_to_1.SQLUpTo, sql_order_by_1.SQLOrderBy, sql_having_1.SQLHaving, _1.SQLClient, bypass, _1.SQLGroupBy, _1.SQLForAllEntries, (0, combi_1.alt)(tab, sql_into_structure_1.SQLIntoStructure));
21
20
  const strict = (0, combi_1.seq)(_1.SQLFrom, "FIELDS", sql_field_list_1.SQLFieldList, where, sql_into_structure_1.SQLIntoStructure, sql_up_to_1.SQLUpTo);
22
21
  const ret = (0, combi_1.seq)("SELECT", (0, combi_1.altPrio)((0, combi_1.seq)((0, combi_1.optPrio)("DISTINCT"), sql_field_list_loop_1.SQLFieldListLoop, perm), strict), (0, combi_1.optPrio)(sql_hints_1.SQLHints));
23
22
  return ret;
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SQLClient = void 0;
4
+ const version_1 = require("../../../version");
4
5
  const combi_1 = require("../combi");
5
6
  const sql_source_simple_1 = require("./sql_source_simple");
6
7
  class SQLClient extends combi_1.Expression {
7
8
  getRunnable() {
8
9
  // todo, client specified and connection not possible in Cloud
9
- const client = (0, combi_1.alt)("CLIENT SPECIFIED", (0, combi_1.seq)("USING CLIENT", sql_source_simple_1.SQLSourceSimple));
10
+ const client = (0, combi_1.alt)("CLIENT SPECIFIED", (0, combi_1.seq)("USING", (0, combi_1.alt)((0, combi_1.ver)(version_1.Version.v740sp05, (0, combi_1.seq)("CLIENT", sql_source_simple_1.SQLSourceSimple)), (0, combi_1.ver)(version_1.Version.v754, (0, combi_1.seq)("CLIENTS IN", (0, combi_1.alt)(sql_source_simple_1.SQLSourceSimple, "T000"))), (0, combi_1.ver)(version_1.Version.v754, "ALL CLIENTS"))));
10
11
  return client;
11
12
  }
12
13
  }
@@ -6,11 +6,10 @@ const expressions_1 = require("../expressions");
6
6
  const tokens_1 = require("../../1_lexer/tokens");
7
7
  class InsertDatabase {
8
8
  getMatcher() {
9
- const client = (0, combi_1.str)("CLIENT SPECIFIED");
10
9
  const sub = (0, combi_1.seq)((0, combi_1.tok)(tokens_1.WParenLeftW), expressions_1.Select, (0, combi_1.tok)(tokens_1.WParenRightW));
11
- const f = (0, combi_1.seq)((0, combi_1.opt)(client), (0, combi_1.opt)(expressions_1.DatabaseConnection), "FROM", (0, combi_1.opt)("TABLE"), (0, combi_1.alt)(expressions_1.SQLSource, sub), (0, combi_1.opt)("ACCEPTING DUPLICATE KEYS"));
12
- const from = (0, combi_1.seq)(expressions_1.DatabaseTable, (0, combi_1.opt)((0, combi_1.alt)(f, client, expressions_1.DatabaseConnection)));
13
- const into = (0, combi_1.seq)("INTO", expressions_1.DatabaseTable, (0, combi_1.opt)("CLIENT SPECIFIED"), (0, combi_1.opt)(expressions_1.DatabaseConnection), "VALUES", expressions_1.SQLSource);
10
+ const f = (0, combi_1.seq)((0, combi_1.opt)(expressions_1.SQLClient), (0, combi_1.opt)(expressions_1.DatabaseConnection), "FROM", (0, combi_1.opt)("TABLE"), (0, combi_1.alt)(expressions_1.SQLSource, sub), (0, combi_1.opt)("ACCEPTING DUPLICATE KEYS"));
11
+ const from = (0, combi_1.seq)(expressions_1.DatabaseTable, (0, combi_1.opt)((0, combi_1.alt)(f, expressions_1.SQLClient, expressions_1.DatabaseConnection)));
12
+ const into = (0, combi_1.seq)("INTO", expressions_1.DatabaseTable, (0, combi_1.opt)(expressions_1.SQLClient), (0, combi_1.opt)(expressions_1.DatabaseConnection), "VALUES", expressions_1.SQLSource);
14
13
  return (0, combi_1.seq)("INSERT", (0, combi_1.alt)(from, into));
15
14
  }
16
15
  }
@@ -6,8 +6,7 @@ const expressions_1 = require("../expressions");
6
6
  class ModifyDatabase {
7
7
  getMatcher() {
8
8
  const from = (0, combi_1.seq)("FROM", (0, combi_1.opt)("TABLE"), expressions_1.SQLSource);
9
- const client = (0, combi_1.str)("CLIENT SPECIFIED");
10
- const options = (0, combi_1.per)(expressions_1.DatabaseConnection, from, client);
9
+ const options = (0, combi_1.per)(expressions_1.DatabaseConnection, from, expressions_1.SQLClient);
11
10
  return (0, combi_1.seq)("MODIFY", expressions_1.DatabaseTable, options);
12
11
  }
13
12
  }
@@ -68,7 +68,7 @@ class Registry {
68
68
  }
69
69
  static abaplintVersion() {
70
70
  // magic, see build script "version.sh"
71
- return "2.91.2";
71
+ return "2.91.5";
72
72
  }
73
73
  getDDICReferences() {
74
74
  return this.references;
@@ -65,6 +65,8 @@ class ObsoleteStatementConf extends _basic_rule_config_1.BasicRuleConfig {
65
65
  this.regex = true;
66
66
  /** Check for OCCURENCES vs OCCURRENCES usage */
67
67
  this.occurences = true;
68
+ /** Check for CLIENT SPECIFIED */
69
+ this.clientSpecified = true;
68
70
  }
69
71
  }
70
72
  exports.ObsoleteStatementConf = ObsoleteStatementConf;
@@ -119,7 +121,9 @@ CALL TRANSFORMATION OBJECTS: https://help.sap.com/doc/abapdocu_752_index_htm/7.5
119
121
 
120
122
  POSIX REGEX: https://help.sap.com/doc/abapdocu_755_index_htm/7.55/en-US/index.htm
121
123
 
122
- OCCURENCES: check for OCCURENCES vs OCCURRENCES`,
124
+ OCCURENCES: check for OCCURENCES vs OCCURRENCES
125
+
126
+ CLIENT SPECIFIED, from 754: https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abapselect_client_obsolete.htm`,
123
127
  };
124
128
  }
125
129
  getConfig() {
@@ -229,7 +233,7 @@ OCCURENCES: check for OCCURENCES vs OCCURRENCES`,
229
233
  }
230
234
  if (this.conf.withHeaderLine === true && sta instanceof Statements.Data) {
231
235
  if (staNode.concatTokens().toUpperCase().includes("WITH HEADER LINE")) {
232
- const token = staNode.getFirstToken();
236
+ const token = staNode.getTokens().find(t => t.getStr().toUpperCase() === "WITH");
233
237
  if (token) {
234
238
  const issue = issue_1.Issue.atToken(file, token, "WITH HEADER LINE is obsolete", this.getMetadata().key, this.conf.severity);
235
239
  issues.push(issue);
@@ -283,6 +287,19 @@ OCCURENCES: check for OCCURENCES vs OCCURRENCES`,
283
287
  issues.push(issue);
284
288
  }
285
289
  }
290
+ if (configVersion >= version_1.Version.v754 && this.conf.clientSpecified
291
+ && (sta instanceof Statements.Select
292
+ || sta instanceof Statements.SelectLoop
293
+ || sta instanceof Statements.DeleteDatabase
294
+ || sta instanceof Statements.InsertDatabase
295
+ || sta instanceof Statements.ModifyDatabase
296
+ || sta instanceof Statements.UpdateDatabase)) {
297
+ const concat = staNode.concatTokens().toUpperCase();
298
+ if (concat.includes(" CLIENT SPECIFIED")) {
299
+ const issue = issue_1.Issue.atStatement(file, staNode, "Use USING CLIENT", this.getMetadata().key, this.conf.severity);
300
+ issues.push(issue);
301
+ }
302
+ }
286
303
  if (configVersion >= version_1.Version.v756 && this.conf.regex) {
287
304
  if (sta instanceof Statements.Find || sta instanceof Statements.Replace) {
288
305
  if ((_c = staNode.findFirstExpression(Expressions.FindType)) === null || _c === void 0 ? void 0 : _c.concatTokens().includes("REGEX")) {
@@ -36,6 +36,11 @@ class SelectPerformance {
36
36
 
37
37
  SELECT *: not reported if using INTO/APPENDING CORRESPONDING FIELDS OF`,
38
38
  tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Performance],
39
+ badExample: `SELECT field1, field2 FROM table
40
+ INTO @DATA(structure) UP TO 1 ROWS ORDER BY field3 DESCENDING.
41
+ ENDSELECT.`,
42
+ goodExample: `SELECT field1, field2 FROM table UP TO 1 ROWS
43
+ INTO TABLE @DATA(table) ORDER BY field3 DESCENDING`,
39
44
  };
40
45
  }
41
46
  initialize(reg) {
@@ -15,6 +15,8 @@ class SelectionScreenNamingConf extends _naming_rule_config_1.NamingRuleConfig {
15
15
  this.parameter = "^P_.+$";
16
16
  /** The pattern for selection-screen select-options */
17
17
  this.selectOption = "^S_.+$";
18
+ /** The pattern for selection-screen screen elements */
19
+ this.screenElement = "^SC_.+$";
18
20
  }
19
21
  }
20
22
  exports.SelectionScreenNamingConf = SelectionScreenNamingConf;
@@ -49,15 +51,20 @@ class SelectionScreenNaming extends _abap_rule_1.ABAPRule {
49
51
  }
50
52
  let parameterCheckDisabled = false;
51
53
  let selectOptionDisabled = false;
54
+ let screenElementDisabled = false;
52
55
  if (this.conf.parameter === undefined || this.conf.parameter.length === 0) {
53
56
  parameterCheckDisabled = true;
54
57
  }
55
58
  if (this.conf.selectOption === undefined || this.conf.selectOption.length === 0) {
56
59
  selectOptionDisabled = true;
57
60
  }
61
+ if (this.conf.screenElement === undefined || this.conf.screenElement.length === 0) {
62
+ screenElementDisabled = true;
63
+ }
58
64
  for (const stat of file.getStatements()) {
59
65
  if ((stat.get() instanceof statements_1.Parameter && !parameterCheckDisabled)
60
- || (stat.get() instanceof statements_1.SelectOption && !selectOptionDisabled)) {
66
+ || (stat.get() instanceof statements_1.SelectOption && !selectOptionDisabled)
67
+ || (stat.get() instanceof statements_1.SelectionScreen && !screenElementDisabled)) {
61
68
  const fieldNode = this.getFieldForStatementNode(stat);
62
69
  const regex = new RegExp(this.getPatternForStatement(stat.get()), "i");
63
70
  if (fieldNode && name_validator_1.NameValidator.violatesRule(fieldNode.getFirstToken().getStr(), regex, this.conf)) {
@@ -75,6 +82,9 @@ class SelectionScreenNaming extends _abap_rule_1.ABAPRule {
75
82
  else if (statement instanceof statements_1.SelectOption) {
76
83
  pattern = this.conf.selectOption;
77
84
  }
85
+ else if (statement instanceof statements_1.SelectionScreen) {
86
+ pattern = this.conf.screenElement;
87
+ }
78
88
  return pattern;
79
89
  }
80
90
  getFieldForStatementNode(statNode) {
@@ -84,6 +94,9 @@ class SelectionScreenNaming extends _abap_rule_1.ABAPRule {
84
94
  else if (statNode.get() instanceof statements_1.SelectOption) {
85
95
  return statNode.findFirstExpression(expressions_1.FieldSub);
86
96
  }
97
+ else if (statNode.get() instanceof statements_1.SelectionScreen) {
98
+ return statNode.findFirstExpression(expressions_1.InlineField);
99
+ }
87
100
  else {
88
101
  return undefined;
89
102
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.91.2",
3
+ "version": "2.91.5",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",
@@ -45,17 +45,17 @@
45
45
  },
46
46
  "homepage": "https://abaplint.org",
47
47
  "devDependencies": {
48
- "@microsoft/api-extractor": "^7.24.2",
48
+ "@microsoft/api-extractor": "^7.28.2",
49
49
  "@types/chai": "^4.3.1",
50
50
  "@types/mocha": "^9.1.1",
51
- "@types/node": "^17.0.40",
51
+ "@types/node": "^18.0.0",
52
52
  "chai": "^4.3.6",
53
- "eslint": "^8.17.0",
53
+ "eslint": "^8.18.0",
54
54
  "mocha": "^10.0.0",
55
55
  "c8": "^7.11.3",
56
56
  "source-map-support": "^0.5.21",
57
57
  "ts-json-schema-generator": "^1.0.0",
58
- "typescript": "^4.7.3"
58
+ "typescript": "^4.7.4"
59
59
  },
60
60
  "dependencies": {
61
61
  "fast-xml-parser": "^4.0.8",