@abaplint/cli 2.120.68 → 2.120.71
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/cli.js +227 -17
- package/package.json +2 -2
package/build/cli.js
CHANGED
|
@@ -10389,7 +10389,7 @@ class StringTemplateFormatting extends combi_1.Expression {
|
|
|
10389
10389
|
const alpha = (0, combi_1.ver)(version_1.Release.v740sp02, (0, combi_1.seq)("ALPHA =", alphaOptions), { also: combi_1.AlsoIn.OpenABAP });
|
|
10390
10390
|
const xsd = (0, combi_1.ver)(version_1.Release.v740sp02, (0, combi_1.seq)("XSD =", zeroXSDOptions));
|
|
10391
10391
|
const country = (0, combi_1.seq)("COUNTRY =", _1.Source);
|
|
10392
|
-
const formatting = (0, combi_1.altPrio)((0, combi_1.seq)("TIME =", dateTimeOptions), (0, combi_1.seq)("DATE =", dateTimeOptions), (0, combi_1.seq)("CASE =", caseOptions), (0, combi_1.seq)("
|
|
10392
|
+
const formatting = (0, combi_1.altPrio)((0, combi_1.seq)("TIME =", dateTimeOptions), (0, combi_1.seq)("DATE =", dateTimeOptions), (0, combi_1.seq)("CASE =", caseOptions), (0, combi_1.seq)("ZERO =", zeroXSDOptions), xsd, (0, combi_1.seq)("STYLE =", styleOptions), (0, combi_1.seq)("CURRENCY =", _1.Source), (0, combi_1.per)(sign, number, decimals, width, pad, alpha, align, country, (0, combi_1.seq)("EXPONENT =", _1.Source)), (0, combi_1.per)(timezone, timestamp));
|
|
10393
10393
|
return formatting;
|
|
10394
10394
|
}
|
|
10395
10395
|
}
|
|
@@ -30121,12 +30121,15 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
30121
30121
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
30122
30122
|
exports.Compare = void 0;
|
|
30123
30123
|
const Expressions = __importStar(__webpack_require__(/*! ../../2_statements/expressions */ "../core/build/src/abap/2_statements/expressions/index.js"));
|
|
30124
|
+
const nodes_1 = __webpack_require__(/*! ../../nodes */ "../core/build/src/abap/nodes/index.js");
|
|
30124
30125
|
const source_1 = __webpack_require__(/*! ./source */ "../core/build/src/abap/5_syntax/expressions/source.js");
|
|
30125
30126
|
const method_call_chain_1 = __webpack_require__(/*! ./method_call_chain */ "../core/build/src/abap/5_syntax/expressions/method_call_chain.js");
|
|
30126
30127
|
const source_field_symbol_1 = __webpack_require__(/*! ./source_field_symbol */ "../core/build/src/abap/5_syntax/expressions/source_field_symbol.js");
|
|
30127
30128
|
const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "../core/build/src/abap/5_syntax/_syntax_input.js");
|
|
30128
30129
|
const basic_1 = __webpack_require__(/*! ../../types/basic */ "../core/build/src/abap/types/basic/index.js");
|
|
30129
30130
|
const _type_utils_1 = __webpack_require__(/*! ../_type_utils */ "../core/build/src/abap/5_syntax/_type_utils.js");
|
|
30131
|
+
const _builtin_1 = __webpack_require__(/*! ../_builtin */ "../core/build/src/abap/5_syntax/_builtin.js");
|
|
30132
|
+
const _object_oriented_1 = __webpack_require__(/*! ../_object_oriented */ "../core/build/src/abap/5_syntax/_object_oriented.js");
|
|
30130
30133
|
class Compare {
|
|
30131
30134
|
static runSyntax(node, input) {
|
|
30132
30135
|
var _a;
|
|
@@ -30141,6 +30144,11 @@ class Compare {
|
|
|
30141
30144
|
for (const t of node.findDirectExpressions(Expressions.MethodCallChain)) {
|
|
30142
30145
|
method_call_chain_1.MethodCallChain.runSyntax(t, input);
|
|
30143
30146
|
}
|
|
30147
|
+
const initialMessage = this.checkInitialOperand(node, input);
|
|
30148
|
+
if (initialMessage !== undefined) {
|
|
30149
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), initialMessage));
|
|
30150
|
+
return;
|
|
30151
|
+
}
|
|
30144
30152
|
const typeUtils = new _type_utils_1.TypeUtils(input.scope);
|
|
30145
30153
|
const compareOperator = (_a = node.findDirectExpression(Expressions.CompareOperator)) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase();
|
|
30146
30154
|
if (compareOperator === "CS"
|
|
@@ -30164,6 +30172,46 @@ class Compare {
|
|
|
30164
30172
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
30165
30173
|
}
|
|
30166
30174
|
}
|
|
30175
|
+
// a built-in function with a character-like result cannot be the operand of IS [NOT] INITIAL,
|
|
30176
|
+
// "Unexpected operator IS" on a system, while one with a numeric result, lines( ), can
|
|
30177
|
+
static checkInitialOperand(node, input) {
|
|
30178
|
+
var _a, _b, _c, _d;
|
|
30179
|
+
if (input.scope.getOpenABAP()) {
|
|
30180
|
+
return undefined;
|
|
30181
|
+
}
|
|
30182
|
+
const tokens = node.getChildren().filter(c => c instanceof nodes_1.TokenNode).map(c => c.getFirstToken().getStr().toUpperCase());
|
|
30183
|
+
if (tokens.includes("IS") === false || tokens[tokens.length - 1] !== "INITIAL") {
|
|
30184
|
+
return undefined;
|
|
30185
|
+
}
|
|
30186
|
+
const chain = (_a = node.findDirectExpression(Expressions.Source)) === null || _a === void 0 ? void 0 : _a.getChildren();
|
|
30187
|
+
// xsdbool( ) and boolc( ) are their own form in the Source grammar, a condition in parentheses
|
|
30188
|
+
const first = (_b = chain === null || chain === void 0 ? void 0 : chain[0]) === null || _b === void 0 ? void 0 : _b.getFirstToken().getStr().toUpperCase();
|
|
30189
|
+
if ((chain === null || chain === void 0 ? void 0 : chain.length) === 4 && chain[0] instanceof nodes_1.TokenNode && (first === "XSDBOOL" || first === "BOOLC")) {
|
|
30190
|
+
return `Built-in function "${chain[0].getFirstToken().getStr()}" cannot be the operand of IS INITIAL`;
|
|
30191
|
+
}
|
|
30192
|
+
if ((chain === null || chain === void 0 ? void 0 : chain.length) !== 1 || !(chain[0] instanceof nodes_1.ExpressionNode) || !(chain[0].get() instanceof Expressions.MethodCallChain)) {
|
|
30193
|
+
return undefined;
|
|
30194
|
+
}
|
|
30195
|
+
const calls = chain[0].getChildren();
|
|
30196
|
+
if (calls.length !== 1 || !(calls[0] instanceof nodes_1.ExpressionNode) || !(calls[0].get() instanceof Expressions.MethodCall)) {
|
|
30197
|
+
return undefined;
|
|
30198
|
+
}
|
|
30199
|
+
const name = (_c = calls[0].findDirectExpression(Expressions.MethodName)) === null || _c === void 0 ? void 0 : _c.concatTokens();
|
|
30200
|
+
const builtin = _builtin_1.BuiltIn.searchBuiltin(name);
|
|
30201
|
+
if (name === undefined || builtin === undefined) {
|
|
30202
|
+
return undefined;
|
|
30203
|
+
}
|
|
30204
|
+
// a method of the same name hides the built-in function
|
|
30205
|
+
const enclosing = input.scope.findClassDefinition(input.scope.getEnclosingClassName());
|
|
30206
|
+
if (enclosing !== undefined && new _object_oriented_1.ObjectOriented(input.scope).searchMethodName(enclosing, name).method !== undefined) {
|
|
30207
|
+
return undefined;
|
|
30208
|
+
}
|
|
30209
|
+
const returning = (_d = builtin.getParameters().getReturning()) === null || _d === void 0 ? void 0 : _d.getType();
|
|
30210
|
+
if (returning instanceof basic_1.StringType || returning instanceof basic_1.CharacterType) {
|
|
30211
|
+
return `Built-in function "${name}" cannot be the operand of IS INITIAL`;
|
|
30212
|
+
}
|
|
30213
|
+
return undefined;
|
|
30214
|
+
}
|
|
30167
30215
|
}
|
|
30168
30216
|
exports.Compare = Compare;
|
|
30169
30217
|
//# sourceMappingURL=compare.js.map
|
|
@@ -31936,6 +31984,9 @@ class FormParam {
|
|
|
31936
31984
|
else if (typeName === "P" && bfound instanceof basic_1.PackedType) {
|
|
31937
31985
|
bfound = basic_1.PGenericType.get();
|
|
31938
31986
|
}
|
|
31987
|
+
else if (typeName === "N" && bfound instanceof basic_1.NumericType) {
|
|
31988
|
+
bfound = basic_1.NGenericType.get();
|
|
31989
|
+
}
|
|
31939
31990
|
}
|
|
31940
31991
|
if (nameToken && bfound) {
|
|
31941
31992
|
return new _typed_identifier_1.TypedIdentifier(nameToken, input.filename, bfound, ["form_parameter" /* IdentifierMeta.FormParameter */]);
|
|
@@ -33322,6 +33373,9 @@ class MethodParam {
|
|
|
33322
33373
|
else if (concat === "TYPE P" || concat.startsWith("TYPE P ")) {
|
|
33323
33374
|
return new _typed_identifier_1.TypedIdentifier(name.getFirstToken(), input.filename, basic_1.PGenericType.get(), meta);
|
|
33324
33375
|
}
|
|
33376
|
+
else if (concat === "TYPE N" || concat.startsWith("TYPE N ")) {
|
|
33377
|
+
return new _typed_identifier_1.TypedIdentifier(name.getFirstToken(), input.filename, basic_1.NGenericType.get(), meta);
|
|
33378
|
+
}
|
|
33325
33379
|
const found = new basic_types_1.BasicTypes(input).parseType(type);
|
|
33326
33380
|
if (found) {
|
|
33327
33381
|
return new _typed_identifier_1.TypedIdentifier(name.getFirstToken(), input.filename, found, meta);
|
|
@@ -40024,9 +40078,9 @@ class CreateObject {
|
|
|
40024
40078
|
if (name === undefined) {
|
|
40025
40079
|
continue;
|
|
40026
40080
|
}
|
|
40027
|
-
const source = p.findDirectExpression(Expressions.Source);
|
|
40028
|
-
const sourceType = source_1.Source.runSyntax(source, input);
|
|
40029
40081
|
const found = allImporting === null || allImporting === void 0 ? void 0 : allImporting.find(p => p.getName().toUpperCase() === name);
|
|
40082
|
+
const source = p.findDirectExpression(Expressions.Source);
|
|
40083
|
+
const sourceType = source_1.Source.runSyntax(source, input, found === null || found === void 0 ? void 0 : found.getType());
|
|
40030
40084
|
if (found === undefined) {
|
|
40031
40085
|
const message = `constructor parameter "${name}" does not exist`;
|
|
40032
40086
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
@@ -51483,6 +51537,7 @@ __exportStar(__webpack_require__(/*! ./generic_object_reference_type */ "../core
|
|
|
51483
51537
|
__exportStar(__webpack_require__(/*! ./hex_type */ "../core/build/src/abap/types/basic/hex_type.js"), exports);
|
|
51484
51538
|
__exportStar(__webpack_require__(/*! ./integer_type */ "../core/build/src/abap/types/basic/integer_type.js"), exports);
|
|
51485
51539
|
__exportStar(__webpack_require__(/*! ./integer8_type */ "../core/build/src/abap/types/basic/integer8_type.js"), exports);
|
|
51540
|
+
__exportStar(__webpack_require__(/*! ./ngeneric_type */ "../core/build/src/abap/types/basic/ngeneric_type.js"), exports);
|
|
51486
51541
|
__exportStar(__webpack_require__(/*! ./numeric_generic_type */ "../core/build/src/abap/types/basic/numeric_generic_type.js"), exports);
|
|
51487
51542
|
__exportStar(__webpack_require__(/*! ./numeric_type */ "../core/build/src/abap/types/basic/numeric_type.js"), exports);
|
|
51488
51543
|
__exportStar(__webpack_require__(/*! ./object_reference_type */ "../core/build/src/abap/types/basic/object_reference_type.js"), exports);
|
|
@@ -51591,6 +51646,39 @@ IntegerType.singletons = new Map();
|
|
|
51591
51646
|
|
|
51592
51647
|
/***/ },
|
|
51593
51648
|
|
|
51649
|
+
/***/ "../core/build/src/abap/types/basic/ngeneric_type.js"
|
|
51650
|
+
/*!***********************************************************!*\
|
|
51651
|
+
!*** ../core/build/src/abap/types/basic/ngeneric_type.js ***!
|
|
51652
|
+
\***********************************************************/
|
|
51653
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
51654
|
+
|
|
51655
|
+
"use strict";
|
|
51656
|
+
|
|
51657
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
51658
|
+
exports.NGenericType = void 0;
|
|
51659
|
+
const numeric_type_1 = __webpack_require__(/*! ./numeric_type */ "../core/build/src/abap/types/basic/numeric_type.js");
|
|
51660
|
+
// "TYPE n" of a method or FORM parameter, where no length can be given.
|
|
51661
|
+
// It is a NumericType, so everything that handles n keeps treating it as such
|
|
51662
|
+
class NGenericType extends numeric_type_1.NumericType {
|
|
51663
|
+
static get() {
|
|
51664
|
+
return this.singleton;
|
|
51665
|
+
}
|
|
51666
|
+
constructor() {
|
|
51667
|
+
super(1);
|
|
51668
|
+
}
|
|
51669
|
+
toText() {
|
|
51670
|
+
return "```n```";
|
|
51671
|
+
}
|
|
51672
|
+
isGeneric() {
|
|
51673
|
+
return true;
|
|
51674
|
+
}
|
|
51675
|
+
}
|
|
51676
|
+
exports.NGenericType = NGenericType;
|
|
51677
|
+
NGenericType.singleton = new NGenericType();
|
|
51678
|
+
//# sourceMappingURL=ngeneric_type.js.map
|
|
51679
|
+
|
|
51680
|
+
/***/ },
|
|
51681
|
+
|
|
51594
51682
|
/***/ "../core/build/src/abap/types/basic/numeric_generic_type.js"
|
|
51595
51683
|
/*!******************************************************************!*\
|
|
51596
51684
|
!*** ../core/build/src/abap/types/basic/numeric_generic_type.js ***!
|
|
@@ -70485,7 +70573,7 @@ class Registry {
|
|
|
70485
70573
|
}
|
|
70486
70574
|
static abaplintVersion() {
|
|
70487
70575
|
// magic, see build script "version.js"
|
|
70488
|
-
return "2.120.
|
|
70576
|
+
return "2.120.71";
|
|
70489
70577
|
}
|
|
70490
70578
|
getDDICReferences() {
|
|
70491
70579
|
return this.ddicReferences;
|
|
@@ -73174,7 +73262,7 @@ exports.CDSCheckSyntaxConf = CDSCheckSyntaxConf;
|
|
|
73174
73262
|
const KNOWN_QUAN_DATA_ELEMENTS = ["MENGE_D"];
|
|
73175
73263
|
const KNOWN_CURR_DATA_ELEMENTS = ["BWERT", "DZWERT"];
|
|
73176
73264
|
// Reserved names, cannot be used as element names, see DDIC table TRESE
|
|
73177
|
-
const RESERVED_ELEMENT_NAMES = ["BEGIN", "NUMBER", "POSITION"];
|
|
73265
|
+
const RESERVED_ELEMENT_NAMES = ["BEGIN", "NUMBER", "POSITION", "ZONE", "HANDLER", "SECTION"];
|
|
73178
73266
|
const MAX_LABEL_LENGTH = 40;
|
|
73179
73267
|
// Annotations which are not supported in CDS view entities
|
|
73180
73268
|
const VIEW_ENTITY_FORBIDDEN_ANNOTATIONS = ["Semantics.unitOfMeasure", "Semantics.currencyCode"];
|
|
@@ -79984,8 +80072,17 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
79984
80072
|
const extra = (valueBody === null || valueBody === void 0 ? void 0 : valueBody.findDirectExpression(Expressions.For)) ? " " : "";
|
|
79985
80073
|
data = indentation + extra + `DATA ${structureName} LIKE LINE OF ${uniqueName}.\n`;
|
|
79986
80074
|
}
|
|
80075
|
+
// all rows are built in the same work area, a component a row leaves out must be initial,
|
|
80076
|
+
// not what an earlier row (or an earlier pass of a surrounding loop) put there
|
|
80077
|
+
const clearRows = valueBody !== undefined && this.valueRowsNeedClear(valueBody);
|
|
80078
|
+
const prefix = [];
|
|
79987
80079
|
for (const a of (valueBody === null || valueBody === void 0 ? void 0 : valueBody.getChildren()) || []) {
|
|
79988
80080
|
if (a.get() instanceof Expressions.FieldAssignment) {
|
|
80081
|
+
if (clearRows === true) {
|
|
80082
|
+
// the shared prefix applies to every following row, re-applied after each CLEAR
|
|
80083
|
+
prefix.push(a.concatTokens());
|
|
80084
|
+
continue;
|
|
80085
|
+
}
|
|
79989
80086
|
if (added === false) {
|
|
79990
80087
|
body += data;
|
|
79991
80088
|
added = true;
|
|
@@ -80009,6 +80106,16 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
80009
80106
|
}
|
|
80010
80107
|
if (a instanceof nodes_1.ExpressionNode && a.get() instanceof Expressions.ValueBodyLine) {
|
|
80011
80108
|
let skip = false;
|
|
80109
|
+
if (clearRows === true && this.isStructuredValueRow(a)) {
|
|
80110
|
+
if (added === false) {
|
|
80111
|
+
body += data;
|
|
80112
|
+
added = true;
|
|
80113
|
+
}
|
|
80114
|
+
body += indentation + `CLEAR ${structureName}.\n`;
|
|
80115
|
+
for (const p of prefix) {
|
|
80116
|
+
body += indentation + structureName + "-" + p + ".\n";
|
|
80117
|
+
}
|
|
80118
|
+
}
|
|
80012
80119
|
for (const b of (a === null || a === void 0 ? void 0 : a.getChildren()) || []) {
|
|
80013
80120
|
if (b.get() instanceof Expressions.FieldAssignment) {
|
|
80014
80121
|
if (added === false) {
|
|
@@ -80087,6 +80194,39 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
80087
80194
|
}
|
|
80088
80195
|
return undefined;
|
|
80089
80196
|
}
|
|
80197
|
+
/** a row that is built in the work area, ie. not "( source )" or "( LINES OF source )" */
|
|
80198
|
+
isStructuredValueRow(row) {
|
|
80199
|
+
return row.findDirectExpression(Expressions.Source) === undefined
|
|
80200
|
+
&& row.findDirectExpression(Expressions.ValueBodyLines) === undefined;
|
|
80201
|
+
}
|
|
80202
|
+
/** true if a row can observe a component that an earlier row, or an earlier pass of a surrounding loop,
|
|
80203
|
+
* left in the shared work area. Not the case if all rows assign the same components, and the shared
|
|
80204
|
+
* prefix is not changed between rows, eg. FOR rows or "( a = 1 b = 2 ) ( a = 3 b = 4 )" */
|
|
80205
|
+
valueRowsNeedClear(valueBody) {
|
|
80206
|
+
let shape = undefined;
|
|
80207
|
+
let rowSeen = false;
|
|
80208
|
+
for (const c of valueBody.getChildren()) {
|
|
80209
|
+
if (c.get() instanceof Expressions.FieldAssignment) {
|
|
80210
|
+
if (rowSeen === true) {
|
|
80211
|
+
return true;
|
|
80212
|
+
}
|
|
80213
|
+
}
|
|
80214
|
+
else if (c instanceof nodes_1.ExpressionNode
|
|
80215
|
+
&& c.get() instanceof Expressions.ValueBodyLine
|
|
80216
|
+
&& this.isStructuredValueRow(c)) {
|
|
80217
|
+
rowSeen = true;
|
|
80218
|
+
const current = c.findDirectExpressions(Expressions.FieldAssignment)
|
|
80219
|
+
.map(f => { var _a; return (_a = f.findDirectExpression(Expressions.FieldSub)) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase().replace(/\s/g, ""); })
|
|
80220
|
+
.sort()
|
|
80221
|
+
.join(",");
|
|
80222
|
+
if (shape !== undefined && shape !== current) {
|
|
80223
|
+
return true;
|
|
80224
|
+
}
|
|
80225
|
+
shape = current;
|
|
80226
|
+
}
|
|
80227
|
+
}
|
|
80228
|
+
return false;
|
|
80229
|
+
}
|
|
80090
80230
|
outlineLet(node, indentation, highSyntax, lowFile) {
|
|
80091
80231
|
var _a;
|
|
80092
80232
|
let ret = "";
|
|
@@ -94832,7 +94972,8 @@ class RedundantConversion {
|
|
|
94832
94972
|
key: "redundant_conversion",
|
|
94833
94973
|
title: "Redundant Conversion",
|
|
94834
94974
|
shortDescription: `Find redundant CONV expressions`,
|
|
94835
|
-
extendedInformation: `Reports CONV expressions whose operand already has the conversion's target type
|
|
94975
|
+
extendedInformation: `Reports CONV expressions whose operand already has the conversion's target type,
|
|
94976
|
+
including the result of a built-in function with a fixed result type, like to_upper( ) or strlen( ).`,
|
|
94836
94977
|
tags: [_irule_1.RuleTag.Quickfix],
|
|
94837
94978
|
badExample: `DATA text TYPE string.
|
|
94838
94979
|
text = CONV string( text ).`,
|
|
@@ -94869,7 +95010,8 @@ text = text.`,
|
|
|
94869
95010
|
if (structure === undefined) {
|
|
94870
95011
|
continue;
|
|
94871
95012
|
}
|
|
94872
|
-
|
|
95013
|
+
// recursive, a CONV can be the argument of a built-in function, which is itself a Source
|
|
95014
|
+
for (const source of structure.findAllExpressionsRecursive(Expressions.Source)) {
|
|
94873
95015
|
if (source.getFirstToken().getStr().toUpperCase() !== "CONV") {
|
|
94874
95016
|
continue;
|
|
94875
95017
|
}
|
|
@@ -94928,6 +95070,15 @@ text = text.`,
|
|
|
94928
95070
|
}
|
|
94929
95071
|
sourceType(source, scope) {
|
|
94930
95072
|
let context;
|
|
95073
|
+
// boolc( <condition> ) is not a MethodCallChain, xsdbool( ) has the same shape but is not reported
|
|
95074
|
+
const first = source.getFirstToken();
|
|
95075
|
+
if (first.getStr().toUpperCase() === "BOOLC"
|
|
95076
|
+
&& source.findDirectExpression(Expressions.Cond) !== undefined
|
|
95077
|
+
&& source.getChildren().length === 4
|
|
95078
|
+
&& scope.getData().references.some(reference => reference.referenceType === _reference_1.ReferenceType.BuiltinMethodReference
|
|
95079
|
+
&& reference.position.getStart().equals(first.getStart()))) {
|
|
95080
|
+
return basic_1.StringType.get();
|
|
95081
|
+
}
|
|
94931
95082
|
for (const child of source.getChildren()) {
|
|
94932
95083
|
if (!(child instanceof nodes_1.ExpressionNode)) {
|
|
94933
95084
|
continue;
|
|
@@ -94938,6 +95089,15 @@ text = text.`,
|
|
|
94938
95089
|
return undefined;
|
|
94939
95090
|
}
|
|
94940
95091
|
}
|
|
95092
|
+
else if (child.get() instanceof Expressions.MethodCallChain) {
|
|
95093
|
+
if (source.getChildren().length !== 1) {
|
|
95094
|
+
return undefined;
|
|
95095
|
+
}
|
|
95096
|
+
context = this.builtinResultType(child, scope);
|
|
95097
|
+
if (context === undefined) {
|
|
95098
|
+
return undefined;
|
|
95099
|
+
}
|
|
95100
|
+
}
|
|
94941
95101
|
else if (child.get() instanceof Expressions.Constant) {
|
|
94942
95102
|
context = this.infer(context, constant_1.Constant.runSyntax(child));
|
|
94943
95103
|
}
|
|
@@ -94958,6 +95118,32 @@ text = text.`,
|
|
|
94958
95118
|
}
|
|
94959
95119
|
return context;
|
|
94960
95120
|
}
|
|
95121
|
+
/** The result type of a call to a built-in function whose result type does not depend on its arguments,
|
|
95122
|
+
* undefined for anything else, e.g. abs( ) or xsdbool( ), or a method of the same name */
|
|
95123
|
+
builtinResultType(chain, scope) {
|
|
95124
|
+
var _a;
|
|
95125
|
+
const children = chain.getChildren();
|
|
95126
|
+
if (children.length !== 1 || !(children[0].get() instanceof Expressions.MethodCall)) {
|
|
95127
|
+
return undefined;
|
|
95128
|
+
}
|
|
95129
|
+
const name = (_a = children[0].findDirectExpression(Expressions.MethodName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
|
|
95130
|
+
if (name === undefined) {
|
|
95131
|
+
return undefined;
|
|
95132
|
+
}
|
|
95133
|
+
const isBuiltin = scope.getData().references.some(reference => reference.referenceType === _reference_1.ReferenceType.BuiltinMethodReference
|
|
95134
|
+
&& reference.position.getStart().equals(name.getStart()));
|
|
95135
|
+
if (isBuiltin === false) {
|
|
95136
|
+
return undefined;
|
|
95137
|
+
}
|
|
95138
|
+
const upper = name.getStr().toUpperCase();
|
|
95139
|
+
if (RedundantConversion.stringResult.has(upper)) {
|
|
95140
|
+
return basic_1.StringType.get();
|
|
95141
|
+
}
|
|
95142
|
+
else if (RedundantConversion.integerResult.has(upper)) {
|
|
95143
|
+
return basic_1.IntegerType.get();
|
|
95144
|
+
}
|
|
95145
|
+
return undefined;
|
|
95146
|
+
}
|
|
94961
95147
|
fieldChainType(fieldChain, scope) {
|
|
94962
95148
|
var _a;
|
|
94963
95149
|
const operand = (_a = scope.getData().references.find(reference => reference.referenceType === _reference_1.ReferenceType.DataReadReference
|
|
@@ -95022,6 +95208,17 @@ text = text.`,
|
|
|
95022
95208
|
}
|
|
95023
95209
|
}
|
|
95024
95210
|
exports.RedundantConversion = RedundantConversion;
|
|
95211
|
+
// built-in functions that always return a string, whatever their arguments
|
|
95212
|
+
RedundantConversion.stringResult = new Set([
|
|
95213
|
+
"BOOLC", "CONCAT_LINES_OF", "CONDENSE", "ESCAPE", "FROM_MIXED", "INSERT", "REPEAT", "REPLACE",
|
|
95214
|
+
"REVERSE", "SEGMENT", "SHIFT_LEFT", "SHIFT_RIGHT", "SUBSTRING", "SUBSTRING_AFTER", "SUBSTRING_BEFORE",
|
|
95215
|
+
"SUBSTRING_FROM", "SUBSTRING_TO", "TO_LOWER", "TO_MIXED", "TO_UPPER", "TRANSLATE"
|
|
95216
|
+
]);
|
|
95217
|
+
// built-in functions that always return an i
|
|
95218
|
+
RedundantConversion.integerResult = new Set([
|
|
95219
|
+
"CHARLEN", "COUNT", "COUNT_ANY_NOT_OF", "COUNT_ANY_OF", "DBMAXLEN", "DISTANCE", "FIND", "FIND_ANY_NOT_OF",
|
|
95220
|
+
"FIND_ANY_OF", "FIND_END", "LINES", "NUMOFCHAR", "STRLEN", "XSTRLEN"
|
|
95221
|
+
]);
|
|
95025
95222
|
//# sourceMappingURL=redundant_conversion.js.map
|
|
95026
95223
|
|
|
95027
95224
|
/***/ },
|
|
@@ -95362,7 +95559,9 @@ class RFCErrorHandling extends _abap_rule_1.ABAPRule {
|
|
|
95362
95559
|
title: "RFC error handling",
|
|
95363
95560
|
tags: [_irule_1.RuleTag.SingleFile],
|
|
95364
95561
|
shortDescription: `Checks that exceptions 'system_failure' and 'communication_failure' are handled in RFC calls`,
|
|
95365
|
-
extendedInformation: `
|
|
95562
|
+
extendedInformation: `RESOURCE_FAILURE is also required for asynchronous calls with DESTINATION IN GROUP.
|
|
95563
|
+
|
|
95564
|
+
https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/abenrfc_exception.html`,
|
|
95366
95565
|
badExample: `CALL FUNCTION 'ZRFC'
|
|
95367
95566
|
DESTINATION lv_rfc.`,
|
|
95368
95567
|
goodExample: `CALL FUNCTION 'ZRFC'
|
|
@@ -95370,12 +95569,12 @@ class RFCErrorHandling extends _abap_rule_1.ABAPRule {
|
|
|
95370
95569
|
EXCEPTIONS
|
|
95371
95570
|
system_failure = 1 MESSAGE msg
|
|
95372
95571
|
communication_failure = 2 MESSAGE msg
|
|
95373
|
-
|
|
95374
|
-
OTHERS = 4.`,
|
|
95572
|
+
OTHERS = 3.`,
|
|
95375
95573
|
};
|
|
95376
95574
|
}
|
|
95377
|
-
getMessage() {
|
|
95378
|
-
return "RFC error handling: At least one unhandled exception from SYSTEM_FAILURE, COMMUNICATION_FAILURE
|
|
95575
|
+
getMessage(requireResourceFailure) {
|
|
95576
|
+
return "RFC error handling: At least one unhandled exception from SYSTEM_FAILURE, COMMUNICATION_FAILURE"
|
|
95577
|
+
+ (requireResourceFailure ? ", RESOURCE_FAILURE" : "");
|
|
95379
95578
|
}
|
|
95380
95579
|
getConfig() {
|
|
95381
95580
|
return this.conf;
|
|
@@ -95390,12 +95589,15 @@ class RFCErrorHandling extends _abap_rule_1.ABAPRule {
|
|
|
95390
95589
|
if (!(stat.get() instanceof Statements.CallFunction)) {
|
|
95391
95590
|
continue;
|
|
95392
95591
|
}
|
|
95393
|
-
|
|
95592
|
+
const destination = stat.findFirstExpression(Expressions.Destination);
|
|
95593
|
+
if (destination === undefined) {
|
|
95394
95594
|
continue;
|
|
95395
95595
|
}
|
|
95596
|
+
const requireResourceFailure = stat.findDirectTokenByText("STARTING") !== undefined
|
|
95597
|
+
&& destination.findDirectTokenByText("GROUP") !== undefined;
|
|
95396
95598
|
const list = stat.findFirstExpression(Expressions.ParameterListExceptions);
|
|
95397
95599
|
if (list === undefined) {
|
|
95398
|
-
const issue = issue_1.Issue.atToken(file, token, this.getMessage(), this.getMetadata().key, this.conf.severity);
|
|
95600
|
+
const issue = issue_1.Issue.atToken(file, token, this.getMessage(requireResourceFailure), this.getMetadata().key, this.conf.severity);
|
|
95399
95601
|
output.push(issue);
|
|
95400
95602
|
continue;
|
|
95401
95603
|
}
|
|
@@ -95406,8 +95608,8 @@ class RFCErrorHandling extends _abap_rule_1.ABAPRule {
|
|
|
95406
95608
|
}
|
|
95407
95609
|
if (names.indexOf("SYSTEM_FAILURE") < 0
|
|
95408
95610
|
|| names.indexOf("COMMUNICATION_FAILURE") < 0
|
|
95409
|
-
|| names.indexOf("RESOURCE_FAILURE") < 0) {
|
|
95410
|
-
const issue = issue_1.Issue.atToken(file, token, this.getMessage(), this.getMetadata().key, this.conf.severity);
|
|
95611
|
+
|| (requireResourceFailure && names.indexOf("RESOURCE_FAILURE") < 0)) {
|
|
95612
|
+
const issue = issue_1.Issue.atToken(file, token, this.getMessage(requireResourceFailure), this.getMetadata().key, this.conf.severity);
|
|
95411
95613
|
output.push(issue);
|
|
95412
95614
|
continue;
|
|
95413
95615
|
}
|
|
@@ -102222,7 +102424,7 @@ class XMLConsistency {
|
|
|
102222
102424
|
}
|
|
102223
102425
|
runTable(obj, file) {
|
|
102224
102426
|
var _a, _b, _c, _d;
|
|
102225
|
-
var _e;
|
|
102427
|
+
var _e, _f;
|
|
102226
102428
|
const issues = [];
|
|
102227
102429
|
for (const field of (_e = obj.getFields()) !== null && _e !== void 0 ? _e : []) {
|
|
102228
102430
|
if (field.DATATYPE === "QUAN" && (!((_a = field.REFTABLE) === null || _a === void 0 ? void 0 : _a.trim()) || !((_b = field.REFFIELD) === null || _b === void 0 ? void 0 : _b.trim()))) {
|
|
@@ -102231,6 +102433,14 @@ class XMLConsistency {
|
|
|
102231
102433
|
}
|
|
102232
102434
|
}
|
|
102233
102435
|
if (obj.getTableCategory() === Objects.TableCategory.Transparent) {
|
|
102436
|
+
// Confirmed reserved database field names, see issue #4331, DAY and HOUR reported by activation.
|
|
102437
|
+
// TRESE also contains names such as TEXT and LENGTH which are allowed here.
|
|
102438
|
+
const reservedFieldNames = ["ZONE", "HANDLER", "SECTION", "PARAMETER", "DAY", "HOUR"];
|
|
102439
|
+
for (const field of (_f = obj.getFields()) !== null && _f !== void 0 ? _f : []) {
|
|
102440
|
+
if (reservedFieldNames.includes(field.FIELDNAME.toUpperCase())) {
|
|
102441
|
+
issues.push(issue_1.Issue.atRow(file, 1, `Table field name "${field.FIELDNAME}" is reserved`, this.getMetadata().key, this.conf.severity));
|
|
102442
|
+
}
|
|
102443
|
+
}
|
|
102234
102444
|
if (!((_c = obj.getDeliveryClass()) === null || _c === void 0 ? void 0 : _c.trim())) {
|
|
102235
102445
|
const message = `Transparent table must have delivery class(CONTFLAG in DD02V) set`;
|
|
102236
102446
|
issues.push(issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.conf.transparentTableSeverity));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/cli",
|
|
3
|
-
"version": "2.120.
|
|
3
|
+
"version": "2.120.71",
|
|
4
4
|
"description": "abaplint - Command Line Interface",
|
|
5
5
|
"funding": "https://github.com/sponsors/larshp",
|
|
6
6
|
"bin": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"homepage": "https://abaplint.org",
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@abaplint/core": "^2.120.
|
|
42
|
+
"@abaplint/core": "^2.120.71",
|
|
43
43
|
"@types/chai": "^4.3.20",
|
|
44
44
|
"@types/minimist": "^1.2.5",
|
|
45
45
|
"@types/mocha": "^10.0.10",
|