@abaplint/core 2.97.17 → 2.98.0

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.
@@ -2958,6 +2958,7 @@ declare interface IGlobalConfig {
2958
2958
  /** input files, glob format */
2959
2959
  files: string;
2960
2960
  skipGeneratedBOPFInterfaces?: boolean;
2961
+ /** Skips generated table maintenances, determined via TOBJ object */
2961
2962
  skipGeneratedFunctionGroups?: boolean;
2962
2963
  skipGeneratedGatewayClasses?: boolean;
2963
2964
  skipGeneratedPersistentClasses?: boolean;
@@ -17,8 +17,12 @@ class Select extends combi_1.Expression {
17
17
  const bypass = (0, combi_1.str)("BYPASSING BUFFER");
18
18
  const fields = (0, combi_1.seq)("FIELDS", _1.SQLFieldList);
19
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);
20
+ const permSingle = (0, combi_1.per)(_1.SQLFrom, sql_into_structure_1.SQLIntoStructure, where, _1.SQLClient, bypass, fields, _1.DatabaseConnection);
20
21
  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));
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));
22
+ const fieldList = (0, combi_1.optPrio)((0, combi_1.altPrio)(_1.SQLFieldList, paren));
23
+ const single = (0, combi_1.seq)("SINGLE", (0, combi_1.optPrio)("FOR UPDATE"), fieldList, permSingle);
24
+ const other = (0, combi_1.seq)((0, combi_1.optPrio)("DISTINCT"), fieldList, perm);
25
+ const ret = (0, combi_1.seq)("SELECT", (0, combi_1.altPrio)(single, other), (0, combi_1.optPrio)(_1.SQLHints));
22
26
  return ret;
23
27
  }
24
28
  }
@@ -63,7 +63,7 @@ class Registry {
63
63
  }
64
64
  static abaplintVersion() {
65
65
  // magic, see build script "version.sh"
66
- return "2.97.17";
66
+ return "2.98.0";
67
67
  }
68
68
  getDDICReferences() {
69
69
  return this.references;
@@ -44,7 +44,7 @@ https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#abap-doc-on
44
44
  var _a, _b;
45
45
  const issues = [];
46
46
  const rows = file.getRawRows();
47
- const regexEmptyTags = '^\\"! .*<[^>]*><';
47
+ const regexEmptyTags = '^\\"! .*<[^/>]*><\\/';
48
48
  const regexEmptyAbapdoc = '^\\"!.+$';
49
49
  const regexEmptyParameterName = '^\\"! @parameter .+\\|';
50
50
  let methods = [];
@@ -21,6 +21,8 @@ class ColonMissingSpace extends _abap_rule_1.ABAPRule {
21
21
  title: "Colon missing space",
22
22
  shortDescription: `Checks for missing spaces after colons in chained statements.`,
23
23
  tags: [_irule_1.RuleTag.Whitespace, _irule_1.RuleTag.Quickfix, _irule_1.RuleTag.SingleFile],
24
+ badExample: `WRITE:hello, world.`,
25
+ goodExample: `WRITE: hello, world.`,
24
26
  };
25
27
  }
26
28
  getMessage() {
@@ -132,6 +132,7 @@ __exportStar(require("./remove_descriptions"), exports);
132
132
  __exportStar(require("./rfc_error_handling"), exports);
133
133
  __exportStar(require("./select_add_order_by"), exports);
134
134
  __exportStar(require("./select_performance"), exports);
135
+ __exportStar(require("./select_single_full_key"), exports);
135
136
  __exportStar(require("./selection_screen_naming"), exports);
136
137
  __exportStar(require("./sequential_blank"), exports);
137
138
  __exportStar(require("./short_case"), exports);
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SelectSingleFullKey = exports.SelectSingleFullKeyConf = void 0;
4
+ const issue_1 = require("../issue");
5
+ const _basic_rule_config_1 = require("./_basic_rule_config");
6
+ const _irule_1 = require("./_irule");
7
+ const __1 = require("..");
8
+ class SelectSingleFullKeyConf extends _basic_rule_config_1.BasicRuleConfig {
9
+ }
10
+ exports.SelectSingleFullKeyConf = SelectSingleFullKeyConf;
11
+ class SelectSingleFullKey {
12
+ constructor() {
13
+ this.conf = new SelectSingleFullKeyConf();
14
+ }
15
+ getMetadata() {
16
+ return {
17
+ key: "select_single_full_key",
18
+ title: "Detect SELECT SINGLE which are possibily not unique",
19
+ shortDescription: `Detect SELECT SINGLE which are possibily not unique`,
20
+ extendedInformation: `Table definitions must be known, ie. inside the errorNamespace`,
21
+ pseudoComment: "EC CI_NOORDER",
22
+ tags: [_irule_1.RuleTag.Experimental],
23
+ };
24
+ }
25
+ initialize(reg) {
26
+ this.reg = reg;
27
+ return this;
28
+ }
29
+ getConfig() {
30
+ return this.conf;
31
+ }
32
+ setConfig(conf) {
33
+ this.conf = conf;
34
+ }
35
+ run(obj) {
36
+ var _a, _b;
37
+ if (!(obj instanceof __1.ABAPObject)) {
38
+ return [];
39
+ }
40
+ const syntax = new __1.SyntaxLogic(this.reg, obj).run();
41
+ if (syntax.issues.length > 0) {
42
+ return [];
43
+ }
44
+ const issues = [];
45
+ const message = "SELECT SINGLE possibily not unique";
46
+ for (const file of obj.getABAPFiles()) {
47
+ const statements = file.getStatements();
48
+ for (let i = 0; i < statements.length; i++) {
49
+ const s = statements[i];
50
+ if (!(s.get() instanceof __1.Statements.Select)) {
51
+ continue;
52
+ }
53
+ else if (s.findTokenSequencePosition("SELECT", "SINGLE") === undefined) {
54
+ continue;
55
+ }
56
+ const databaseTable = s.findFirstExpression(__1.Expressions.DatabaseTable);
57
+ if (databaseTable === undefined) {
58
+ continue;
59
+ }
60
+ const next = statements[i + 1];
61
+ if ((next === null || next === void 0 ? void 0 : next.get()) instanceof __1.Comment && next.concatTokens().includes(this.getMetadata().pseudoComment + "")) {
62
+ continue;
63
+ }
64
+ const tabl = this.findReference(databaseTable.getFirstToken().getStart(), syntax.spaghetti, file);
65
+ const keys = this.reg.getObject("TABL", tabl).listKeys(this.reg);
66
+ const cond = s.findFirstExpression(__1.Expressions.SQLCond);
67
+ const set = new Set(keys);
68
+ for (const compare of (cond === null || cond === void 0 ? void 0 : cond.findAllExpressionsRecursive(__1.Expressions.SQLCompare)) || []) {
69
+ if (compare.getChildren().length === 3) {
70
+ const fname = (_a = compare.findDirectExpression(__1.Expressions.SQLFieldName)) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase();
71
+ const operator = (_b = compare.findDirectExpression(__1.Expressions.SQLCompareOperator)) === null || _b === void 0 ? void 0 : _b.concatTokens().toUpperCase();
72
+ if (fname && (operator === "=" || operator === "EQ")) {
73
+ set.delete(fname);
74
+ }
75
+ }
76
+ }
77
+ if (set.size > 0) {
78
+ issues.push(issue_1.Issue.atStatement(file, s, message, this.getMetadata().key, this.getConfig().severity));
79
+ }
80
+ }
81
+ }
82
+ return issues;
83
+ }
84
+ findReference(position, spaghetti, file) {
85
+ const scope = spaghetti.lookupPosition(position, file.getFilename());
86
+ return scope === null || scope === void 0 ? void 0 : scope.findTableReference(position);
87
+ }
88
+ }
89
+ exports.SelectSingleFullKey = SelectSingleFullKey;
90
+ //# sourceMappingURL=select_single_full_key.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.97.17",
3
+ "version": "2.98.0",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",
@@ -50,7 +50,7 @@
50
50
  "@microsoft/api-extractor": "^7.34.4",
51
51
  "@types/chai": "^4.3.4",
52
52
  "@types/mocha": "^10.0.1",
53
- "@types/node": "^18.15.13",
53
+ "@types/node": "^18.16.1",
54
54
  "chai": "^4.3.7",
55
55
  "eslint": "^8.39.0",
56
56
  "mocha": "^10.2.0",