@abaplint/core 2.83.11 → 2.83.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.
- package/build/abaplint.d.ts +7 -0
- package/build/src/abap/2_statements/expressions/index.js +1 -0
- package/build/src/abap/2_statements/expressions/raise_with.js +13 -0
- package/build/src/abap/2_statements/statements/raise.js +2 -3
- package/build/src/ddic.js +6 -15
- package/build/src/objects/data_definition.js +8 -0
- package/build/src/objects/table.js +8 -2
- package/build/src/registry.js +1 -1
- package/build/src/rules/downport.js +72 -2
- package/build/src/rules/unnecessary_chaining.js +1 -1
- package/package.json +2 -2
package/build/abaplint.d.ts
CHANGED
|
@@ -1242,6 +1242,7 @@ declare class DataDefinition extends AbstractObject {
|
|
|
1242
1242
|
allowNamespace: boolean;
|
|
1243
1243
|
};
|
|
1244
1244
|
getSQLViewName(): string | undefined;
|
|
1245
|
+
getDefinitionName(): string | undefined;
|
|
1245
1246
|
getDescription(): string | undefined;
|
|
1246
1247
|
parseType(reg: IRegistry): AbstractType;
|
|
1247
1248
|
getParsedData(): ParsedDataDefinition | undefined;
|
|
@@ -1879,6 +1880,7 @@ declare namespace Expressions {
|
|
|
1879
1880
|
PerformTables,
|
|
1880
1881
|
PerformUsing,
|
|
1881
1882
|
RadioGroupName,
|
|
1883
|
+
RaiseWith,
|
|
1882
1884
|
ReadTableTarget,
|
|
1883
1885
|
ReceiveParameters,
|
|
1884
1886
|
Redefinition,
|
|
@@ -4079,6 +4081,7 @@ declare class ParenRightW extends Token {
|
|
|
4079
4081
|
|
|
4080
4082
|
declare type ParsedDataDefinition = {
|
|
4081
4083
|
sqlViewName: string | undefined;
|
|
4084
|
+
definitionName: string | undefined;
|
|
4082
4085
|
fields: {
|
|
4083
4086
|
key: boolean;
|
|
4084
4087
|
name: string;
|
|
@@ -4254,6 +4257,10 @@ declare class RaiseEvent implements IStatement {
|
|
|
4254
4257
|
getMatcher(): IStatementRunnable;
|
|
4255
4258
|
}
|
|
4256
4259
|
|
|
4260
|
+
declare class RaiseWith extends Expression {
|
|
4261
|
+
getRunnable(): IStatementRunnable;
|
|
4262
|
+
}
|
|
4263
|
+
|
|
4257
4264
|
declare class Ranges implements IStatement {
|
|
4258
4265
|
getMatcher(): IStatementRunnable;
|
|
4259
4266
|
}
|
|
@@ -128,6 +128,7 @@ __exportStar(require("./perform_changing"), exports);
|
|
|
128
128
|
__exportStar(require("./perform_tables"), exports);
|
|
129
129
|
__exportStar(require("./perform_using"), exports);
|
|
130
130
|
__exportStar(require("./radio_group_name"), exports);
|
|
131
|
+
__exportStar(require("./raise_with"), exports);
|
|
131
132
|
__exportStar(require("./read_table_target"), exports);
|
|
132
133
|
__exportStar(require("./receive_parameters"), exports);
|
|
133
134
|
__exportStar(require("./redefinition"), exports);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RaiseWith = void 0;
|
|
4
|
+
const combi_1 = require("../combi");
|
|
5
|
+
const _1 = require(".");
|
|
6
|
+
class RaiseWith extends combi_1.Expression {
|
|
7
|
+
getRunnable() {
|
|
8
|
+
const wit = (0, combi_1.seq)("WITH", _1.Source, (0, combi_1.opt)(_1.Source), (0, combi_1.opt)(_1.Source), (0, combi_1.opt)(_1.Source));
|
|
9
|
+
return wit;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.RaiseWith = RaiseWith;
|
|
13
|
+
//# sourceMappingURL=raise_with.js.map
|
|
@@ -6,9 +6,8 @@ const version_1 = require("../../../version");
|
|
|
6
6
|
const expressions_1 = require("../expressions");
|
|
7
7
|
class Raise {
|
|
8
8
|
getMatcher() {
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const messid = (0, combi_1.seq)("MESSAGE ID", expressions_1.Source, "NUMBER", expressions_1.Source, (0, combi_1.optPrio)(wit));
|
|
9
|
+
const mess = (0, combi_1.seq)("MESSAGE", expressions_1.MessageSource, (0, combi_1.opt)(expressions_1.RaiseWith));
|
|
10
|
+
const messid = (0, combi_1.seq)("MESSAGE ID", expressions_1.Source, "NUMBER", expressions_1.Source, (0, combi_1.optPrio)(expressions_1.RaiseWith));
|
|
12
11
|
const exporting = (0, combi_1.seq)("EXPORTING", expressions_1.ParameterListS);
|
|
13
12
|
const from = (0, combi_1.seq)("TYPE", expressions_1.ClassName, (0, combi_1.opt)((0, combi_1.alt)((0, combi_1.ver)(version_1.Version.v750, (0, combi_1.alt)(mess, messid)), (0, combi_1.ver)(version_1.Version.v752, "USING MESSAGE"))), (0, combi_1.optPrio)(exporting));
|
|
14
13
|
const clas = (0, combi_1.seq)((0, combi_1.optPrio)("RESUMABLE"), "EXCEPTION", (0, combi_1.altPrio)(from, (0, combi_1.ver)(version_1.Version.v752, expressions_1.Source), expressions_1.SimpleSource2));
|
package/build/src/ddic.js
CHANGED
|
@@ -143,6 +143,7 @@ class DDIC {
|
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
lookupNoVoid(name) {
|
|
146
|
+
var _a;
|
|
146
147
|
const foundTABL = this.reg.getObject("TABL", name);
|
|
147
148
|
if (foundTABL) {
|
|
148
149
|
return { type: foundTABL.parseType(this.reg), object: foundTABL };
|
|
@@ -155,10 +156,6 @@ class DDIC {
|
|
|
155
156
|
if (foundTTYP) {
|
|
156
157
|
return { type: foundTTYP.parseType(this.reg), object: foundTTYP };
|
|
157
158
|
}
|
|
158
|
-
const foundDDLS = this.reg.getObject("DDLS", name);
|
|
159
|
-
if (foundDDLS) {
|
|
160
|
-
return { type: foundDDLS.parseType(this.reg), object: foundDDLS };
|
|
161
|
-
}
|
|
162
159
|
const foundDTEL = this.reg.getObject("DTEL", name);
|
|
163
160
|
if (foundDTEL) {
|
|
164
161
|
return { type: foundDTEL.parseType(this.reg), object: foundDTEL };
|
|
@@ -166,7 +163,7 @@ class DDIC {
|
|
|
166
163
|
const upper = name.toUpperCase();
|
|
167
164
|
for (const obj of this.reg.getObjectsByType("DDLS")) {
|
|
168
165
|
const ddls = obj;
|
|
169
|
-
if (ddls.getSQLViewName() === upper) {
|
|
166
|
+
if (ddls.getSQLViewName() === upper || ((_a = ddls.getDefinitionName()) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === upper) {
|
|
170
167
|
return { type: ddls.parseType(this.reg), object: obj };
|
|
171
168
|
}
|
|
172
169
|
}
|
|
@@ -213,6 +210,7 @@ class DDIC {
|
|
|
213
210
|
}
|
|
214
211
|
}
|
|
215
212
|
lookupTableOrView(name) {
|
|
213
|
+
var _a;
|
|
216
214
|
if (name === undefined) {
|
|
217
215
|
return { type: new Types.UnknownType("undefined, lookupTableOrView") };
|
|
218
216
|
}
|
|
@@ -220,20 +218,17 @@ class DDIC {
|
|
|
220
218
|
if (foundTABL) {
|
|
221
219
|
return { type: foundTABL.parseType(this.reg), object: foundTABL };
|
|
222
220
|
}
|
|
223
|
-
const foundDDLS = this.reg.getObject("DDLS", name);
|
|
224
|
-
if (foundDDLS) {
|
|
225
|
-
return { type: foundDDLS.parseType(this.reg), object: foundDDLS };
|
|
226
|
-
}
|
|
227
221
|
const upper = name.toUpperCase();
|
|
228
222
|
for (const obj of this.reg.getObjectsByType("DDLS")) {
|
|
229
223
|
const ddls = obj;
|
|
230
|
-
if (ddls.getSQLViewName() === upper) {
|
|
224
|
+
if (ddls.getSQLViewName() === upper || ((_a = ddls.getDefinitionName()) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === upper) {
|
|
231
225
|
return { type: ddls.parseType(this.reg), object: ddls };
|
|
232
226
|
}
|
|
233
227
|
}
|
|
234
228
|
return this.lookupView(name);
|
|
235
229
|
}
|
|
236
230
|
lookupTableOrView2(name) {
|
|
231
|
+
var _a;
|
|
237
232
|
if (name === undefined) {
|
|
238
233
|
return undefined;
|
|
239
234
|
}
|
|
@@ -245,14 +240,10 @@ class DDIC {
|
|
|
245
240
|
if (foundVIEW) {
|
|
246
241
|
return foundVIEW;
|
|
247
242
|
}
|
|
248
|
-
const foundDDLS = this.reg.getObject("DDLS", name);
|
|
249
|
-
if (foundDDLS) {
|
|
250
|
-
return foundDDLS;
|
|
251
|
-
}
|
|
252
243
|
const upper = name.toUpperCase();
|
|
253
244
|
for (const obj of this.reg.getObjectsByType("DDLS")) {
|
|
254
245
|
const ddls = obj;
|
|
255
|
-
if (ddls.getSQLViewName() === upper) {
|
|
246
|
+
if (ddls.getSQLViewName() === upper || ((_a = ddls.getDefinitionName()) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === upper) {
|
|
256
247
|
return ddls;
|
|
257
248
|
}
|
|
258
249
|
}
|
|
@@ -25,6 +25,11 @@ class DataDefinition extends _abstract_object_1.AbstractObject {
|
|
|
25
25
|
this.parse();
|
|
26
26
|
return (_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.sqlViewName;
|
|
27
27
|
}
|
|
28
|
+
getDefinitionName() {
|
|
29
|
+
var _a;
|
|
30
|
+
this.parse();
|
|
31
|
+
return (_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.definitionName;
|
|
32
|
+
}
|
|
28
33
|
getDescription() {
|
|
29
34
|
// todo
|
|
30
35
|
return undefined;
|
|
@@ -53,12 +58,14 @@ class DataDefinition extends _abstract_object_1.AbstractObject {
|
|
|
53
58
|
return this.parserError;
|
|
54
59
|
}
|
|
55
60
|
parse() {
|
|
61
|
+
var _a, _b;
|
|
56
62
|
if (this.isDirty() === false) {
|
|
57
63
|
return { updated: false, runtime: 0 };
|
|
58
64
|
}
|
|
59
65
|
const start = Date.now();
|
|
60
66
|
this.parsedData = {
|
|
61
67
|
sqlViewName: undefined,
|
|
68
|
+
definitionName: undefined,
|
|
62
69
|
fields: [],
|
|
63
70
|
sources: [],
|
|
64
71
|
relations: [],
|
|
@@ -68,6 +75,7 @@ class DataDefinition extends _abstract_object_1.AbstractObject {
|
|
|
68
75
|
this.findSQLViewName();
|
|
69
76
|
this.parsedData.tree = new cds_parser_1.CDSParser().parse(this.findSourceFile());
|
|
70
77
|
if (this.parsedData.tree) {
|
|
78
|
+
this.parsedData.definitionName = (_b = (_a = this.parsedData.tree) === null || _a === void 0 ? void 0 : _a.findFirstExpression(expressions_1.CDSName)) === null || _b === void 0 ? void 0 : _b.getFirstToken().getStr();
|
|
71
79
|
this.findSourcesAndRelations(this.parsedData.tree);
|
|
72
80
|
this.findFieldNames(this.parsedData.tree);
|
|
73
81
|
}
|
|
@@ -90,8 +90,13 @@ class Table extends _abstract_object_1.AbstractObject {
|
|
|
90
90
|
found = found.getType();
|
|
91
91
|
}
|
|
92
92
|
if (found instanceof Types.StructureType) {
|
|
93
|
-
|
|
94
|
-
components.push({ name:
|
|
93
|
+
if (field.GROUPNAME !== undefined) {
|
|
94
|
+
components.push({ name: field.GROUPNAME, type: found });
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
for (const c of found.getComponents()) {
|
|
98
|
+
components.push({ name: c.name, type: c.type });
|
|
99
|
+
}
|
|
95
100
|
}
|
|
96
101
|
}
|
|
97
102
|
else if ((((_a = field.PRECFIELD) === null || _a === void 0 ? void 0 : _a.startsWith("CI_")) || ((_b = field.PRECFIELD) === null || _b === void 0 ? void 0 : _b.startsWith("SI_")))
|
|
@@ -241,6 +246,7 @@ class Table extends _abstract_object_1.AbstractObject {
|
|
|
241
246
|
DATATYPE: field.DATATYPE,
|
|
242
247
|
DECIMALS: field.DECIMALS,
|
|
243
248
|
KEYFLAG: field.KEYFLAG,
|
|
249
|
+
GROUPNAME: field.GROUPNAME,
|
|
244
250
|
});
|
|
245
251
|
}
|
|
246
252
|
}
|
package/build/src/registry.js
CHANGED
|
@@ -19,7 +19,8 @@ const _typed_identifier_1 = require("../abap/types/_typed_identifier");
|
|
|
19
19
|
const basic_1 = require("../abap/types/basic");
|
|
20
20
|
const config_1 = require("../config");
|
|
21
21
|
const tokens_1 = require("../abap/1_lexer/tokens");
|
|
22
|
-
// todo: refactor each sub-rule to new classes
|
|
22
|
+
// todo: refactor each sub-rule to new classes?
|
|
23
|
+
// todo: add configuration
|
|
23
24
|
class DownportConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
24
25
|
}
|
|
25
26
|
exports.DownportConf = DownportConf;
|
|
@@ -52,6 +53,8 @@ Current rules:
|
|
|
52
53
|
* SELECT INTO @DATA definitions are outlined
|
|
53
54
|
* Some occurrences of string template formatting option ALPHA changed to function module call
|
|
54
55
|
* SELECT/INSERT/MODIFY/DELETE/UPDATE "," in field list removed, "@" in source/targets removed
|
|
56
|
+
* PARTIALLY IMPLEMENTED removed, it can be quick fixed via rule implement_methods
|
|
57
|
+
* RAISE EXCEPTION ... MESSAGE
|
|
55
58
|
|
|
56
59
|
Only one transformation is applied to a statement at a time, so multiple steps might be required to do the full downport.`,
|
|
57
60
|
tags: [_irule_1.RuleTag.Experimental, _irule_1.RuleTag.Downport, _irule_1.RuleTag.Quickfix],
|
|
@@ -143,7 +146,15 @@ Only one transformation is applied to a statement at a time, so multiple steps m
|
|
|
143
146
|
if (low.getFirstToken().getStart() instanceof position_1.VirtualPosition) {
|
|
144
147
|
return undefined;
|
|
145
148
|
}
|
|
146
|
-
let found = this.
|
|
149
|
+
let found = this.partiallyImplemented(high, lowFile);
|
|
150
|
+
if (found) {
|
|
151
|
+
return found;
|
|
152
|
+
}
|
|
153
|
+
found = this.raiseException(high, lowFile, highSyntax);
|
|
154
|
+
if (found) {
|
|
155
|
+
return found;
|
|
156
|
+
}
|
|
157
|
+
found = this.emptyKey(high, lowFile);
|
|
147
158
|
if (found) {
|
|
148
159
|
return found;
|
|
149
160
|
}
|
|
@@ -428,6 +439,65 @@ ${indentation}`);
|
|
|
428
439
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
429
440
|
return issue_1.Issue.atToken(lowFile, node.getFirstToken(), "Outline DATA", this.getMetadata().key, this.conf.severity, fix);
|
|
430
441
|
}
|
|
442
|
+
partiallyImplemented(node, lowFile) {
|
|
443
|
+
if (node.get() instanceof Statements.InterfaceDef) {
|
|
444
|
+
const partially = node.findDirectTokenByText("PARTIALLY");
|
|
445
|
+
if (partially === undefined) {
|
|
446
|
+
return undefined;
|
|
447
|
+
}
|
|
448
|
+
const implemented = node.findDirectTokenByText("IMPLEMENTED");
|
|
449
|
+
if (implemented === undefined) {
|
|
450
|
+
return undefined;
|
|
451
|
+
}
|
|
452
|
+
const fix = edit_helper_1.EditHelper.deleteRange(lowFile, partially.getStart(), implemented.getEnd());
|
|
453
|
+
return issue_1.Issue.atToken(lowFile, partially, "Downport PARTIALLY IMPLEMENTED", this.getMetadata().key, this.conf.severity, fix);
|
|
454
|
+
}
|
|
455
|
+
return undefined;
|
|
456
|
+
}
|
|
457
|
+
raiseException(node, lowFile, highSyntax) {
|
|
458
|
+
/*
|
|
459
|
+
Note: IF_T100_DYN_MSG does not exist in 702, so this rule is mostly relevant for the transpiler
|
|
460
|
+
|
|
461
|
+
DATA foo LIKE if_t100_message=>t100key.
|
|
462
|
+
foo-msgid = 'ZHVAM'.
|
|
463
|
+
foo-msgno = '001'.
|
|
464
|
+
foo-attr1 = 'IF_T100_DYN_MSG~MSGV1'.
|
|
465
|
+
foo-attr2 = 'IF_T100_DYN_MSG~MSGV2'.
|
|
466
|
+
foo-attr3 = 'IF_T100_DYN_MSG~MSGV3'.
|
|
467
|
+
foo-attr4 = 'IF_T100_DYN_MSG~MSGV4'.
|
|
468
|
+
DATA bar TYPE REF TO zcl_hvam_exception.
|
|
469
|
+
CREATE OBJECT bar EXPORTING textid = foo.
|
|
470
|
+
bar->if_t100_dyn_msg~msgty = 'E'.
|
|
471
|
+
bar->if_t100_dyn_msg~msgv1 = 'abc'.
|
|
472
|
+
bar->if_t100_dyn_msg~msgv2 = 'abc'.
|
|
473
|
+
bar->if_t100_dyn_msg~msgv3 = 'abc'.
|
|
474
|
+
bar->if_t100_dyn_msg~msgv4 = 'abc'.
|
|
475
|
+
RAISE EXCEPTION bar.
|
|
476
|
+
*/
|
|
477
|
+
var _a;
|
|
478
|
+
if (node.get() instanceof Statements.Raise) {
|
|
479
|
+
const startToken = node.findDirectTokenByText("ID");
|
|
480
|
+
if (startToken === undefined) {
|
|
481
|
+
return undefined;
|
|
482
|
+
}
|
|
483
|
+
const sources = node.findDirectExpressions(Expressions.Source);
|
|
484
|
+
const id = sources[0].concatTokens();
|
|
485
|
+
const number = sources[1].concatTokens();
|
|
486
|
+
const className = ((_a = node.findDirectExpression(Expressions.ClassName)) === null || _a === void 0 ? void 0 : _a.concatTokens()) || "ERROR";
|
|
487
|
+
const uniqueName1 = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
488
|
+
const uniqueName2 = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
489
|
+
const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
490
|
+
const abap = `DATA ${uniqueName1} LIKE if_t100_message=>t100key.
|
|
491
|
+
${indentation}${uniqueName1}-msgid = ${id}.
|
|
492
|
+
${indentation}${uniqueName1}-msgno = ${number}.
|
|
493
|
+
${indentation}DATA ${uniqueName2} TYPE REF TO ${className}.
|
|
494
|
+
${indentation}CREATE OBJECT ${uniqueName2} EXPORTING textid = ${uniqueName1}.
|
|
495
|
+
${indentation}RAISE EXCEPTION ${uniqueName2}.`;
|
|
496
|
+
const fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getStart(), node.getEnd(), abap);
|
|
497
|
+
return issue_1.Issue.atToken(lowFile, startToken, "Downport RAISE MESSAGE", this.getMetadata().key, this.conf.severity, fix);
|
|
498
|
+
}
|
|
499
|
+
return undefined;
|
|
500
|
+
}
|
|
431
501
|
emptyKey(node, lowFile) {
|
|
432
502
|
for (let i of node.findAllExpressions(Expressions.TypeTable)) {
|
|
433
503
|
const key = i.findDirectExpression(Expressions.TypeTableKey);
|
|
@@ -58,7 +58,7 @@ class UnnecessaryChaining extends _abap_rule_1.ABAPRule {
|
|
|
58
58
|
}
|
|
59
59
|
const fix = edit_helper_1.EditHelper.deleteRange(file, colon.getStart(), colon.getEnd());
|
|
60
60
|
const message = "Unnecessary chaining";
|
|
61
|
-
const issue = issue_1.Issue.
|
|
61
|
+
const issue = issue_1.Issue.atToken(file, colon, message, this.getMetadata().key, this.conf.severity, fix);
|
|
62
62
|
issues.push(issue);
|
|
63
63
|
}
|
|
64
64
|
return issues;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/core",
|
|
3
|
-
"version": "2.83.
|
|
3
|
+
"version": "2.83.15",
|
|
4
4
|
"description": "abaplint - Core API",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/abaplint.d.ts",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"chai": "^4.3.4",
|
|
53
53
|
"eslint": "^8.5.0",
|
|
54
54
|
"mocha": "^9.1.3",
|
|
55
|
-
"c8": "^7.
|
|
55
|
+
"c8": "^7.11.0",
|
|
56
56
|
"source-map-support": "^0.5.21",
|
|
57
57
|
"ts-json-schema-generator": "^0.97.0",
|
|
58
58
|
"typescript": "^4.5.4"
|