@abaplint/transpiler-cli 2.14.6 → 2.14.7
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/bundle.js +719 -95
- package/package.json +3 -3
package/build/bundle.js
CHANGED
|
@@ -4135,7 +4135,7 @@ class ExpandMacros {
|
|
|
4135
4135
|
listMacroNames() {
|
|
4136
4136
|
return this.macros.listMacroNames();
|
|
4137
4137
|
}
|
|
4138
|
-
find(statements, file, clear = true) {
|
|
4138
|
+
find(statements, file, clear = true, includePath = new Set()) {
|
|
4139
4139
|
var _a, _b, _c;
|
|
4140
4140
|
let nameToken = undefined;
|
|
4141
4141
|
let start = undefined;
|
|
@@ -4156,14 +4156,16 @@ class ExpandMacros {
|
|
|
4156
4156
|
else if (type instanceof Statements.Include) {
|
|
4157
4157
|
const includeName = (_b = statement.findDirectExpression(Expressions.IncludeName)) === null || _b === void 0 ? void 0 : _b.concatTokens();
|
|
4158
4158
|
// todo, this does not take function module includes into account
|
|
4159
|
-
// todo, workaround for cyclic includes?
|
|
4160
4159
|
const prog = (_c = this.reg) === null || _c === void 0 ? void 0 : _c.getObject("PROG", includeName);
|
|
4161
4160
|
if (prog) {
|
|
4162
4161
|
prog.parse(this.release, this.globalMacros, this.reg, this.languageVersion);
|
|
4163
4162
|
const includeMainFile = prog.getMainABAPFile();
|
|
4164
|
-
|
|
4163
|
+
// an include that is already on the current include path is not walked again
|
|
4164
|
+
if (includeMainFile && includePath.has(includeMainFile.getFilename()) === false) {
|
|
4165
|
+
includePath.add(includeMainFile.getFilename());
|
|
4165
4166
|
// slow, this copies everything,
|
|
4166
|
-
this.find([...includeMainFile.getStatements()], includeMainFile, false);
|
|
4167
|
+
this.find([...includeMainFile.getStatements()], includeMainFile, false, includePath);
|
|
4168
|
+
includePath.delete(includeMainFile.getFilename());
|
|
4167
4169
|
}
|
|
4168
4170
|
}
|
|
4169
4171
|
}
|
|
@@ -14418,11 +14420,11 @@ class Convert {
|
|
|
14418
14420
|
const dat = (0, combi_1.seq)("DATE", expressions_1.Source);
|
|
14419
14421
|
const tim = (0, combi_1.seq)("TIME", expressions_1.Source);
|
|
14420
14422
|
const stamp = (0, combi_1.seq)("INTO TIME STAMP", expressions_1.Target);
|
|
14421
|
-
const intoutc = (0, combi_1.ver)(version_1.Release.v754, (0, combi_1.seq)("INTO UTCLONG", expressions_1.Target));
|
|
14423
|
+
const intoutc = (0, combi_1.ver)(version_1.Release.v754, (0, combi_1.seq)("INTO UTCLONG", expressions_1.Target), { also: combi_1.AlsoIn.OpenABAP });
|
|
14422
14424
|
const invert = (0, combi_1.seq)("INTO INVERTED-DATE", expressions_1.Target);
|
|
14423
14425
|
const date = (0, combi_1.seq)((0, combi_1.per)(dat, tim), (0, combi_1.per)(daylightSource, stamp, zone, invert, intoutc));
|
|
14424
14426
|
const inv = (0, combi_1.seq)("INVERTED-DATE", expressions_1.Source, "INTO DATE", expressions_1.Target);
|
|
14425
|
-
const utclong = (0, combi_1.ver)(version_1.Release.v754, (0, combi_1.seq)("UTCLONG", expressions_1.Source, (0, combi_1.per)(zone, into,
|
|
14427
|
+
const utclong = (0, combi_1.ver)(version_1.Release.v754, (0, combi_1.seq)("UTCLONG", expressions_1.Source, (0, combi_1.per)(zone, into, daylightTarget)), { also: combi_1.AlsoIn.OpenABAP });
|
|
14426
14428
|
return (0, combi_1.seq)("CONVERT", (0, combi_1.alt)(time, date, inv, utclong));
|
|
14427
14429
|
}
|
|
14428
14430
|
}
|
|
@@ -26338,28 +26340,28 @@ BuiltIn.methods = {
|
|
|
26338
26340
|
"ABS": {
|
|
26339
26341
|
counter: BuiltIn.counter++,
|
|
26340
26342
|
mandatory: {
|
|
26341
|
-
"val": new basic_1.
|
|
26343
|
+
"val": new basic_1.NumericGenericType(),
|
|
26342
26344
|
},
|
|
26343
26345
|
return: basic_1.IntegerType.get(),
|
|
26344
26346
|
},
|
|
26345
26347
|
"ACOS": {
|
|
26346
26348
|
counter: BuiltIn.counter++,
|
|
26347
26349
|
mandatory: {
|
|
26348
|
-
"val": new basic_1.
|
|
26350
|
+
"val": new basic_1.NumericGenericType(),
|
|
26349
26351
|
},
|
|
26350
26352
|
return: new basic_1.FloatType(),
|
|
26351
26353
|
},
|
|
26352
26354
|
"ASIN": {
|
|
26353
26355
|
counter: BuiltIn.counter++,
|
|
26354
26356
|
mandatory: {
|
|
26355
|
-
"val": new basic_1.
|
|
26357
|
+
"val": new basic_1.NumericGenericType(),
|
|
26356
26358
|
},
|
|
26357
26359
|
return: new basic_1.FloatType(),
|
|
26358
26360
|
},
|
|
26359
26361
|
"ATAN": {
|
|
26360
26362
|
counter: BuiltIn.counter++,
|
|
26361
26363
|
mandatory: {
|
|
26362
|
-
"val": new basic_1.
|
|
26364
|
+
"val": new basic_1.NumericGenericType(),
|
|
26363
26365
|
},
|
|
26364
26366
|
return: new basic_1.FloatType(),
|
|
26365
26367
|
},
|
|
@@ -26393,7 +26395,7 @@ BuiltIn.methods = {
|
|
|
26393
26395
|
"CEIL": {
|
|
26394
26396
|
counter: BuiltIn.counter++,
|
|
26395
26397
|
mandatory: {
|
|
26396
|
-
"val": new basic_1.
|
|
26398
|
+
"val": new basic_1.NumericGenericType(),
|
|
26397
26399
|
},
|
|
26398
26400
|
return: basic_1.IntegerType.get(),
|
|
26399
26401
|
},
|
|
@@ -26530,14 +26532,14 @@ BuiltIn.methods = {
|
|
|
26530
26532
|
"COS": {
|
|
26531
26533
|
counter: BuiltIn.counter++,
|
|
26532
26534
|
mandatory: {
|
|
26533
|
-
"val": new basic_1.
|
|
26535
|
+
"val": new basic_1.NumericGenericType(),
|
|
26534
26536
|
},
|
|
26535
26537
|
return: new basic_1.FloatType(),
|
|
26536
26538
|
},
|
|
26537
26539
|
"COSH": {
|
|
26538
26540
|
counter: BuiltIn.counter++,
|
|
26539
26541
|
mandatory: {
|
|
26540
|
-
"val": new basic_1.
|
|
26542
|
+
"val": new basic_1.NumericGenericType(),
|
|
26541
26543
|
},
|
|
26542
26544
|
return: new basic_1.FloatType(),
|
|
26543
26545
|
},
|
|
@@ -26617,7 +26619,7 @@ BuiltIn.methods = {
|
|
|
26617
26619
|
"EXP": {
|
|
26618
26620
|
counter: BuiltIn.counter++,
|
|
26619
26621
|
mandatory: {
|
|
26620
|
-
"val": new basic_1.
|
|
26622
|
+
"val": new basic_1.NumericGenericType(),
|
|
26621
26623
|
},
|
|
26622
26624
|
return: new basic_1.FloatType(),
|
|
26623
26625
|
},
|
|
@@ -26686,14 +26688,14 @@ BuiltIn.methods = {
|
|
|
26686
26688
|
"FLOOR": {
|
|
26687
26689
|
counter: BuiltIn.counter++,
|
|
26688
26690
|
mandatory: {
|
|
26689
|
-
"val": new basic_1.
|
|
26691
|
+
"val": new basic_1.NumericGenericType(),
|
|
26690
26692
|
},
|
|
26691
26693
|
return: basic_1.IntegerType.get(),
|
|
26692
26694
|
},
|
|
26693
26695
|
"FRAC": {
|
|
26694
26696
|
counter: BuiltIn.counter++,
|
|
26695
26697
|
mandatory: {
|
|
26696
|
-
"val": new basic_1.
|
|
26698
|
+
"val": new basic_1.NumericGenericType(),
|
|
26697
26699
|
},
|
|
26698
26700
|
return: basic_1.IntegerType.get(),
|
|
26699
26701
|
},
|
|
@@ -26725,8 +26727,8 @@ BuiltIn.methods = {
|
|
|
26725
26727
|
"IPOW": {
|
|
26726
26728
|
counter: BuiltIn.counter++,
|
|
26727
26729
|
mandatory: {
|
|
26728
|
-
"base": new basic_1.
|
|
26729
|
-
"exp": new basic_1.
|
|
26730
|
+
"base": new basic_1.NumericGenericType(),
|
|
26731
|
+
"exp": new basic_1.NumericGenericType(),
|
|
26730
26732
|
},
|
|
26731
26733
|
return: basic_1.IntegerType.get(),
|
|
26732
26734
|
release: version_1.Release.v740sp02,
|
|
@@ -26758,14 +26760,14 @@ BuiltIn.methods = {
|
|
|
26758
26760
|
"LOG": {
|
|
26759
26761
|
counter: BuiltIn.counter++,
|
|
26760
26762
|
mandatory: {
|
|
26761
|
-
"val": new basic_1.
|
|
26763
|
+
"val": new basic_1.NumericGenericType(),
|
|
26762
26764
|
},
|
|
26763
26765
|
return: new basic_1.FloatType(),
|
|
26764
26766
|
},
|
|
26765
26767
|
"LOG10": {
|
|
26766
26768
|
counter: BuiltIn.counter++,
|
|
26767
26769
|
mandatory: {
|
|
26768
|
-
"val": new basic_1.
|
|
26770
|
+
"val": new basic_1.NumericGenericType(),
|
|
26769
26771
|
},
|
|
26770
26772
|
return: new basic_1.FloatType(),
|
|
26771
26773
|
},
|
|
@@ -26871,7 +26873,7 @@ BuiltIn.methods = {
|
|
|
26871
26873
|
"RESCALE": {
|
|
26872
26874
|
counter: BuiltIn.counter++,
|
|
26873
26875
|
mandatory: {
|
|
26874
|
-
"val": new basic_1.
|
|
26876
|
+
"val": new basic_1.NumericGenericType(),
|
|
26875
26877
|
},
|
|
26876
26878
|
optional: {
|
|
26877
26879
|
"dec": basic_1.IntegerType.get(),
|
|
@@ -26892,7 +26894,7 @@ BuiltIn.methods = {
|
|
|
26892
26894
|
"ROUND": {
|
|
26893
26895
|
counter: BuiltIn.counter++,
|
|
26894
26896
|
mandatory: {
|
|
26895
|
-
"val": new basic_1.
|
|
26897
|
+
"val": new basic_1.NumericGenericType(),
|
|
26896
26898
|
},
|
|
26897
26899
|
optional: {
|
|
26898
26900
|
"dec": basic_1.IntegerType.get(),
|
|
@@ -26944,28 +26946,28 @@ BuiltIn.methods = {
|
|
|
26944
26946
|
"SIGN": {
|
|
26945
26947
|
counter: BuiltIn.counter++,
|
|
26946
26948
|
mandatory: {
|
|
26947
|
-
"val": new basic_1.
|
|
26949
|
+
"val": new basic_1.NumericGenericType(),
|
|
26948
26950
|
},
|
|
26949
26951
|
return: basic_1.IntegerType.get(),
|
|
26950
26952
|
},
|
|
26951
26953
|
"SIN": {
|
|
26952
26954
|
counter: BuiltIn.counter++,
|
|
26953
26955
|
mandatory: {
|
|
26954
|
-
"val": new basic_1.
|
|
26956
|
+
"val": new basic_1.NumericGenericType(),
|
|
26955
26957
|
},
|
|
26956
26958
|
return: new basic_1.FloatType(),
|
|
26957
26959
|
},
|
|
26958
26960
|
"SINH": {
|
|
26959
26961
|
counter: BuiltIn.counter++,
|
|
26960
26962
|
mandatory: {
|
|
26961
|
-
"val": new basic_1.
|
|
26963
|
+
"val": new basic_1.NumericGenericType(),
|
|
26962
26964
|
},
|
|
26963
26965
|
return: new basic_1.FloatType(),
|
|
26964
26966
|
},
|
|
26965
26967
|
"SQRT": {
|
|
26966
26968
|
counter: BuiltIn.counter++,
|
|
26967
26969
|
mandatory: {
|
|
26968
|
-
"val": new basic_1.
|
|
26970
|
+
"val": new basic_1.NumericGenericType(),
|
|
26969
26971
|
},
|
|
26970
26972
|
return: new basic_1.FloatType(),
|
|
26971
26973
|
},
|
|
@@ -27055,14 +27057,14 @@ BuiltIn.methods = {
|
|
|
27055
27057
|
"TAN": {
|
|
27056
27058
|
counter: BuiltIn.counter++,
|
|
27057
27059
|
mandatory: {
|
|
27058
|
-
"val": new basic_1.
|
|
27060
|
+
"val": new basic_1.NumericGenericType(),
|
|
27059
27061
|
},
|
|
27060
27062
|
return: new basic_1.FloatType(),
|
|
27061
27063
|
},
|
|
27062
27064
|
"TANH": {
|
|
27063
27065
|
counter: BuiltIn.counter++,
|
|
27064
27066
|
mandatory: {
|
|
27065
|
-
"val": new basic_1.
|
|
27067
|
+
"val": new basic_1.NumericGenericType(),
|
|
27066
27068
|
},
|
|
27067
27069
|
return: new basic_1.FloatType(),
|
|
27068
27070
|
},
|
|
@@ -27106,7 +27108,7 @@ BuiltIn.methods = {
|
|
|
27106
27108
|
"TRUNC": {
|
|
27107
27109
|
counter: BuiltIn.counter++,
|
|
27108
27110
|
mandatory: {
|
|
27109
|
-
"val": new basic_1.
|
|
27111
|
+
"val": new basic_1.NumericGenericType(),
|
|
27110
27112
|
},
|
|
27111
27113
|
return: basic_1.IntegerType.get(),
|
|
27112
27114
|
},
|
|
@@ -27117,9 +27119,9 @@ BuiltIn.methods = {
|
|
|
27117
27119
|
},
|
|
27118
27120
|
optional: {
|
|
27119
27121
|
"days": basic_1.IntegerType.get(),
|
|
27120
|
-
"
|
|
27121
|
-
"minutes": basic_1.
|
|
27122
|
-
"seconds": new basic_1.
|
|
27122
|
+
"hours": basic_1.IntegerType.get(),
|
|
27123
|
+
"minutes": new basic_1.Integer8Type(),
|
|
27124
|
+
"seconds": new basic_1.DecFloat34Type(),
|
|
27123
27125
|
},
|
|
27124
27126
|
return: new basic_1.UTCLongType(),
|
|
27125
27127
|
release: version_1.Release.v754,
|
|
@@ -27135,7 +27137,7 @@ BuiltIn.methods = {
|
|
|
27135
27137
|
"high": new basic_1.UTCLongType(),
|
|
27136
27138
|
"low": new basic_1.UTCLongType(),
|
|
27137
27139
|
},
|
|
27138
|
-
return: new basic_1.
|
|
27140
|
+
return: new basic_1.DecFloat34Type(),
|
|
27139
27141
|
release: version_1.Release.v754,
|
|
27140
27142
|
},
|
|
27141
27143
|
"XSDBOOL": {
|
|
@@ -28487,7 +28489,12 @@ class Procedural {
|
|
|
28487
28489
|
this.scope = scope;
|
|
28488
28490
|
this.reg = reg;
|
|
28489
28491
|
}
|
|
28490
|
-
addAllFormDefinitions(file, obj) {
|
|
28492
|
+
addAllFormDefinitions(file, obj, visited = new Set()) {
|
|
28493
|
+
// an include reached again through a cycle of INCLUDEs is not walked twice
|
|
28494
|
+
if (visited.has(file.getFilename())) {
|
|
28495
|
+
return;
|
|
28496
|
+
}
|
|
28497
|
+
visited.add(file.getFilename());
|
|
28491
28498
|
const structure = file.getStructure();
|
|
28492
28499
|
if (structure) {
|
|
28493
28500
|
const input = {
|
|
@@ -28508,12 +28515,12 @@ class Procedural {
|
|
|
28508
28515
|
for (const node of includes) {
|
|
28509
28516
|
const found = this.findInclude(node, obj);
|
|
28510
28517
|
if (found) {
|
|
28511
|
-
this.addAllFormDefinitions(found, obj);
|
|
28518
|
+
this.addAllFormDefinitions(found, obj, visited);
|
|
28512
28519
|
}
|
|
28513
28520
|
}
|
|
28514
28521
|
}
|
|
28515
28522
|
findInclude(node, obj) {
|
|
28516
|
-
//
|
|
28523
|
+
// cyclic includes are cut by the callers, includes not found are reported by rule "check_include"
|
|
28517
28524
|
// todo: how to make sure code is not duplicated here and in rule "check_include" / include graph?
|
|
28518
28525
|
const expr = node.findFirstExpression(Expressions.IncludeName);
|
|
28519
28526
|
if (expr === undefined) {
|
|
@@ -29315,7 +29322,9 @@ class TypeUtils {
|
|
|
29315
29322
|
return false;
|
|
29316
29323
|
}
|
|
29317
29324
|
else if (source instanceof basic_1.Integer8Type) {
|
|
29318
|
-
if (target instanceof basic_1.IntegerType
|
|
29325
|
+
if (target instanceof basic_1.IntegerType
|
|
29326
|
+
|| target instanceof basic_1.StringType
|
|
29327
|
+
|| target instanceof basic_1.FloatType) {
|
|
29319
29328
|
return false;
|
|
29320
29329
|
}
|
|
29321
29330
|
}
|
|
@@ -31183,7 +31192,11 @@ const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modu
|
|
|
31183
31192
|
// On a character or byte field of fixed length the substring must lie inside the field, else it is
|
|
31184
31193
|
// a syntax error. Other types, a dynamic offset or length and "*" (undefined) are left alone, as is
|
|
31185
31194
|
// length 0. The offset is applied first, so the length is compared to what remains after the offset.
|
|
31195
|
+
// A substring of a date, time or numeric text field has type n; its bounds are not checked.
|
|
31186
31196
|
function substringType(context, offset, length, node, input) {
|
|
31197
|
+
if (context instanceof basic_1.DateType || context instanceof basic_1.TimeType || context instanceof basic_1.NumericType) {
|
|
31198
|
+
return numericSubstringType(context, offset, length);
|
|
31199
|
+
}
|
|
31187
31200
|
if (!(context instanceof basic_1.CharacterType) && !(context instanceof basic_1.HexType)) {
|
|
31188
31201
|
return context;
|
|
31189
31202
|
}
|
|
@@ -31206,6 +31219,24 @@ function substringType(context, offset, length, node, input) {
|
|
|
31206
31219
|
}
|
|
31207
31220
|
return context;
|
|
31208
31221
|
}
|
|
31222
|
+
function numericSubstringType(context, offset, length) {
|
|
31223
|
+
const hasOffset = offset !== undefined && offset > 0;
|
|
31224
|
+
const hasLength = length !== undefined && length > 0;
|
|
31225
|
+
if (hasOffset === false && hasLength === false) {
|
|
31226
|
+
return context;
|
|
31227
|
+
}
|
|
31228
|
+
let remaining = context instanceof basic_1.DateType ? 8 : context instanceof basic_1.TimeType ? 6 : context.getLength();
|
|
31229
|
+
if (hasOffset) {
|
|
31230
|
+
remaining = remaining - offset;
|
|
31231
|
+
}
|
|
31232
|
+
if (hasLength) {
|
|
31233
|
+
remaining = Math.min(remaining, length);
|
|
31234
|
+
}
|
|
31235
|
+
if (remaining <= 0) {
|
|
31236
|
+
return context;
|
|
31237
|
+
}
|
|
31238
|
+
return new basic_1.NumericType(remaining);
|
|
31239
|
+
}
|
|
31209
31240
|
// A field symbol typed "c" or "x" is generic, but its type is represented with length 1, so the
|
|
31210
31241
|
// offset or length at "index" is not checked when it directly follows the field symbol
|
|
31211
31242
|
function isFieldSymbolItself(children, index) {
|
|
@@ -41338,6 +41369,16 @@ class Convert {
|
|
|
41338
41369
|
target_1.Target.runSyntax(stampTarget, input);
|
|
41339
41370
|
}
|
|
41340
41371
|
}
|
|
41372
|
+
const utclongTarget = node.findExpressionAfterToken("UTCLONG");
|
|
41373
|
+
if ((utclongTarget === null || utclongTarget === void 0 ? void 0 : utclongTarget.get()) instanceof Expressions.Target) {
|
|
41374
|
+
const inline = utclongTarget === null || utclongTarget === void 0 ? void 0 : utclongTarget.findDirectExpression(Expressions.InlineData);
|
|
41375
|
+
if (inline) {
|
|
41376
|
+
inline_data_1.InlineData.runSyntax(inline, input, new basic_1.UTCLongType());
|
|
41377
|
+
}
|
|
41378
|
+
else {
|
|
41379
|
+
target_1.Target.runSyntax(utclongTarget, input);
|
|
41380
|
+
}
|
|
41381
|
+
}
|
|
41341
41382
|
}
|
|
41342
41383
|
}
|
|
41343
41384
|
exports.Convert = Convert;
|
|
@@ -50858,6 +50899,8 @@ if (Object.keys(map).length === 0) {
|
|
|
50858
50899
|
// -----------------------------------
|
|
50859
50900
|
class SyntaxLogic {
|
|
50860
50901
|
constructor(reg, object) {
|
|
50902
|
+
// files the traversal walked into through INCLUDEs, outermost first
|
|
50903
|
+
this.includeStack = [];
|
|
50861
50904
|
this.reg = reg;
|
|
50862
50905
|
this.issues = [];
|
|
50863
50906
|
this.deferred = [];
|
|
@@ -50965,11 +51008,20 @@ class SyntaxLogic {
|
|
|
50965
51008
|
// walk into INCLUDEs
|
|
50966
51009
|
if (isStatement && child.get() instanceof Statements.Include) {
|
|
50967
51010
|
const file = this.helpers.proc.findInclude(child, this.object);
|
|
50968
|
-
|
|
51011
|
+
// an INCLUDE that leads back to a file already being walked is not followed again
|
|
51012
|
+
const cyclic = file !== undefined && (file.getFilename() === this.currentFile.getFilename()
|
|
51013
|
+
|| this.includeStack.includes(file.getFilename()));
|
|
51014
|
+
if (file !== undefined && file.getStructure() !== undefined && cyclic === false) {
|
|
50969
51015
|
const old = this.currentFile;
|
|
51016
|
+
this.includeStack.push(old.getFilename());
|
|
50970
51017
|
this.currentFile = file;
|
|
50971
|
-
|
|
50972
|
-
|
|
51018
|
+
try {
|
|
51019
|
+
this.traverse(file.getStructure());
|
|
51020
|
+
}
|
|
51021
|
+
finally {
|
|
51022
|
+
this.currentFile = old;
|
|
51023
|
+
this.includeStack.pop();
|
|
51024
|
+
}
|
|
50973
51025
|
}
|
|
50974
51026
|
}
|
|
50975
51027
|
if (isStructure || isStatement) {
|
|
@@ -51379,11 +51431,46 @@ exports.ArtifactsABAP = ArtifactsABAP;
|
|
|
51379
51431
|
|
|
51380
51432
|
"use strict";
|
|
51381
51433
|
|
|
51434
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
51435
|
+
if (k2 === undefined) k2 = k;
|
|
51436
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
51437
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
51438
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
51439
|
+
}
|
|
51440
|
+
Object.defineProperty(o, k2, desc);
|
|
51441
|
+
}) : (function(o, m, k, k2) {
|
|
51442
|
+
if (k2 === undefined) k2 = k;
|
|
51443
|
+
o[k2] = m[k];
|
|
51444
|
+
}));
|
|
51445
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
51446
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
51447
|
+
}) : function(o, v) {
|
|
51448
|
+
o["default"] = v;
|
|
51449
|
+
});
|
|
51450
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
51451
|
+
var ownKeys = function(o) {
|
|
51452
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
51453
|
+
var ar = [];
|
|
51454
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
51455
|
+
return ar;
|
|
51456
|
+
};
|
|
51457
|
+
return ownKeys(o);
|
|
51458
|
+
};
|
|
51459
|
+
return function (mod) {
|
|
51460
|
+
if (mod && mod.__esModule) return mod;
|
|
51461
|
+
var result = {};
|
|
51462
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
51463
|
+
__setModuleDefault(result, mod);
|
|
51464
|
+
return result;
|
|
51465
|
+
};
|
|
51466
|
+
})();
|
|
51382
51467
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
51383
51468
|
exports.CrossIncludeMacros = void 0;
|
|
51384
51469
|
const _abap_object_1 = __webpack_require__(/*! ../objects/_abap_object */ "./node_modules/@abaplint/core/build/src/objects/_abap_object.js");
|
|
51385
51470
|
const program_1 = __webpack_require__(/*! ../objects/program */ "./node_modules/@abaplint/core/build/src/objects/program.js");
|
|
51386
51471
|
const _statement_1 = __webpack_require__(/*! ./2_statements/statements/_statement */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/_statement.js");
|
|
51472
|
+
const statements_1 = __webpack_require__(/*! ./2_statements/statements */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/index.js");
|
|
51473
|
+
const Expressions = __importStar(__webpack_require__(/*! ./2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js"));
|
|
51387
51474
|
const expand_macros_1 = __webpack_require__(/*! ./2_statements/expand_macros */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expand_macros.js");
|
|
51388
51475
|
const include_graph_1 = __webpack_require__(/*! ../utils/include_graph */ "./node_modules/@abaplint/core/build/src/utils/include_graph.js");
|
|
51389
51476
|
// Macros can be defined in one include and used in a sibling include, connected
|
|
@@ -51396,6 +51483,7 @@ class CrossIncludeMacros {
|
|
|
51396
51483
|
this.reg = reg;
|
|
51397
51484
|
}
|
|
51398
51485
|
run() {
|
|
51486
|
+
this.reparseCyclicPrograms();
|
|
51399
51487
|
const candidates = this.findCandidates();
|
|
51400
51488
|
if (candidates.length === 0) {
|
|
51401
51489
|
return;
|
|
@@ -51423,6 +51511,45 @@ class CrossIncludeMacros {
|
|
|
51423
51511
|
}
|
|
51424
51512
|
}
|
|
51425
51513
|
//////////////////////////////
|
|
51514
|
+
// A program or include in an INCLUDE cycle can be parsed while the include defining its macros is still
|
|
51515
|
+
// being parsed, depending on the order the files were added. Everything is parsed now, so parse it again.
|
|
51516
|
+
reparseCyclicPrograms() {
|
|
51517
|
+
const config = this.reg.getConfig();
|
|
51518
|
+
for (const obj of this.reg.getObjects()) {
|
|
51519
|
+
if (obj instanceof program_1.Program && this.hasUnknown(obj) && this.isInIncludeCycle(obj)) {
|
|
51520
|
+
obj.setDirty();
|
|
51521
|
+
obj.parse(config.getRelease(), config.getSyntaxSetttings().globalMacros, this.reg, config.getLanguageVersion());
|
|
51522
|
+
}
|
|
51523
|
+
}
|
|
51524
|
+
}
|
|
51525
|
+
hasUnknown(prog) {
|
|
51526
|
+
return prog.getABAPFiles().some(f => f.getStatements().some(s => s.get() instanceof _statement_1.Unknown));
|
|
51527
|
+
}
|
|
51528
|
+
// the include graph does not link INCLUDEs of main programs, so follow the INCLUDEs from the program
|
|
51529
|
+
isInIncludeCycle(prog) {
|
|
51530
|
+
var _a;
|
|
51531
|
+
const seen = new Set();
|
|
51532
|
+
const stack = [prog];
|
|
51533
|
+
while (stack.length > 0) {
|
|
51534
|
+
for (const file of stack.pop().getABAPFiles()) {
|
|
51535
|
+
for (const statement of file.getStatements()) {
|
|
51536
|
+
if (!(statement.get() instanceof statements_1.Include)) {
|
|
51537
|
+
continue;
|
|
51538
|
+
}
|
|
51539
|
+
const name = (_a = statement.findDirectExpression(Expressions.IncludeName)) === null || _a === void 0 ? void 0 : _a.concatTokens();
|
|
51540
|
+
const included = this.reg.getObject("PROG", name);
|
|
51541
|
+
if (included === prog) {
|
|
51542
|
+
return true;
|
|
51543
|
+
}
|
|
51544
|
+
else if (included instanceof program_1.Program && seen.has(included) === false) {
|
|
51545
|
+
seen.add(included);
|
|
51546
|
+
stack.push(included);
|
|
51547
|
+
}
|
|
51548
|
+
}
|
|
51549
|
+
}
|
|
51550
|
+
}
|
|
51551
|
+
return false;
|
|
51552
|
+
}
|
|
51426
51553
|
findCandidates() {
|
|
51427
51554
|
const ret = [];
|
|
51428
51555
|
for (const obj of this.reg.getObjects()) {
|
|
@@ -63196,6 +63323,7 @@ class ABAPObject extends _abstract_object_1.AbstractObject {
|
|
|
63196
63323
|
}
|
|
63197
63324
|
constructor(name) {
|
|
63198
63325
|
super(name);
|
|
63326
|
+
this.parsing = false;
|
|
63199
63327
|
this.parsed = [];
|
|
63200
63328
|
this.texts = undefined;
|
|
63201
63329
|
this.rawXMLCache = undefined;
|
|
@@ -63204,11 +63332,19 @@ class ABAPObject extends _abstract_object_1.AbstractObject {
|
|
|
63204
63332
|
return !!x && x instanceof ABAPObject;
|
|
63205
63333
|
}
|
|
63206
63334
|
parse(release, globalMacros, reg, languageVersion = version_1.LanguageVersion.Normal) {
|
|
63207
|
-
|
|
63335
|
+
// an INCLUDE that leads back to this object while it is being parsed is not followed again
|
|
63336
|
+
if (this.isDirty() === false || this.parsing === true) {
|
|
63208
63337
|
return { updated: false, runtime: 0 };
|
|
63209
63338
|
}
|
|
63210
63339
|
const abapFiles = this.getFiles().filter(f => f.getFilename().endsWith(".abap"));
|
|
63211
|
-
|
|
63340
|
+
let result;
|
|
63341
|
+
this.parsing = true;
|
|
63342
|
+
try {
|
|
63343
|
+
result = new abap_parser_1.ABAPParser({ release, globalMacros, reg, languageVersion }).parse(abapFiles);
|
|
63344
|
+
}
|
|
63345
|
+
finally {
|
|
63346
|
+
this.parsing = false;
|
|
63347
|
+
}
|
|
63212
63348
|
this.parsed = result.output;
|
|
63213
63349
|
this.old = result.issues;
|
|
63214
63350
|
this.dirty = false;
|
|
@@ -72425,7 +72561,7 @@ class Registry {
|
|
|
72425
72561
|
}
|
|
72426
72562
|
static abaplintVersion() {
|
|
72427
72563
|
// magic, see build script "version.js"
|
|
72428
|
-
return "2.120.
|
|
72564
|
+
return "2.120.80";
|
|
72429
72565
|
}
|
|
72430
72566
|
getDDICReferences() {
|
|
72431
72567
|
return this.ddicReferences;
|
|
@@ -88174,6 +88310,7 @@ __exportStar(__webpack_require__(/*! ./inline_data_old_versions */ "./node_modul
|
|
|
88174
88310
|
__exportStar(__webpack_require__(/*! ./inline_packed_computation */ "./node_modules/@abaplint/core/build/src/rules/inline_packed_computation.js"), exports);
|
|
88175
88311
|
__exportStar(__webpack_require__(/*! ./intf_referencing_clas */ "./node_modules/@abaplint/core/build/src/rules/intf_referencing_clas.js"), exports);
|
|
88176
88312
|
__exportStar(__webpack_require__(/*! ./invalid_table_index */ "./node_modules/@abaplint/core/build/src/rules/invalid_table_index.js"), exports);
|
|
88313
|
+
__exportStar(__webpack_require__(/*! ./is_assigned_in_loop */ "./node_modules/@abaplint/core/build/src/rules/is_assigned_in_loop.js"), exports);
|
|
88177
88314
|
__exportStar(__webpack_require__(/*! ./keep_single_parameter_on_one_line */ "./node_modules/@abaplint/core/build/src/rules/keep_single_parameter_on_one_line.js"), exports);
|
|
88178
88315
|
__exportStar(__webpack_require__(/*! ./keyword_case */ "./node_modules/@abaplint/core/build/src/rules/keyword_case.js"), exports);
|
|
88179
88316
|
__exportStar(__webpack_require__(/*! ./line_break_multiple_parameters */ "./node_modules/@abaplint/core/build/src/rules/line_break_multiple_parameters.js"), exports);
|
|
@@ -88239,6 +88376,7 @@ __exportStar(__webpack_require__(/*! ./prefix_is_current_class */ "./node_module
|
|
|
88239
88376
|
__exportStar(__webpack_require__(/*! ./range_row_values */ "./node_modules/@abaplint/core/build/src/rules/range_row_values.js"), exports);
|
|
88240
88377
|
__exportStar(__webpack_require__(/*! ./reduce_procedural_code */ "./node_modules/@abaplint/core/build/src/rules/reduce_procedural_code.js"), exports);
|
|
88241
88378
|
__exportStar(__webpack_require__(/*! ./reduce_string_templates */ "./node_modules/@abaplint/core/build/src/rules/reduce_string_templates.js"), exports);
|
|
88379
|
+
__exportStar(__webpack_require__(/*! ./redundant_cast */ "./node_modules/@abaplint/core/build/src/rules/redundant_cast.js"), exports);
|
|
88242
88380
|
__exportStar(__webpack_require__(/*! ./redundant_conversion */ "./node_modules/@abaplint/core/build/src/rules/redundant_conversion.js"), exports);
|
|
88243
88381
|
__exportStar(__webpack_require__(/*! ./release_idoc */ "./node_modules/@abaplint/core/build/src/rules/release_idoc.js"), exports);
|
|
88244
88382
|
__exportStar(__webpack_require__(/*! ./remove_descriptions */ "./node_modules/@abaplint/core/build/src/rules/remove_descriptions.js"), exports);
|
|
@@ -88923,6 +89061,258 @@ exports.InvalidTableIndex = InvalidTableIndex;
|
|
|
88923
89061
|
|
|
88924
89062
|
/***/ },
|
|
88925
89063
|
|
|
89064
|
+
/***/ "./node_modules/@abaplint/core/build/src/rules/is_assigned_in_loop.js"
|
|
89065
|
+
/*!****************************************************************************!*\
|
|
89066
|
+
!*** ./node_modules/@abaplint/core/build/src/rules/is_assigned_in_loop.js ***!
|
|
89067
|
+
\****************************************************************************/
|
|
89068
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
89069
|
+
|
|
89070
|
+
"use strict";
|
|
89071
|
+
|
|
89072
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
89073
|
+
if (k2 === undefined) k2 = k;
|
|
89074
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
89075
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
89076
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
89077
|
+
}
|
|
89078
|
+
Object.defineProperty(o, k2, desc);
|
|
89079
|
+
}) : (function(o, m, k, k2) {
|
|
89080
|
+
if (k2 === undefined) k2 = k;
|
|
89081
|
+
o[k2] = m[k];
|
|
89082
|
+
}));
|
|
89083
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
89084
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
89085
|
+
}) : function(o, v) {
|
|
89086
|
+
o["default"] = v;
|
|
89087
|
+
});
|
|
89088
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
89089
|
+
var ownKeys = function(o) {
|
|
89090
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
89091
|
+
var ar = [];
|
|
89092
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
89093
|
+
return ar;
|
|
89094
|
+
};
|
|
89095
|
+
return ownKeys(o);
|
|
89096
|
+
};
|
|
89097
|
+
return function (mod) {
|
|
89098
|
+
if (mod && mod.__esModule) return mod;
|
|
89099
|
+
var result = {};
|
|
89100
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
89101
|
+
__setModuleDefault(result, mod);
|
|
89102
|
+
return result;
|
|
89103
|
+
};
|
|
89104
|
+
})();
|
|
89105
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
89106
|
+
exports.IsAssignedInLoop = exports.IsAssignedInLoopConf = void 0;
|
|
89107
|
+
const Statements = __importStar(__webpack_require__(/*! ../abap/2_statements/statements */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/index.js"));
|
|
89108
|
+
const Expressions = __importStar(__webpack_require__(/*! ../abap/2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js"));
|
|
89109
|
+
const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
|
|
89110
|
+
const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
|
|
89111
|
+
const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "./node_modules/@abaplint/core/build/src/rules/_abap_rule.js");
|
|
89112
|
+
const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
|
|
89113
|
+
const edit_helper_1 = __webpack_require__(/*! ../edit_helper */ "./node_modules/@abaplint/core/build/src/edit_helper.js");
|
|
89114
|
+
const severity_1 = __webpack_require__(/*! ../severity */ "./node_modules/@abaplint/core/build/src/severity.js");
|
|
89115
|
+
class IsAssignedInLoopConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
89116
|
+
constructor() {
|
|
89117
|
+
super(...arguments);
|
|
89118
|
+
this.severity = severity_1.Severity.Warning;
|
|
89119
|
+
}
|
|
89120
|
+
}
|
|
89121
|
+
exports.IsAssignedInLoopConf = IsAssignedInLoopConf;
|
|
89122
|
+
class IsAssignedInLoop extends _abap_rule_1.ABAPRule {
|
|
89123
|
+
constructor() {
|
|
89124
|
+
super(...arguments);
|
|
89125
|
+
this.conf = new IsAssignedInLoopConf();
|
|
89126
|
+
}
|
|
89127
|
+
getMetadata() {
|
|
89128
|
+
return {
|
|
89129
|
+
key: "is_assigned_in_loop",
|
|
89130
|
+
title: "IS ASSIGNED after READ TABLE or ASSIGN in a loop",
|
|
89131
|
+
shortDescription: `Reports IS [NOT] ASSIGNED after a READ TABLE ... ASSIGNING or ASSIGN inside a loop, without UNASSIGN before it`,
|
|
89132
|
+
extendedInformation: `A failed READ TABLE ... ASSIGNING or ASSIGN keeps the previous binding of the field symbol. Inside a
|
|
89133
|
+
loop, the field symbol still points to the row of an earlier iteration, so IS ASSIGNED is true
|
|
89134
|
+
although the statement failed, and the code goes on with the wrong row.
|
|
89135
|
+
|
|
89136
|
+
Add UNASSIGN <fs> before the statement, inside the loop, or check sy-subrc after a READ TABLE.
|
|
89137
|
+
The quick fix inserts the UNASSIGN; it is not offered for a field symbol declared inline in
|
|
89138
|
+
the statement, or for a chained statement.
|
|
89139
|
+
|
|
89140
|
+
Not reported: a check that also reads sy-subrc, an ASSIGN that cannot fail (a static source
|
|
89141
|
+
without dereference, table expression or dynamic part), and loops outside of the
|
|
89142
|
+
method, form or function module of the statement. See also subrc_after_assign.`,
|
|
89143
|
+
tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Quickfix],
|
|
89144
|
+
badExample: `LOOP AT lt_cells INTO ls_cell.
|
|
89145
|
+
READ TABLE lt_styles ASSIGNING <style> WITH KEY id = ls_cell-style.
|
|
89146
|
+
IF <style> IS ASSIGNED.
|
|
89147
|
+
ls_cell-format = <style>-format.
|
|
89148
|
+
ENDIF.
|
|
89149
|
+
ENDLOOP.`,
|
|
89150
|
+
goodExample: `LOOP AT lt_cells INTO ls_cell.
|
|
89151
|
+
UNASSIGN <style>.
|
|
89152
|
+
READ TABLE lt_styles ASSIGNING <style> WITH KEY id = ls_cell-style.
|
|
89153
|
+
IF <style> IS ASSIGNED.
|
|
89154
|
+
ls_cell-format = <style>-format.
|
|
89155
|
+
ENDIF.
|
|
89156
|
+
ENDLOOP.`,
|
|
89157
|
+
};
|
|
89158
|
+
}
|
|
89159
|
+
getConfig() {
|
|
89160
|
+
return this.conf;
|
|
89161
|
+
}
|
|
89162
|
+
setConfig(conf) {
|
|
89163
|
+
this.conf = conf;
|
|
89164
|
+
}
|
|
89165
|
+
runParsed(file) {
|
|
89166
|
+
const issues = [];
|
|
89167
|
+
const statements = file.getStatements();
|
|
89168
|
+
for (let i = 0; i < statements.length; i++) {
|
|
89169
|
+
const statement = statements[i];
|
|
89170
|
+
const name = this.boundByFailable(statement);
|
|
89171
|
+
if (name === undefined) {
|
|
89172
|
+
continue;
|
|
89173
|
+
}
|
|
89174
|
+
const fs = name.toUpperCase();
|
|
89175
|
+
const loop = this.innermostLoop(i, statements);
|
|
89176
|
+
if (loop === undefined || this.unassignedBefore(loop, i, statements, fs) === true) {
|
|
89177
|
+
continue;
|
|
89178
|
+
}
|
|
89179
|
+
const check = this.nextCheck(i, statements, fs);
|
|
89180
|
+
if (check === undefined) {
|
|
89181
|
+
continue;
|
|
89182
|
+
}
|
|
89183
|
+
const read = statement.get() instanceof Statements.ReadTable;
|
|
89184
|
+
const message = `${read ? "READ TABLE" : "ASSIGN"} in a loop keeps the previous binding of ${name} when it fails, `
|
|
89185
|
+
+ `UNASSIGN ${name} before it` + (read ? " or check sy-subrc" : "");
|
|
89186
|
+
const fix = this.buildFix(file, statement, name);
|
|
89187
|
+
issues.push(issue_1.Issue.atStatement(file, check, message, this.getMetadata().key, this.conf.severity, fix));
|
|
89188
|
+
}
|
|
89189
|
+
return issues;
|
|
89190
|
+
}
|
|
89191
|
+
////////////////
|
|
89192
|
+
/** the field symbol bound by a READ TABLE ... ASSIGNING or an ASSIGN that can fail */
|
|
89193
|
+
boundByFailable(statement) {
|
|
89194
|
+
var _a, _b, _c;
|
|
89195
|
+
const s = statement.get();
|
|
89196
|
+
if (s instanceof Statements.ReadTable) {
|
|
89197
|
+
const target = (_a = statement.findDirectExpression(Expressions.ReadTableTarget)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.FSTarget);
|
|
89198
|
+
return (_b = target === null || target === void 0 ? void 0 : target.findFirstExpression(Expressions.FieldSymbol)) === null || _b === void 0 ? void 0 : _b.concatTokens();
|
|
89199
|
+
}
|
|
89200
|
+
else if (s instanceof Statements.Assign) {
|
|
89201
|
+
const source = statement.findDirectExpression(Expressions.AssignSource);
|
|
89202
|
+
if (source === undefined) {
|
|
89203
|
+
return undefined;
|
|
89204
|
+
}
|
|
89205
|
+
const first = source.getFirstToken().getStr().toUpperCase();
|
|
89206
|
+
const failable = first === "COMPONENT"
|
|
89207
|
+
|| first === "TABLE"
|
|
89208
|
+
|| source.findFirstExpression(Expressions.Dynamic) !== undefined
|
|
89209
|
+
|| source.findFirstExpression(Expressions.Dereference) !== undefined
|
|
89210
|
+
|| source.findFirstExpression(Expressions.TableExpression) !== undefined
|
|
89211
|
+
|| statement.findDirectTokenByText("INCREMENT") !== undefined;
|
|
89212
|
+
if (failable === false) {
|
|
89213
|
+
return undefined;
|
|
89214
|
+
}
|
|
89215
|
+
const target = statement.findDirectExpression(Expressions.FSTarget);
|
|
89216
|
+
return (_c = target === null || target === void 0 ? void 0 : target.findFirstExpression(Expressions.FieldSymbol)) === null || _c === void 0 ? void 0 : _c.concatTokens();
|
|
89217
|
+
}
|
|
89218
|
+
return undefined;
|
|
89219
|
+
}
|
|
89220
|
+
/** index of the innermost LOOP, DO, WHILE or SELECT loop around the statement, in the same block */
|
|
89221
|
+
innermostLoop(index, statements) {
|
|
89222
|
+
let depth = 0;
|
|
89223
|
+
for (let i = index - 1; i >= 0 && this.startsBlock(statements[i]) === false; i--) {
|
|
89224
|
+
if (this.endsLoop(statements[i])) {
|
|
89225
|
+
depth++;
|
|
89226
|
+
}
|
|
89227
|
+
else if (this.startsLoop(statements[i])) {
|
|
89228
|
+
if (depth === 0) {
|
|
89229
|
+
return i;
|
|
89230
|
+
}
|
|
89231
|
+
depth--;
|
|
89232
|
+
}
|
|
89233
|
+
}
|
|
89234
|
+
return undefined;
|
|
89235
|
+
}
|
|
89236
|
+
unassignedBefore(loop, index, statements, fs) {
|
|
89237
|
+
for (let i = loop + 1; i < index; i++) {
|
|
89238
|
+
if (statements[i].get() instanceof Statements.Unassign && this.mentions(statements[i], fs)) {
|
|
89239
|
+
return true;
|
|
89240
|
+
}
|
|
89241
|
+
}
|
|
89242
|
+
return false;
|
|
89243
|
+
}
|
|
89244
|
+
/** the first IS [NOT] ASSIGNED of the field symbol after the statement, before the end of the loop
|
|
89245
|
+
* or another UNASSIGN or binding of it; a check that also reads sy-subrc is fine */
|
|
89246
|
+
nextCheck(index, statements, fs) {
|
|
89247
|
+
let depth = 0;
|
|
89248
|
+
for (let i = index + 1; i < statements.length && this.startsBlock(statements[i]) === false; i++) {
|
|
89249
|
+
const statement = statements[i];
|
|
89250
|
+
if (this.startsLoop(statement)) {
|
|
89251
|
+
depth++;
|
|
89252
|
+
}
|
|
89253
|
+
else if (this.endsLoop(statement)) {
|
|
89254
|
+
if (depth === 0) {
|
|
89255
|
+
return undefined;
|
|
89256
|
+
}
|
|
89257
|
+
depth--;
|
|
89258
|
+
}
|
|
89259
|
+
const concat = statement.concatTokens().toUpperCase();
|
|
89260
|
+
if (concat.includes(fs + " IS ASSIGNED") || concat.includes(fs + " IS NOT ASSIGNED")) {
|
|
89261
|
+
return concat.includes("SY-SUBRC") ? undefined : statement;
|
|
89262
|
+
}
|
|
89263
|
+
if ((statement.get() instanceof Statements.Unassign && this.mentions(statement, fs))
|
|
89264
|
+
|| this.binds(statement, fs)) {
|
|
89265
|
+
return undefined;
|
|
89266
|
+
}
|
|
89267
|
+
}
|
|
89268
|
+
return undefined;
|
|
89269
|
+
}
|
|
89270
|
+
mentions(statement, fs) {
|
|
89271
|
+
return statement.findAllExpressions(Expressions.FieldSymbol).some(e => e.concatTokens().toUpperCase() === fs);
|
|
89272
|
+
}
|
|
89273
|
+
binds(statement, fs) {
|
|
89274
|
+
return statement.findAllExpressions(Expressions.FSTarget)
|
|
89275
|
+
.some(t => { var _a; return ((_a = t.findFirstExpression(Expressions.FieldSymbol)) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase()) === fs; });
|
|
89276
|
+
}
|
|
89277
|
+
startsLoop(statement) {
|
|
89278
|
+
const s = statement.get();
|
|
89279
|
+
return s instanceof Statements.Loop
|
|
89280
|
+
|| s instanceof Statements.Do
|
|
89281
|
+
|| s instanceof Statements.While
|
|
89282
|
+
|| s instanceof Statements.SelectLoop;
|
|
89283
|
+
}
|
|
89284
|
+
endsLoop(statement) {
|
|
89285
|
+
const s = statement.get();
|
|
89286
|
+
return s instanceof Statements.EndLoop
|
|
89287
|
+
|| s instanceof Statements.EndDo
|
|
89288
|
+
|| s instanceof Statements.EndWhile
|
|
89289
|
+
|| s instanceof Statements.EndSelect;
|
|
89290
|
+
}
|
|
89291
|
+
startsBlock(statement) {
|
|
89292
|
+
const s = statement.get();
|
|
89293
|
+
return s instanceof Statements.MethodImplementation
|
|
89294
|
+
|| s instanceof Statements.Form
|
|
89295
|
+
|| s instanceof Statements.FunctionModule
|
|
89296
|
+
|| s instanceof Statements.Module
|
|
89297
|
+
|| s instanceof Statements.EndMethod
|
|
89298
|
+
|| s instanceof Statements.EndForm
|
|
89299
|
+
|| s instanceof Statements.EndFunction
|
|
89300
|
+
|| s instanceof Statements.EndModule;
|
|
89301
|
+
}
|
|
89302
|
+
/** UNASSIGN on a line of its own before the statement, with the same indentation */
|
|
89303
|
+
buildFix(file, statement, name) {
|
|
89304
|
+
if (statement.getColon() !== undefined || statement.findFirstExpression(Expressions.InlineFS) !== undefined) {
|
|
89305
|
+
return undefined;
|
|
89306
|
+
}
|
|
89307
|
+
const start = statement.getStart();
|
|
89308
|
+
return edit_helper_1.EditHelper.insertAt(file, start, `UNASSIGN ${name}.\n` + " ".repeat(start.getCol() - 1));
|
|
89309
|
+
}
|
|
89310
|
+
}
|
|
89311
|
+
exports.IsAssignedInLoop = IsAssignedInLoop;
|
|
89312
|
+
//# sourceMappingURL=is_assigned_in_loop.js.map
|
|
89313
|
+
|
|
89314
|
+
/***/ },
|
|
89315
|
+
|
|
88926
89316
|
/***/ "./node_modules/@abaplint/core/build/src/rules/keep_single_parameter_on_one_line.js"
|
|
88927
89317
|
/*!******************************************************************************************!*\
|
|
88928
89318
|
!*** ./node_modules/@abaplint/core/build/src/rules/keep_single_parameter_on_one_line.js ***!
|
|
@@ -90622,7 +91012,11 @@ ENDIF.
|
|
|
90622
91012
|
&& lastChildren[1].getChildren().length === 1
|
|
90623
91013
|
&& lastChildren[1].getFirstToken().getStr().startsWith("-") === false
|
|
90624
91014
|
&& lastChildren[2].getFirstToken().getStr() === ")") {
|
|
90625
|
-
const
|
|
91015
|
+
const fixText = lastChildren[1].concatTokens();
|
|
91016
|
+
const start = lastChildren[0].getFirstToken().getStart();
|
|
91017
|
+
const end = lastChildren[2].getLastToken().getEnd();
|
|
91018
|
+
const fix = edit_helper_1.EditHelper.replaceRange(file, start, end, fixText);
|
|
91019
|
+
const issue = issue_1.Issue.atToken(file, lastChildren[0].getFirstToken(), "Too many parentheses", this.getMetadata().key, this.conf.severity, fix);
|
|
90626
91020
|
issues.push(issue);
|
|
90627
91021
|
}
|
|
90628
91022
|
}
|
|
@@ -90751,6 +91145,7 @@ const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/co
|
|
|
90751
91145
|
const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "./node_modules/@abaplint/core/build/src/rules/_abap_rule.js");
|
|
90752
91146
|
const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
|
|
90753
91147
|
const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
|
|
91148
|
+
const edit_helper_1 = __webpack_require__(/*! ../edit_helper */ "./node_modules/@abaplint/core/build/src/edit_helper.js");
|
|
90754
91149
|
class MaxOneMethodParameterPerLineConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
90755
91150
|
}
|
|
90756
91151
|
exports.MaxOneMethodParameterPerLineConf = MaxOneMethodParameterPerLineConf;
|
|
@@ -90764,7 +91159,7 @@ class MaxOneMethodParameterPerLine extends _abap_rule_1.ABAPRule {
|
|
|
90764
91159
|
key: "max_one_method_parameter_per_line",
|
|
90765
91160
|
title: "Max one method parameter definition per line",
|
|
90766
91161
|
shortDescription: `Keep max one method parameter description per line`,
|
|
90767
|
-
tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Whitespace],
|
|
91162
|
+
tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Whitespace, _irule_1.RuleTag.Quickfix],
|
|
90768
91163
|
badExample: `
|
|
90769
91164
|
METHODS apps_scope_token
|
|
90770
91165
|
IMPORTING
|
|
@@ -90793,7 +91188,8 @@ METHODS apps_scope_token
|
|
|
90793
91188
|
continue;
|
|
90794
91189
|
}
|
|
90795
91190
|
if (prev.getFirstToken().getStart().getRow() === p.getFirstToken().getStart().getRow()) {
|
|
90796
|
-
const
|
|
91191
|
+
const fix = this.buildFix(file, statement, p);
|
|
91192
|
+
const issue = issue_1.Issue.atToken(file, prev.getFirstToken(), this.getMetadata().title, this.getMetadata().key, this.conf.severity, fix);
|
|
90797
91193
|
issues.push(issue);
|
|
90798
91194
|
}
|
|
90799
91195
|
prev = p;
|
|
@@ -90801,8 +91197,32 @@ METHODS apps_scope_token
|
|
|
90801
91197
|
}
|
|
90802
91198
|
return issues;
|
|
90803
91199
|
}
|
|
91200
|
+
/** moves the parameter, or its preceding section keyword, to a new line */
|
|
91201
|
+
buildFix(file, statement, param) {
|
|
91202
|
+
const tokens = statement.getTokens();
|
|
91203
|
+
const index = tokens.indexOf(param.getFirstToken());
|
|
91204
|
+
if (index < 1) {
|
|
91205
|
+
return undefined;
|
|
91206
|
+
}
|
|
91207
|
+
let target = tokens[index];
|
|
91208
|
+
let indent = statement.findFirstExpression(Expressions.MethodParam).getFirstToken().getStart().getCol();
|
|
91209
|
+
const before = tokens[index - 1];
|
|
91210
|
+
if (MaxOneMethodParameterPerLine.SECTIONS.includes(before.getStr().toUpperCase())) {
|
|
91211
|
+
if (index < 2) {
|
|
91212
|
+
return undefined;
|
|
91213
|
+
}
|
|
91214
|
+
target = before;
|
|
91215
|
+
indent = tokens.find(t => MaxOneMethodParameterPerLine.SECTIONS.includes(t.getStr().toUpperCase())).getStart().getCol();
|
|
91216
|
+
}
|
|
91217
|
+
const previous = tokens[tokens.indexOf(target) - 1];
|
|
91218
|
+
if (previous.getEnd().getRow() !== target.getStart().getRow()) {
|
|
91219
|
+
return undefined;
|
|
91220
|
+
}
|
|
91221
|
+
return edit_helper_1.EditHelper.replaceRange(file, previous.getEnd(), target.getStart(), "\n" + " ".repeat(indent - 1));
|
|
91222
|
+
}
|
|
90804
91223
|
}
|
|
90805
91224
|
exports.MaxOneMethodParameterPerLine = MaxOneMethodParameterPerLine;
|
|
91225
|
+
MaxOneMethodParameterPerLine.SECTIONS = ["IMPORTING", "EXPORTING", "CHANGING", "RETURNING"];
|
|
90806
91226
|
//# sourceMappingURL=max_one_method_parameter_per_line.js.map
|
|
90807
91227
|
|
|
90808
91228
|
/***/ },
|
|
@@ -92214,6 +92634,8 @@ const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "./node_modules/@ab
|
|
|
92214
92634
|
const sequential_blank_1 = __webpack_require__(/*! ./sequential_blank */ "./node_modules/@abaplint/core/build/src/rules/sequential_blank.js");
|
|
92215
92635
|
const Statements = __importStar(__webpack_require__(/*! ../abap/2_statements/statements */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/index.js"));
|
|
92216
92636
|
const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
|
|
92637
|
+
const edit_helper_1 = __webpack_require__(/*! ../edit_helper */ "./node_modules/@abaplint/core/build/src/edit_helper.js");
|
|
92638
|
+
const position_1 = __webpack_require__(/*! ../position */ "./node_modules/@abaplint/core/build/src/position.js");
|
|
92217
92639
|
var NewlineLogic;
|
|
92218
92640
|
(function (NewlineLogic) {
|
|
92219
92641
|
NewlineLogic["Exact"] = "exact";
|
|
@@ -92243,7 +92665,7 @@ class NewlineBetweenMethods extends _abap_rule_1.ABAPRule {
|
|
|
92243
92665
|
key: "newline_between_methods",
|
|
92244
92666
|
title: "New line between methods",
|
|
92245
92667
|
shortDescription: `Checks for newlines between method implementations.`,
|
|
92246
|
-
tags: [_irule_1.RuleTag.Whitespace, _irule_1.RuleTag.SingleFile],
|
|
92668
|
+
tags: [_irule_1.RuleTag.Whitespace, _irule_1.RuleTag.Quickfix, _irule_1.RuleTag.SingleFile],
|
|
92247
92669
|
};
|
|
92248
92670
|
}
|
|
92249
92671
|
getMessage() {
|
|
@@ -92272,18 +92694,35 @@ class NewlineBetweenMethods extends _abap_rule_1.ABAPRule {
|
|
|
92272
92694
|
continue;
|
|
92273
92695
|
}
|
|
92274
92696
|
let counter = 0;
|
|
92275
|
-
while (sequential_blank_1.SequentialBlank.isBlankOrWhitespace(rows[nextRow])
|
|
92697
|
+
while (sequential_blank_1.SequentialBlank.isBlankOrWhitespace(rows[nextRow])) {
|
|
92276
92698
|
counter++;
|
|
92277
92699
|
nextRow++;
|
|
92278
92700
|
}
|
|
92279
92701
|
if ((counter !== this.conf.count && this.conf.logic === NewlineLogic.Exact)
|
|
92280
92702
|
|| (counter >= this.conf.count && this.conf.logic === NewlineLogic.Less)
|
|
92281
92703
|
|| counter === 0) {
|
|
92282
|
-
|
|
92704
|
+
const fix = this.buildFix(file, rows, statement.getStart().getRow(), counter);
|
|
92705
|
+
issues.push(issue_1.Issue.atStatement(file, statement, this.getMessage(), this.getMetadata().key, this.conf.severity, fix));
|
|
92283
92706
|
}
|
|
92284
92707
|
}
|
|
92285
92708
|
return issues;
|
|
92286
92709
|
}
|
|
92710
|
+
buildFix(file, rows, row, blanks) {
|
|
92711
|
+
let target = this.conf.count;
|
|
92712
|
+
if (this.conf.logic === NewlineLogic.Less) {
|
|
92713
|
+
target = blanks === 0 ? 1 : this.conf.count - 1;
|
|
92714
|
+
}
|
|
92715
|
+
if (blanks < target) {
|
|
92716
|
+
const end = new position_1.Position(row, rows[row - 1].length + 1);
|
|
92717
|
+
return edit_helper_1.EditHelper.insertAt(file, end, "\n".repeat(target - blanks));
|
|
92718
|
+
}
|
|
92719
|
+
else if (blanks > target) {
|
|
92720
|
+
const start = new position_1.Position(row + target, rows[row + target - 1].length + 1);
|
|
92721
|
+
const end = new position_1.Position(row + blanks, rows[row + blanks - 1].length + 1);
|
|
92722
|
+
return edit_helper_1.EditHelper.deleteRange(file, start, end);
|
|
92723
|
+
}
|
|
92724
|
+
return undefined;
|
|
92725
|
+
}
|
|
92287
92726
|
isConfigurationValid() {
|
|
92288
92727
|
if (this.conf.count < 1 || (this.conf.count === 1 && this.conf.logic === NewlineLogic.Less)) {
|
|
92289
92728
|
return false;
|
|
@@ -97208,7 +97647,7 @@ class PreferPragmas extends _abap_rule_1.ABAPRule {
|
|
|
97208
97647
|
return {
|
|
97209
97648
|
key: "prefer_pragmas",
|
|
97210
97649
|
title: "prefer pragmas over pseudo comments ",
|
|
97211
|
-
shortDescription: `prefer pragmas over pseudo comments
|
|
97650
|
+
shortDescription: `prefer pragmas over pseudo comments`,
|
|
97212
97651
|
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-pragmas-to-pseudo-comments`,
|
|
97213
97652
|
tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Styleguide],
|
|
97214
97653
|
badExample: `DATA foo1 TYPE i. "#EC NEEDED`,
|
|
@@ -98725,6 +99164,173 @@ exports.ReduceStringTemplates = ReduceStringTemplates;
|
|
|
98725
99164
|
|
|
98726
99165
|
/***/ },
|
|
98727
99166
|
|
|
99167
|
+
/***/ "./node_modules/@abaplint/core/build/src/rules/redundant_cast.js"
|
|
99168
|
+
/*!***********************************************************************!*\
|
|
99169
|
+
!*** ./node_modules/@abaplint/core/build/src/rules/redundant_cast.js ***!
|
|
99170
|
+
\***********************************************************************/
|
|
99171
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
99172
|
+
|
|
99173
|
+
"use strict";
|
|
99174
|
+
|
|
99175
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
99176
|
+
if (k2 === undefined) k2 = k;
|
|
99177
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
99178
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
99179
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
99180
|
+
}
|
|
99181
|
+
Object.defineProperty(o, k2, desc);
|
|
99182
|
+
}) : (function(o, m, k, k2) {
|
|
99183
|
+
if (k2 === undefined) k2 = k;
|
|
99184
|
+
o[k2] = m[k];
|
|
99185
|
+
}));
|
|
99186
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
99187
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
99188
|
+
}) : function(o, v) {
|
|
99189
|
+
o["default"] = v;
|
|
99190
|
+
});
|
|
99191
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
99192
|
+
var ownKeys = function(o) {
|
|
99193
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
99194
|
+
var ar = [];
|
|
99195
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
99196
|
+
return ar;
|
|
99197
|
+
};
|
|
99198
|
+
return ownKeys(o);
|
|
99199
|
+
};
|
|
99200
|
+
return function (mod) {
|
|
99201
|
+
if (mod && mod.__esModule) return mod;
|
|
99202
|
+
var result = {};
|
|
99203
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
99204
|
+
__setModuleDefault(result, mod);
|
|
99205
|
+
return result;
|
|
99206
|
+
};
|
|
99207
|
+
})();
|
|
99208
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
99209
|
+
exports.RedundantCast = exports.RedundantCastConf = void 0;
|
|
99210
|
+
const Expressions = __importStar(__webpack_require__(/*! ../abap/2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js"));
|
|
99211
|
+
const _reference_1 = __webpack_require__(/*! ../abap/5_syntax/_reference */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_reference.js");
|
|
99212
|
+
const syntax_1 = __webpack_require__(/*! ../abap/5_syntax/syntax */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/syntax.js");
|
|
99213
|
+
const nodes_1 = __webpack_require__(/*! ../abap/nodes */ "./node_modules/@abaplint/core/build/src/abap/nodes/index.js");
|
|
99214
|
+
const _typed_identifier_1 = __webpack_require__(/*! ../abap/types/_typed_identifier */ "./node_modules/@abaplint/core/build/src/abap/types/_typed_identifier.js");
|
|
99215
|
+
const basic_1 = __webpack_require__(/*! ../abap/types/basic */ "./node_modules/@abaplint/core/build/src/abap/types/basic/index.js");
|
|
99216
|
+
const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
|
|
99217
|
+
const _abap_object_1 = __webpack_require__(/*! ../objects/_abap_object */ "./node_modules/@abaplint/core/build/src/objects/_abap_object.js");
|
|
99218
|
+
const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
|
|
99219
|
+
const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
|
|
99220
|
+
const edit_helper_1 = __webpack_require__(/*! ../edit_helper */ "./node_modules/@abaplint/core/build/src/edit_helper.js");
|
|
99221
|
+
const version_1 = __webpack_require__(/*! ../version */ "./node_modules/@abaplint/core/build/src/version.js");
|
|
99222
|
+
class RedundantCastConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
99223
|
+
}
|
|
99224
|
+
exports.RedundantCastConf = RedundantCastConf;
|
|
99225
|
+
class RedundantCast {
|
|
99226
|
+
constructor() {
|
|
99227
|
+
this.conf = new RedundantCastConf();
|
|
99228
|
+
}
|
|
99229
|
+
getMetadata() {
|
|
99230
|
+
return {
|
|
99231
|
+
key: "redundant_cast",
|
|
99232
|
+
title: "Redundant Cast",
|
|
99233
|
+
shortDescription: `Find redundant CAST expressions`,
|
|
99234
|
+
extendedInformation: `Reports CAST expressions whose operand is already a reference to the cast's target class or interface.`,
|
|
99235
|
+
tags: [_irule_1.RuleTag.Quickfix],
|
|
99236
|
+
badExample: `DATA ref TYPE REF TO lcl.
|
|
99237
|
+
DATA(copy) = CAST lcl( ref ).`,
|
|
99238
|
+
goodExample: `DATA ref TYPE REF TO lcl.
|
|
99239
|
+
DATA(copy) = ref.`,
|
|
99240
|
+
};
|
|
99241
|
+
}
|
|
99242
|
+
getConfig() {
|
|
99243
|
+
return this.conf;
|
|
99244
|
+
}
|
|
99245
|
+
setConfig(conf) {
|
|
99246
|
+
this.conf = conf;
|
|
99247
|
+
}
|
|
99248
|
+
initialize(reg) {
|
|
99249
|
+
this.reg = reg;
|
|
99250
|
+
return this;
|
|
99251
|
+
}
|
|
99252
|
+
run(obj) {
|
|
99253
|
+
var _a;
|
|
99254
|
+
if (!(0, version_1.releaseAtLeast)(this.reg.getConfig().getRelease(), version_1.Release.v740sp02)
|
|
99255
|
+
&& !this.reg.getConfig().isOpenABAP()) {
|
|
99256
|
+
return [];
|
|
99257
|
+
}
|
|
99258
|
+
if (!(obj instanceof _abap_object_1.ABAPObject)) {
|
|
99259
|
+
return [];
|
|
99260
|
+
}
|
|
99261
|
+
const syntax = new syntax_1.SyntaxLogic(this.reg, obj).run();
|
|
99262
|
+
if (syntax.issues.length > 0) {
|
|
99263
|
+
return [];
|
|
99264
|
+
}
|
|
99265
|
+
const issues = [];
|
|
99266
|
+
for (const file of obj.getABAPFiles()) {
|
|
99267
|
+
const structure = file.getStructure();
|
|
99268
|
+
if (structure === undefined) {
|
|
99269
|
+
continue;
|
|
99270
|
+
}
|
|
99271
|
+
for (const cast of structure.findAllExpressionsRecursive(Expressions.Cast)) {
|
|
99272
|
+
const typeExpression = cast.findDirectExpression(Expressions.TypeNameOrInfer);
|
|
99273
|
+
const source = cast.findDirectExpression(Expressions.Source);
|
|
99274
|
+
if (typeExpression === undefined
|
|
99275
|
+
|| source === undefined
|
|
99276
|
+
|| cast.findDirectExpression(Expressions.Let) !== undefined) {
|
|
99277
|
+
continue;
|
|
99278
|
+
}
|
|
99279
|
+
const scope = syntax.spaghetti.lookupPosition(cast.getFirstToken().getStart(), file.getFilename());
|
|
99280
|
+
if (scope === undefined) {
|
|
99281
|
+
continue;
|
|
99282
|
+
}
|
|
99283
|
+
const target = (_a = scope.getData().references.find(reference => reference.referenceType === _reference_1.ReferenceType.InferredType
|
|
99284
|
+
&& reference.position.getStart().equals(typeExpression.getFirstToken().getStart()))) === null || _a === void 0 ? void 0 : _a.resolved;
|
|
99285
|
+
if (!(target instanceof _typed_identifier_1.TypedIdentifier)) {
|
|
99286
|
+
continue;
|
|
99287
|
+
}
|
|
99288
|
+
const operandType = this.sourceType(source, scope);
|
|
99289
|
+
if (operandType === undefined || this.sameType(target.getType(), operandType) === false) {
|
|
99290
|
+
continue;
|
|
99291
|
+
}
|
|
99292
|
+
const closingParen = cast.getDirectTokens().find(token => token.getStr() === ")" && token.getStart().isAfter(source.getLastToken().getStart()));
|
|
99293
|
+
if (closingParen === undefined) {
|
|
99294
|
+
continue;
|
|
99295
|
+
}
|
|
99296
|
+
const fix = edit_helper_1.EditHelper.replaceRange(file, cast.getFirstToken().getStart(), closingParen.getEnd(), source.concatTokens());
|
|
99297
|
+
issues.push(issue_1.Issue.atRange(file, cast.getFirstToken().getStart(), closingParen.getEnd(), "Redundant CAST expression", this.getMetadata().key, this.conf.severity, fix));
|
|
99298
|
+
}
|
|
99299
|
+
}
|
|
99300
|
+
return issues;
|
|
99301
|
+
}
|
|
99302
|
+
/** The type of a plain variable or attribute, undefined for anything more complex */
|
|
99303
|
+
sourceType(source, scope) {
|
|
99304
|
+
var _a;
|
|
99305
|
+
const children = source.getChildren();
|
|
99306
|
+
if (children.length !== 1 || !(children[0].get() instanceof Expressions.FieldChain)) {
|
|
99307
|
+
return undefined;
|
|
99308
|
+
}
|
|
99309
|
+
const fieldChain = children[0];
|
|
99310
|
+
const last = fieldChain.getLastChild();
|
|
99311
|
+
if (!(last instanceof nodes_1.ExpressionNode)
|
|
99312
|
+
|| !(last.get() instanceof Expressions.SourceField || last.get() instanceof Expressions.AttributeName)) {
|
|
99313
|
+
return undefined;
|
|
99314
|
+
}
|
|
99315
|
+
const operand = (_a = scope.getData().references.find(reference => reference.referenceType === _reference_1.ReferenceType.DataReadReference
|
|
99316
|
+
&& reference.position.getStart().equals(last.getFirstToken().getStart()))) === null || _a === void 0 ? void 0 : _a.resolved;
|
|
99317
|
+
if (!(operand instanceof _typed_identifier_1.TypedIdentifier)) {
|
|
99318
|
+
return undefined;
|
|
99319
|
+
}
|
|
99320
|
+
return operand.getType();
|
|
99321
|
+
}
|
|
99322
|
+
sameType(first, second) {
|
|
99323
|
+
if (!(first instanceof basic_1.ObjectReferenceType) || !(second instanceof basic_1.ObjectReferenceType)) {
|
|
99324
|
+
return false;
|
|
99325
|
+
}
|
|
99326
|
+
return first.getIdentifierName().toUpperCase() === second.getIdentifierName().toUpperCase();
|
|
99327
|
+
}
|
|
99328
|
+
}
|
|
99329
|
+
exports.RedundantCast = RedundantCast;
|
|
99330
|
+
//# sourceMappingURL=redundant_cast.js.map
|
|
99331
|
+
|
|
99332
|
+
/***/ },
|
|
99333
|
+
|
|
98728
99334
|
/***/ "./node_modules/@abaplint/core/build/src/rules/redundant_conversion.js"
|
|
98729
99335
|
/*!*****************************************************************************!*\
|
|
98730
99336
|
!*** ./node_modules/@abaplint/core/build/src/rules/redundant_conversion.js ***!
|
|
@@ -98930,9 +99536,9 @@ text = text.`,
|
|
|
98930
99536
|
context = this.infer(context, this.sourceType(child, scope));
|
|
98931
99537
|
}
|
|
98932
99538
|
else if (child.get() instanceof Expressions.ArithOperator) {
|
|
98933
|
-
|
|
98934
|
-
|
|
98935
|
-
|
|
99539
|
+
// the CONV sets the calculation type of arithmetic expressions, only redundant
|
|
99540
|
+
// if the assignment target has the same type, see arithmeticUsesSameTargetType
|
|
99541
|
+
return undefined;
|
|
98936
99542
|
}
|
|
98937
99543
|
else {
|
|
98938
99544
|
return undefined;
|
|
@@ -107611,7 +108217,6 @@ const position_1 = __webpack_require__(/*! ../position */ "./node_modules/@abapl
|
|
|
107611
108217
|
const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
|
|
107612
108218
|
const _abap_object_1 = __webpack_require__(/*! ../objects/_abap_object */ "./node_modules/@abaplint/core/build/src/objects/_abap_object.js");
|
|
107613
108219
|
const severity_1 = __webpack_require__(/*! ../severity */ "./node_modules/@abaplint/core/build/src/severity.js");
|
|
107614
|
-
// todo, check for cycles/circular dependencies, method findTop
|
|
107615
108220
|
// todo, add configurable error for multiple use includes
|
|
107616
108221
|
const FMXXINCLUDE = /^(\/\w+\/)?L.+XX$/;
|
|
107617
108222
|
function getABAPObjects(reg) {
|
|
@@ -107647,11 +108252,33 @@ class Graph {
|
|
|
107647
108252
|
}
|
|
107648
108253
|
this.edges[from.filename].push(toFilename);
|
|
107649
108254
|
}
|
|
107650
|
-
|
|
108255
|
+
// true if "to" is reachable from "from" via the edges, "from" itself counts
|
|
108256
|
+
isReachable(from, to) {
|
|
108257
|
+
const seen = new Set();
|
|
108258
|
+
const stack = [from];
|
|
108259
|
+
while (stack.length > 0) {
|
|
108260
|
+
const current = stack.pop();
|
|
108261
|
+
if (current === to) {
|
|
108262
|
+
return true;
|
|
108263
|
+
}
|
|
108264
|
+
if (seen.has(current) === false) {
|
|
108265
|
+
seen.add(current);
|
|
108266
|
+
stack.push(...this.edges[current] || []);
|
|
108267
|
+
}
|
|
108268
|
+
}
|
|
108269
|
+
return false;
|
|
108270
|
+
}
|
|
108271
|
+
findTop(filename, path = new Set()) {
|
|
107651
108272
|
const ret = [];
|
|
108273
|
+
path.add(filename);
|
|
107652
108274
|
for (const to of this.edges[filename] || []) {
|
|
107653
|
-
|
|
108275
|
+
// an INCLUDE cycle, the file is already on the current path
|
|
108276
|
+
if (path.has(to)) {
|
|
108277
|
+
continue;
|
|
108278
|
+
}
|
|
108279
|
+
ret.push(...this.findTop(to, path));
|
|
107654
108280
|
}
|
|
108281
|
+
path.delete(filename);
|
|
107655
108282
|
if (ret.length === 0) {
|
|
107656
108283
|
const found = this.findVertexByFilename(filename);
|
|
107657
108284
|
if (found !== undefined) {
|
|
@@ -107706,6 +108333,7 @@ class IncludeGraph {
|
|
|
107706
108333
|
///////////////////////////////
|
|
107707
108334
|
build() {
|
|
107708
108335
|
this.addVertices();
|
|
108336
|
+
const included = [];
|
|
107709
108337
|
for (const o of getABAPObjects(this.reg)) {
|
|
107710
108338
|
for (const f of o.getABAPFiles()) {
|
|
107711
108339
|
if (f.getFilename().includes(".prog.screen_") || f.getFilename().includes(".fugr.screen_")) {
|
|
@@ -107736,11 +108364,19 @@ class IncludeGraph {
|
|
|
107736
108364
|
}
|
|
107737
108365
|
else {
|
|
107738
108366
|
this.graph.addEdge(found, f.getFilename());
|
|
108367
|
+
included.push({ file: f, statement: s, vertex: found, name });
|
|
107739
108368
|
}
|
|
107740
108369
|
}
|
|
107741
108370
|
}
|
|
107742
108371
|
}
|
|
107743
108372
|
}
|
|
108373
|
+
// cycles are not followed, but ABAP rejects them, so report them
|
|
108374
|
+
for (const i of included) {
|
|
108375
|
+
if (this.graph.isReachable(i.file.getFilename(), i.vertex.filename)) {
|
|
108376
|
+
const issue = issue_1.Issue.atStatement(i.file, i.statement, "Cyclic INCLUDE, " + i.name, new check_include_1.CheckInclude().getMetadata().key, this.severity);
|
|
108377
|
+
this.issues.push(issue);
|
|
108378
|
+
}
|
|
108379
|
+
}
|
|
107744
108380
|
}
|
|
107745
108381
|
addVertices() {
|
|
107746
108382
|
for (const o of getABAPObjects(this.reg)) {
|
|
@@ -119607,46 +120243,34 @@ exports.ConvertTranspiler = void 0;
|
|
|
119607
120243
|
const abaplint = __importStar(__webpack_require__(/*! @abaplint/core */ "./node_modules/@abaplint/core/build/src/index.js"));
|
|
119608
120244
|
const expressions_1 = __webpack_require__(/*! ../expressions */ "./node_modules/@abaplint/transpiler/build/src/expressions/index.js");
|
|
119609
120245
|
const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/transpiler/build/src/chunk.js");
|
|
120246
|
+
const OPERANDS = ["date", "time", "stamp", "utclong", "zone", "daylight"];
|
|
119610
120247
|
class ConvertTranspiler {
|
|
119611
120248
|
transpile(node, traversal) {
|
|
119612
|
-
const source =
|
|
119613
|
-
const target =
|
|
119614
|
-
|
|
119615
|
-
|
|
119616
|
-
|
|
119617
|
-
|
|
119618
|
-
|
|
119619
|
-
|
|
119620
|
-
|
|
119621
|
-
|
|
119622
|
-
|
|
119623
|
-
|
|
119624
|
-
|
|
119625
|
-
|
|
119626
|
-
|
|
119627
|
-
|
|
119628
|
-
|
|
119629
|
-
|
|
119630
|
-
|
|
119631
|
-
|
|
119632
|
-
|
|
119633
|
-
|
|
119634
|
-
}
|
|
119635
|
-
const utclong = node.findExpressionAfterToken("UTCLONG");
|
|
119636
|
-
if (utclong?.get() instanceof abaplint.Expressions.Source) {
|
|
119637
|
-
source.push("utclong: " + new expressions_1.SourceTranspiler().transpile(utclong, traversal).getCode());
|
|
119638
|
-
}
|
|
119639
|
-
else if (utclong?.get() instanceof abaplint.Expressions.Target) {
|
|
119640
|
-
target.push("utclong: " + new expressions_1.TargetTranspiler().transpile(utclong, traversal).getCode());
|
|
119641
|
-
}
|
|
119642
|
-
const zone = node.findExpressionAfterToken("ZONE");
|
|
119643
|
-
if (zone?.get() instanceof abaplint.Expressions.Source) {
|
|
119644
|
-
source.push("zone: " + new expressions_1.SourceTranspiler().transpile(zone, traversal).getCode());
|
|
119645
|
-
}
|
|
119646
|
-
else if (zone?.get() instanceof abaplint.Expressions.Target) {
|
|
119647
|
-
target.push("zone: " + new expressions_1.TargetTranspiler().transpile(zone, traversal).getCode());
|
|
120249
|
+
const source = {};
|
|
120250
|
+
const target = {};
|
|
120251
|
+
// each operand is named by the keyword in front of it; "TIME" after "SAVING" is the
|
|
120252
|
+
// daylight saving flag, which may come before or after the TIME operand
|
|
120253
|
+
const children = node.getChildren();
|
|
120254
|
+
for (let i = 1; i < children.length; i++) {
|
|
120255
|
+
const child = children[i];
|
|
120256
|
+
if (!(child instanceof abaplint.Nodes.ExpressionNode)) {
|
|
120257
|
+
continue;
|
|
120258
|
+
}
|
|
120259
|
+
const keyword = children[i - 1].concatTokens().toUpperCase();
|
|
120260
|
+
const before = i >= 2 ? children[i - 2].concatTokens().toUpperCase() : "";
|
|
120261
|
+
const name = keyword === "TIME" && before === "SAVING" ? "daylight" : keyword.toLowerCase();
|
|
120262
|
+
if (OPERANDS.includes(name) === false || source[name] !== undefined || target[name] !== undefined) {
|
|
120263
|
+
continue;
|
|
120264
|
+
}
|
|
120265
|
+
if (child.get() instanceof abaplint.Expressions.Source) {
|
|
120266
|
+
source[name] = new expressions_1.SourceTranspiler().transpile(child, traversal).getCode();
|
|
120267
|
+
}
|
|
120268
|
+
else if (child.get() instanceof abaplint.Expressions.Target) {
|
|
120269
|
+
target[name] = new expressions_1.TargetTranspiler().transpile(child, traversal).getCode();
|
|
120270
|
+
}
|
|
119648
120271
|
}
|
|
119649
|
-
|
|
120272
|
+
const list = (operands) => OPERANDS.filter(n => operands[n] !== undefined).map(n => n + ": " + operands[n]).join(",");
|
|
120273
|
+
return new chunk_1.Chunk(`abap.statements.convert({${list(source)}}, {${list(target)}});`);
|
|
119650
120274
|
}
|
|
119651
120275
|
}
|
|
119652
120276
|
exports.ConvertTranspiler = ConvertTranspiler;
|
|
@@ -130913,8 +131537,8 @@ class Traversal {
|
|
|
130913
131537
|
ret += "const sup = super();\n";
|
|
130914
131538
|
}
|
|
130915
131539
|
const cName = Traversal.escapeNamespace(def.getName().toLowerCase());
|
|
130916
|
-
ret += `this.me = new abap.types.ABAPObject();
|
|
130917
|
-
this.me.set(this);
|
|
131540
|
+
ret += `this.me = new abap.types.ABAPObject();
|
|
131541
|
+
this.me.set(this);
|
|
130918
131542
|
this.INTERNAL_ID = abap.internalIdCounter++;\n`;
|
|
130919
131543
|
ret += this.buildFriendsAccess(def, def.getSuperClass() !== undefined);
|
|
130920
131544
|
ret += this.buildThisAttributes(def, cName);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/transpiler-cli",
|
|
3
|
-
"version": "2.14.
|
|
3
|
+
"version": "2.14.7",
|
|
4
4
|
"description": "Transpiler - Command Line Interface",
|
|
5
5
|
"funding": "https://github.com/sponsors/larshp",
|
|
6
6
|
"bin": {
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"author": "abaplint",
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@abaplint/core": "^2.120.
|
|
31
|
-
"@abaplint/transpiler": "^2.14.
|
|
30
|
+
"@abaplint/core": "^2.120.80",
|
|
31
|
+
"@abaplint/transpiler": "^2.14.7",
|
|
32
32
|
"@types/glob": "^9.0.0",
|
|
33
33
|
"@types/node": "^26.6.2",
|
|
34
34
|
"@types/progress": "^2.0.7",
|