@abaplint/core 2.113.247 → 2.114.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.
@@ -2023,6 +2023,15 @@ declare class ElseIf_2 implements IStatement {
2023
2023
  getMatcher(): IStatementRunnable;
2024
2024
  }
2025
2025
 
2026
+ declare class EmailTemplate extends AbstractObject {
2027
+ getType(): string;
2028
+ getAllowedNaming(): {
2029
+ maxLength: number;
2030
+ allowNamespace: boolean;
2031
+ };
2032
+ getDescription(): string | undefined;
2033
+ }
2034
+
2026
2035
  export declare class Empty implements IStatement {
2027
2036
  getMatcher(): IStatementRunnable;
2028
2037
  }
@@ -5008,7 +5017,6 @@ declare namespace Objects {
5008
5017
  BRFPlusSystemApplication,
5009
5018
  BSPApplication,
5010
5019
  BusinessAddInImplementation,
5011
- CDSEntityBuffer,
5012
5020
  BusinessCatalogAppAssignment,
5013
5021
  BusinessCatalog,
5014
5022
  BusinessConfigurationMaintenanceObject,
@@ -5017,6 +5025,7 @@ declare namespace Objects {
5017
5025
  BusinessFunctionSetAssignment,
5018
5026
  BusinessObjectModel,
5019
5027
  BusinessObjectType,
5028
+ CDSEntityBuffer,
5020
5029
  ParsedMetadataExtension,
5021
5030
  CDSMetadataExtension,
5022
5031
  CDSType,
@@ -5046,6 +5055,7 @@ declare namespace Objects {
5046
5055
  EcattTestConfiguration,
5047
5056
  EcattTestDataContainer,
5048
5057
  EcattTestScript,
5058
+ EmailTemplate,
5049
5059
  EnhancementImplementation,
5050
5060
  IBadiDefinition,
5051
5061
  EnhancementSpot,
@@ -5142,6 +5152,7 @@ declare namespace Objects {
5142
5152
  TableType,
5143
5153
  EnhancementCategory,
5144
5154
  TableCategory,
5155
+ SecondaryIndex,
5145
5156
  Table,
5146
5157
  TechnicalJobDefinition,
5147
5158
  TransactionVariant,
@@ -5871,6 +5882,11 @@ declare class SearchHelp extends AbstractObject {
5871
5882
  getDescription(): string | undefined;
5872
5883
  }
5873
5884
 
5885
+ declare type SecondaryIndex = {
5886
+ name: string;
5887
+ fields: string[];
5888
+ };
5889
+
5874
5890
  declare class SectionContents implements IStructure {
5875
5891
  getMatcher(): IStructureRunnable;
5876
5892
  }
@@ -6963,6 +6979,7 @@ declare class Table extends AbstractObject {
6963
6979
  private parsedType;
6964
6980
  getType(): string;
6965
6981
  getDescription(): string | undefined;
6982
+ getSecondaryIndexes(): SecondaryIndex[] | undefined;
6966
6983
  getAllowedNaming(): IAllowedNaming;
6967
6984
  setDirty(): void;
6968
6985
  listKeys(reg: IRegistry): string[];
@@ -17,7 +17,7 @@ const _syntax_input_1 = require("../_syntax_input");
17
17
  const isSimple = /^\w+$/;
18
18
  class Select {
19
19
  static runSyntax(node, input, skipImplicitInto = false) {
20
- var _a, _b;
20
+ var _a;
21
21
  const token = node.getFirstToken();
22
22
  let from = node.findDirectExpression(Expressions.SQLFrom);
23
23
  if (from === undefined) {
@@ -38,10 +38,8 @@ class Select {
38
38
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
39
39
  return;
40
40
  }
41
- const isSingle = ((_a = node.getChildren()[1]) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase()) === "SINGLE"
42
- || node.get() instanceof Expressions.SelectLoop;
43
41
  this.checkFields(fields, dbSources, input, node);
44
- this.handleInto(node, input, fields, dbSources, isSingle);
42
+ const intoExpression = this.handleInto(node, input, fields, dbSources);
45
43
  const fae = node.findDirectExpression(Expressions.SQLForAllEntries);
46
44
  if (fae) {
47
45
  input.scope.push(_scope_type_1.ScopeType.OpenSQL, "SELECT", token.getStart(), input.filename);
@@ -55,7 +53,7 @@ class Select {
55
53
  && node.findDirectExpression(Expressions.SQLIntoTable) === undefined
56
54
  && node.findDirectExpression(Expressions.SQLIntoList) === undefined
57
55
  && node.findDirectExpression(Expressions.SQLIntoStructure) === undefined) {
58
- const fields = (_b = node.findFirstExpression(Expressions.SQLAggregation)) === null || _b === void 0 ? void 0 : _b.concatTokens();
56
+ const fields = (_a = node.findFirstExpression(Expressions.SQLAggregation)) === null || _a === void 0 ? void 0 : _a.concatTokens();
59
57
  const c = new RegExp(/^count\(\s*\*\s*\)$/, "i");
60
58
  if (fields === undefined || c.test(fields) === false) {
61
59
  const nameToken = from === null || from === void 0 ? void 0 : from.findDirectExpression(Expressions.SQLFromSource);
@@ -89,8 +87,18 @@ class Select {
89
87
  for (const s of node.findAllExpressions(Expressions.SQLCompare)) {
90
88
  sql_compare_1.SQLCompare.runSyntax(s, input, dbSources);
91
89
  }
92
- for (const s of node.findDirectExpressions(Expressions.SQLOrderBy)) {
93
- sql_order_by_1.SQLOrderBy.runSyntax(s, input);
90
+ const orderBy = node.findDirectExpression(Expressions.SQLOrderBy);
91
+ if (orderBy) {
92
+ sql_order_by_1.SQLOrderBy.runSyntax(orderBy, input);
93
+ const where = node.findDirectExpression(Expressions.SQLCond);
94
+ if (intoExpression
95
+ && where
96
+ && intoExpression.getFirstToken().getStart().isBefore(orderBy.getFirstToken().getStart())
97
+ && where.getFirstToken().getStart().isBefore(orderBy.getFirstToken().getStart())
98
+ && where.getFirstToken().getStart().isBefore(intoExpression.getFirstToken().getStart())) {
99
+ const message = `ORDER BY must be before INTO, after WHERE`;
100
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, orderBy.getFirstToken(), message));
101
+ }
94
102
  }
95
103
  if (this.isStrictMode(node)) {
96
104
  this.strictModeChecks(node, input);
@@ -141,13 +149,14 @@ class Select {
141
149
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
142
150
  }
143
151
  }
144
- static handleInto(node, input, fields, dbSources, _isSingle) {
152
+ static handleInto(node, input, fields, dbSources) {
145
153
  const intoTable = node.findDirectExpression(Expressions.SQLIntoTable);
146
154
  if (intoTable) {
147
155
  const inline = intoTable.findFirstExpression(Expressions.InlineData);
148
156
  if (inline) {
149
157
  inline_data_1.InlineData.runSyntax(inline, input, this.buildTableType(fields, dbSources, input.scope));
150
158
  }
159
+ return intoTable;
151
160
  }
152
161
  const intoStructure = node.findDirectExpression(Expressions.SQLIntoStructure);
153
162
  if (intoStructure) {
@@ -161,6 +170,7 @@ class Select {
161
170
  inline_data_1.InlineData.runSyntax(inline, input, basic_1.VoidType.get("SELECT_todo1"));
162
171
  }
163
172
  }
173
+ return intoStructure;
164
174
  }
165
175
  const intoList = node.findDirectExpression(Expressions.SQLIntoList);
166
176
  if (intoList) {
@@ -200,7 +210,9 @@ class Select {
200
210
  inline_data_1.InlineData.runSyntax(inline, input, type);
201
211
  }
202
212
  }
213
+ return intoList;
203
214
  }
215
+ return undefined;
204
216
  }
205
217
  static checkFields(fields, dbSources, input, node) {
206
218
  if (dbSources.length > 1) {
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EmailTemplate = void 0;
4
+ const _abstract_object_1 = require("./_abstract_object");
5
+ class EmailTemplate extends _abstract_object_1.AbstractObject {
6
+ getType() {
7
+ return "SMTG";
8
+ }
9
+ getAllowedNaming() {
10
+ return {
11
+ maxLength: 60, // todo
12
+ allowNamespace: true,
13
+ };
14
+ }
15
+ getDescription() {
16
+ // todo
17
+ return undefined;
18
+ }
19
+ }
20
+ exports.EmailTemplate = EmailTemplate;
21
+ //# sourceMappingURL=email_template.js.map
@@ -36,7 +36,6 @@ __exportStar(require("./behavior_definition"), exports);
36
36
  __exportStar(require("./brf_plus_system_application"), exports);
37
37
  __exportStar(require("./bsp_application"), exports);
38
38
  __exportStar(require("./business_add_in_implementation"), exports);
39
- __exportStar(require("./cds_entity_buffer"), exports);
40
39
  __exportStar(require("./business_catalog_app_assignment"), exports);
41
40
  __exportStar(require("./business_catalog"), exports);
42
41
  __exportStar(require("./business_configuration_maintenance_object"), exports);
@@ -45,6 +44,7 @@ __exportStar(require("./business_function_assignment"), exports);
45
44
  __exportStar(require("./business_function_set_assignment"), exports);
46
45
  __exportStar(require("./business_object_model"), exports);
47
46
  __exportStar(require("./business_object_type"), exports);
47
+ __exportStar(require("./cds_entity_buffer"), exports);
48
48
  __exportStar(require("./cds_metadata_extension"), exports);
49
49
  __exportStar(require("./cds_type"), exports);
50
50
  __exportStar(require("./change_document"), exports);
@@ -70,6 +70,7 @@ __exportStar(require("./domain"), exports);
70
70
  __exportStar(require("./ecatt_test_configuration"), exports);
71
71
  __exportStar(require("./ecatt_test_data_container"), exports);
72
72
  __exportStar(require("./ecatt_test_script"), exports);
73
+ __exportStar(require("./email_template"), exports);
73
74
  __exportStar(require("./enhancement_implementation"), exports);
74
75
  __exportStar(require("./enhancement_spot"), exports);
75
76
  __exportStar(require("./entity_type"), exports);
@@ -40,6 +40,13 @@ class Table extends _abstract_object_1.AbstractObject {
40
40
  }
41
41
  return (_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.description;
42
42
  }
43
+ getSecondaryIndexes() {
44
+ var _a;
45
+ if (this.parsedData === undefined) {
46
+ this.parseXML();
47
+ }
48
+ return (_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.secondaryIndexes;
49
+ }
43
50
  getAllowedNaming() {
44
51
  let length = 30;
45
52
  const regex = /^((\/[A-Z_\d]{3,8}\/)|[a-zA-Z0-9]{3}|CI_)\w+$/;
@@ -267,7 +274,7 @@ class Table extends _abstract_object_1.AbstractObject {
267
274
  }
268
275
  ///////////////
269
276
  parseXML() {
270
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
277
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
271
278
  const parsed = super.parseRaw2();
272
279
  if (parsed === undefined) {
273
280
  return;
@@ -306,6 +313,25 @@ class Table extends _abstract_object_1.AbstractObject {
306
313
  DDTEXT: field.DDTEXT,
307
314
  });
308
315
  }
316
+ // secondary indexes
317
+ const indexes = (_m = parsed.abapGit["asx:abap"]["asx:values"]) === null || _m === void 0 ? void 0 : _m.DD12V;
318
+ ;
319
+ this.parsedData.secondaryIndexes = [];
320
+ for (const index of (0, xml_utils_1.xmlToArray)(indexes === null || indexes === void 0 ? void 0 : indexes.DD12V)) {
321
+ const indexName = index.INDEXNAME;
322
+ const indexFields = [];
323
+ const indexFieldsXml = (_o = parsed.abapGit["asx:abap"]["asx:values"]) === null || _o === void 0 ? void 0 : _o.DD17V;
324
+ for (const indexField of (0, xml_utils_1.xmlToArray)(indexFieldsXml === null || indexFieldsXml === void 0 ? void 0 : indexFieldsXml.DD17V)) {
325
+ if (indexField.INDEXNAME === indexName) {
326
+ // assumption: fields are listed by POSITION in the xml
327
+ indexFields.push(indexField.FIELDNAME);
328
+ }
329
+ }
330
+ this.parsedData.secondaryIndexes.push({
331
+ name: indexName,
332
+ fields: indexFields,
333
+ });
334
+ }
309
335
  }
310
336
  }
311
337
  exports.Table = Table;
@@ -74,7 +74,7 @@ class Registry {
74
74
  }
75
75
  static abaplintVersion() {
76
76
  // magic, see build script "version.sh"
77
- return "2.113.247";
77
+ return "2.114.0";
78
78
  }
79
79
  getDDICReferences() {
80
80
  return this.ddicReferences;
@@ -83,6 +83,7 @@ __exportStar(require("./implement_methods"), exports);
83
83
  __exportStar(require("./implicit_start_of_selection"), exports);
84
84
  __exportStar(require("./in_statement_indentation"), exports);
85
85
  __exportStar(require("./indentation"), exports);
86
+ __exportStar(require("./index_completely_contained"), exports);
86
87
  __exportStar(require("./inline_data_old_versions"), exports);
87
88
  __exportStar(require("./intf_referencing_clas"), exports);
88
89
  __exportStar(require("./invalid_table_index"), exports);
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IndexCompletelyContained = exports.IndexCompletelyContainedConf = void 0;
4
+ const _basic_rule_config_1 = require("./_basic_rule_config");
5
+ const _irule_1 = require("./_irule");
6
+ const issue_1 = require("../issue");
7
+ const position_1 = require("../position");
8
+ const Objects = require("../objects");
9
+ class IndexCompletelyContainedConf extends _basic_rule_config_1.BasicRuleConfig {
10
+ }
11
+ exports.IndexCompletelyContainedConf = IndexCompletelyContainedConf;
12
+ class IndexCompletelyContained {
13
+ constructor() {
14
+ this.conf = new IndexCompletelyContainedConf();
15
+ }
16
+ getMetadata() {
17
+ return {
18
+ key: "index_completely_contained",
19
+ title: "Check if database table indexes are completely contained",
20
+ shortDescription: `If indexes are completely contained in other indexes, they can be removed to improve performance.`,
21
+ tags: [_irule_1.RuleTag.Performance],
22
+ };
23
+ }
24
+ initialize() {
25
+ return this;
26
+ }
27
+ getConfig() {
28
+ return this.conf;
29
+ }
30
+ setConfig(conf) {
31
+ this.conf = conf;
32
+ }
33
+ run(obj) {
34
+ if (!(obj instanceof Objects.Table)) {
35
+ return [];
36
+ }
37
+ const indexes = obj.getSecondaryIndexes();
38
+ if (indexes === undefined || indexes.length === 0) {
39
+ return [];
40
+ }
41
+ const issues = [];
42
+ for (let i = 0; i < indexes.length; i++) {
43
+ const indexA = indexes[i];
44
+ for (let j = 0; j < indexes.length; j++) {
45
+ if (i === j) {
46
+ continue;
47
+ }
48
+ const indexB = indexes[j];
49
+ let contained = true;
50
+ for (const field of indexA.fields) {
51
+ if (indexB.fields.indexOf(field) === -1) {
52
+ contained = false;
53
+ break;
54
+ }
55
+ }
56
+ if (contained) {
57
+ const position = new position_1.Position(1, 1);
58
+ const message = `Index "${indexA.name}" is completely contained in index "${indexB.name}"`;
59
+ issues.push(issue_1.Issue.atPosition(obj.getFiles()[0], position, message, this.getMetadata().key, this.conf.severity));
60
+ }
61
+ }
62
+ }
63
+ return issues;
64
+ }
65
+ }
66
+ exports.IndexCompletelyContained = IndexCompletelyContained;
67
+ //# sourceMappingURL=index_completely_contained.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.113.247",
3
+ "version": "2.114.0",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",