@abaplint/cli 2.120.28 → 2.120.30
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 +247 -28
- package/package.json +2 -2
package/build/cli.js
CHANGED
|
@@ -3781,10 +3781,10 @@ exports.ClassName = ClassName;
|
|
|
3781
3781
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
3782
3782
|
exports.Color = void 0;
|
|
3783
3783
|
const combi_1 = __webpack_require__(/*! ../combi */ "../core/build/src/abap/2_statements/combi.js");
|
|
3784
|
-
const
|
|
3784
|
+
const simple_source3_1 = __webpack_require__(/*! ./simple_source3 */ "../core/build/src/abap/2_statements/expressions/simple_source3.js");
|
|
3785
3785
|
class Color extends combi_1.Expression {
|
|
3786
3786
|
getRunnable() {
|
|
3787
|
-
const eq = (0, combi_1.seq)("=",
|
|
3787
|
+
const eq = (0, combi_1.seq)("=", simple_source3_1.SimpleSource3);
|
|
3788
3788
|
const integers = (0, combi_1.altPrio)("1", "2", "3", "4", "5", "6", "7");
|
|
3789
3789
|
const texts = (0, combi_1.altPrio)("COL_BACKGROUND", "COL_HEADING", "COL_NORMAL", "COL_TOTAL", "COL_KEY", "COL_POSITIVE", "COL_NEGATIVE", "COL_GROUP");
|
|
3790
3790
|
const value = (0, combi_1.alt)(eq, (0, combi_1.altPrio)("ON", "OFF", "COLOR OFF", (0, combi_1.altPrio)(integers, texts)));
|
|
@@ -26676,6 +26676,31 @@ class ObjectOriented {
|
|
|
26676
26676
|
}
|
|
26677
26677
|
return ret;
|
|
26678
26678
|
}
|
|
26679
|
+
// does the supplied class have friendship with "friendName"?
|
|
26680
|
+
// note that interfaces of the friend, and subclasses of the friend also have friendship
|
|
26681
|
+
hasFriendship(cd, friendName) {
|
|
26682
|
+
var _a;
|
|
26683
|
+
const friends = cd.getFriends().map(f => f.toUpperCase());
|
|
26684
|
+
const isFriend = (name) => friends.includes(name.toUpperCase()) || this.scope.isLocalFriend(cd.getName(), name);
|
|
26685
|
+
if (isFriend(friendName)) {
|
|
26686
|
+
return true;
|
|
26687
|
+
}
|
|
26688
|
+
const friendDefinition = this.scope.findClassDefinition(friendName);
|
|
26689
|
+
if (friendDefinition === undefined) {
|
|
26690
|
+
return false;
|
|
26691
|
+
}
|
|
26692
|
+
if (this.findInterfaces(friendDefinition).some(i => friends.includes(i.name.toUpperCase()))) {
|
|
26693
|
+
return true;
|
|
26694
|
+
}
|
|
26695
|
+
let sup = friendDefinition.getSuperClass();
|
|
26696
|
+
while (sup !== undefined) {
|
|
26697
|
+
if (isFriend(sup)) {
|
|
26698
|
+
return true;
|
|
26699
|
+
}
|
|
26700
|
+
sup = (_a = this.scope.findClassDefinition(sup)) === null || _a === void 0 ? void 0 : _a.getSuperClass();
|
|
26701
|
+
}
|
|
26702
|
+
return false;
|
|
26703
|
+
}
|
|
26679
26704
|
searchEvent(def, name) {
|
|
26680
26705
|
if (def === undefined || name === undefined) {
|
|
26681
26706
|
return undefined;
|
|
@@ -27865,6 +27890,9 @@ class TypeUtils {
|
|
|
27865
27890
|
console.dir(source);
|
|
27866
27891
|
console.dir(target);
|
|
27867
27892
|
*/
|
|
27893
|
+
if (source instanceof basic_1.UTCLongType || target instanceof basic_1.UTCLongType) {
|
|
27894
|
+
return this.isUTCLongAssignable(source, target);
|
|
27895
|
+
}
|
|
27868
27896
|
if (target instanceof basic_1.TableType) {
|
|
27869
27897
|
if (target.isWithHeader()) {
|
|
27870
27898
|
return this.isAssignable(source, target.getRowType());
|
|
@@ -28016,6 +28044,33 @@ class TypeUtils {
|
|
|
28016
28044
|
}
|
|
28017
28045
|
return true;
|
|
28018
28046
|
}
|
|
28047
|
+
// utclong can only be converted to and from character like types
|
|
28048
|
+
isUTCLongAssignable(source, target) {
|
|
28049
|
+
if (this.isGenericOrVoid(source) || this.isGenericOrVoid(target)) {
|
|
28050
|
+
return true;
|
|
28051
|
+
}
|
|
28052
|
+
else if (source instanceof basic_1.UTCLongType && target instanceof basic_1.UTCLongType) {
|
|
28053
|
+
return true;
|
|
28054
|
+
}
|
|
28055
|
+
else if (source instanceof basic_1.UTCLongType) {
|
|
28056
|
+
return this.isTextLike(target);
|
|
28057
|
+
}
|
|
28058
|
+
return this.isTextLike(source);
|
|
28059
|
+
}
|
|
28060
|
+
isGenericOrVoid(type) {
|
|
28061
|
+
return type instanceof basic_1.VoidType
|
|
28062
|
+
|| type instanceof basic_1.AnyType
|
|
28063
|
+
|| type instanceof basic_1.DataType
|
|
28064
|
+
|| type instanceof basic_1.UnknownType;
|
|
28065
|
+
}
|
|
28066
|
+
isTextLike(type) {
|
|
28067
|
+
return type instanceof basic_1.CharacterType
|
|
28068
|
+
|| type instanceof basic_1.StringType
|
|
28069
|
+
|| type instanceof basic_1.CLikeType
|
|
28070
|
+
|| type instanceof basic_1.CSequenceType
|
|
28071
|
+
|| type instanceof cgeneric_type_1.CGenericType
|
|
28072
|
+
|| type instanceof basic_1.SimpleType;
|
|
28073
|
+
}
|
|
28019
28074
|
}
|
|
28020
28075
|
exports.TypeUtils = TypeUtils;
|
|
28021
28076
|
//# sourceMappingURL=_type_utils.js.map
|
|
@@ -28098,6 +28153,7 @@ const types_1 = __webpack_require__(/*! ../types */ "../core/build/src/abap/type
|
|
|
28098
28153
|
const expressions_1 = __webpack_require__(/*! ../2_statements/expressions */ "../core/build/src/abap/2_statements/expressions/index.js");
|
|
28099
28154
|
const _builtin_1 = __webpack_require__(/*! ./_builtin */ "../core/build/src/abap/5_syntax/_builtin.js");
|
|
28100
28155
|
const position_1 = __webpack_require__(/*! ../../position */ "../core/build/src/position.js");
|
|
28156
|
+
const _syntax_input_1 = __webpack_require__(/*! ./_syntax_input */ "../core/build/src/abap/5_syntax/_syntax_input.js");
|
|
28101
28157
|
class BasicTypes {
|
|
28102
28158
|
constructor(input) {
|
|
28103
28159
|
this.input = input;
|
|
@@ -29038,6 +29094,13 @@ class BasicTypes {
|
|
|
29038
29094
|
}
|
|
29039
29095
|
const chain = val.findFirstExpression(Expressions.SimpleFieldChain);
|
|
29040
29096
|
if (chain) {
|
|
29097
|
+
// todo, hardcoded for now, should be a generic check that the chain is a constant
|
|
29098
|
+
const concat = chain.concatTokens().toUpperCase();
|
|
29099
|
+
if (concat === "SY-DATUM" || concat === "SY-UZEIT") {
|
|
29100
|
+
const message = "VALUE, " + concat.toLowerCase() + " is not a constant";
|
|
29101
|
+
this.input.issues.push((0, _syntax_input_1.syntaxIssue)(this.input, chain.getFirstToken(), message));
|
|
29102
|
+
return undefined;
|
|
29103
|
+
}
|
|
29041
29104
|
return this.resolveConstantValue(chain);
|
|
29042
29105
|
}
|
|
29043
29106
|
throw new Error("findValue, unexpected");
|
|
@@ -32311,6 +32374,8 @@ const _reference_1 = __webpack_require__(/*! ../_reference */ "../core/build/src
|
|
|
32311
32374
|
const component_name_1 = __webpack_require__(/*! ./component_name */ "../core/build/src/abap/5_syntax/expressions/component_name.js");
|
|
32312
32375
|
const attribute_name_1 = __webpack_require__(/*! ./attribute_name */ "../core/build/src/abap/5_syntax/expressions/attribute_name.js");
|
|
32313
32376
|
const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "../core/build/src/abap/5_syntax/_syntax_input.js");
|
|
32377
|
+
const visibility_1 = __webpack_require__(/*! ../../4_file_information/visibility */ "../core/build/src/abap/4_file_information/visibility.js");
|
|
32378
|
+
const class_definition_1 = __webpack_require__(/*! ../../types/class_definition */ "../core/build/src/abap/types/class_definition.js");
|
|
32314
32379
|
class MethodCallChain {
|
|
32315
32380
|
static runSyntax(node, input, targetType) {
|
|
32316
32381
|
var _a, _b;
|
|
@@ -32359,6 +32424,12 @@ class MethodCallChain {
|
|
|
32359
32424
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, methodToken, message));
|
|
32360
32425
|
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
32361
32426
|
}
|
|
32427
|
+
const notVisible = method ? this.checkVisibility(method, def, foundDef, input) : undefined;
|
|
32428
|
+
if (notVisible !== undefined) {
|
|
32429
|
+
const message = `Method "${methodName}" is ${notVisible} and cannot be accessed`;
|
|
32430
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, methodToken, message));
|
|
32431
|
+
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
32432
|
+
}
|
|
32362
32433
|
const voidedName = context instanceof basic_1.VoidType ? context.getVoided() : undefined;
|
|
32363
32434
|
const extra = helper.methodReferenceExtras(foundDef, className || voidedName);
|
|
32364
32435
|
input.scope.addReference(methodToken, method, _reference_1.ReferenceType.MethodReference, input.filename, extra);
|
|
@@ -32401,6 +32472,47 @@ class MethodCallChain {
|
|
|
32401
32472
|
return context;
|
|
32402
32473
|
}
|
|
32403
32474
|
//////////////////////////////////////
|
|
32475
|
+
// returns the visibility as text if the method cannot be accessed from the current scope
|
|
32476
|
+
static checkVisibility(method, def, foundDef, input) {
|
|
32477
|
+
var _a, _b, _c;
|
|
32478
|
+
const visibility = method.getVisibility();
|
|
32479
|
+
if (visibility === visibility_1.Visibility.Public || foundDef === undefined) {
|
|
32480
|
+
return undefined;
|
|
32481
|
+
}
|
|
32482
|
+
else if (!(foundDef instanceof class_definition_1.ClassDefinition)) {
|
|
32483
|
+
// interface members are always public
|
|
32484
|
+
return undefined;
|
|
32485
|
+
}
|
|
32486
|
+
const name = foundDef.getName().toUpperCase();
|
|
32487
|
+
const enclosing = (_a = input.scope.getEnclosingClassName()) === null || _a === void 0 ? void 0 : _a.toUpperCase();
|
|
32488
|
+
if (enclosing === undefined || enclosing === name) {
|
|
32489
|
+
return undefined;
|
|
32490
|
+
}
|
|
32491
|
+
// friendship with the class used at the call site also gives access to inherited members
|
|
32492
|
+
const helper = new _object_oriented_1.ObjectOriented(input.scope);
|
|
32493
|
+
const visited = [];
|
|
32494
|
+
let current = def instanceof class_definition_1.ClassDefinition ? def : foundDef;
|
|
32495
|
+
while (current !== undefined && visited.includes(current.getName().toUpperCase()) === false) {
|
|
32496
|
+
visited.push(current.getName().toUpperCase());
|
|
32497
|
+
if (helper.hasFriendship(current, enclosing)) {
|
|
32498
|
+
return undefined;
|
|
32499
|
+
}
|
|
32500
|
+
const sup = current.getSuperClass();
|
|
32501
|
+
current = sup === undefined ? undefined : input.scope.findClassDefinition(sup);
|
|
32502
|
+
}
|
|
32503
|
+
if (visibility === visibility_1.Visibility.Protected) {
|
|
32504
|
+
// subclasses can access protected members
|
|
32505
|
+
let sup = (_b = input.scope.findClassDefinition(enclosing)) === null || _b === void 0 ? void 0 : _b.getSuperClass();
|
|
32506
|
+
while (sup !== undefined) {
|
|
32507
|
+
if (sup.toUpperCase() === name) {
|
|
32508
|
+
return undefined;
|
|
32509
|
+
}
|
|
32510
|
+
sup = (_c = input.scope.findClassDefinition(sup)) === null || _c === void 0 ? void 0 : _c.getSuperClass();
|
|
32511
|
+
}
|
|
32512
|
+
return "protected";
|
|
32513
|
+
}
|
|
32514
|
+
return "private";
|
|
32515
|
+
}
|
|
32404
32516
|
static findTop(first, input, targetType) {
|
|
32405
32517
|
var _a;
|
|
32406
32518
|
if (first.get() instanceof Expressions.ClassName) {
|
|
@@ -35069,6 +35181,7 @@ const basic_1 = __webpack_require__(/*! ../../types/basic */ "../core/build/src/
|
|
|
35069
35181
|
const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "../core/build/src/abap/5_syntax/_syntax_input.js");
|
|
35070
35182
|
const sql_set_op_group_1 = __webpack_require__(/*! ./sql_set_op_group */ "../core/build/src/abap/5_syntax/expressions/sql_set_op_group.js");
|
|
35071
35183
|
const sql_source_1 = __webpack_require__(/*! ./sql_source */ "../core/build/src/abap/5_syntax/expressions/sql_source.js");
|
|
35184
|
+
const RANGE_COMPONENTS = ["SIGN", "OPTION", "LOW", "HIGH"];
|
|
35072
35185
|
class SQLIn {
|
|
35073
35186
|
static runSyntax(node, input) {
|
|
35074
35187
|
const setop = node.findDirectExpression(Expressions.SQLSetOpGroup);
|
|
@@ -35088,6 +35201,12 @@ class SQLIn {
|
|
|
35088
35201
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
35089
35202
|
return;
|
|
35090
35203
|
}
|
|
35204
|
+
if (intype instanceof basic_1.TableType && this.isRangeRow(intype.getRowType()) === false) {
|
|
35205
|
+
const name = insource.concatTokens().replace(/^@/, "").replace(/\[\]$/, "");
|
|
35206
|
+
const message = `row structure of ${name} is not correct`;
|
|
35207
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
35208
|
+
return;
|
|
35209
|
+
}
|
|
35091
35210
|
}
|
|
35092
35211
|
return;
|
|
35093
35212
|
}
|
|
@@ -35098,6 +35217,16 @@ class SQLIn {
|
|
|
35098
35217
|
sql_source_1.SQLSource.runSyntax(s, input);
|
|
35099
35218
|
}
|
|
35100
35219
|
}
|
|
35220
|
+
// "IN itab" expects a ranges table, ie. the row must have SIGN, OPTION, LOW and HIGH
|
|
35221
|
+
static isRangeRow(rowType) {
|
|
35222
|
+
if (rowType instanceof basic_1.VoidType || rowType instanceof basic_1.UnknownType || rowType instanceof basic_1.AnyType) {
|
|
35223
|
+
return true;
|
|
35224
|
+
}
|
|
35225
|
+
else if (!(rowType instanceof basic_1.StructureType)) {
|
|
35226
|
+
return false;
|
|
35227
|
+
}
|
|
35228
|
+
return RANGE_COMPONENTS.every(c => rowType.getComponentByName(c) !== undefined);
|
|
35229
|
+
}
|
|
35101
35230
|
}
|
|
35102
35231
|
exports.SQLIn = SQLIn;
|
|
35103
35232
|
//# sourceMappingURL=sql_in.js.map
|
|
@@ -39176,7 +39305,7 @@ class CreateObject {
|
|
|
39176
39305
|
this.validateParameters(cdef, node, input);
|
|
39177
39306
|
}
|
|
39178
39307
|
static checkInstantiationAllowed(cdef, input) {
|
|
39179
|
-
var _a, _b
|
|
39308
|
+
var _a, _b;
|
|
39180
39309
|
const createVis = cdef.getCreateVisibility();
|
|
39181
39310
|
if (createVis === visibility_1.Visibility.Public) {
|
|
39182
39311
|
return undefined;
|
|
@@ -39189,34 +39318,17 @@ class CreateObject {
|
|
|
39189
39318
|
if (enclosingClass.toUpperCase() === cdef.getName().toUpperCase()) {
|
|
39190
39319
|
return undefined;
|
|
39191
39320
|
}
|
|
39192
|
-
if (
|
|
39193
|
-
input.scope.isLocalFriend(cdef.getName(), enclosingClass)) {
|
|
39321
|
+
if (new _object_oriented_1.ObjectOriented(input.scope).hasFriendship(cdef, enclosingClass)) {
|
|
39194
39322
|
return undefined;
|
|
39195
39323
|
}
|
|
39196
|
-
const enclosingDefinition = input.scope.findClassDefinition(enclosingClass);
|
|
39197
|
-
if (enclosingDefinition !== undefined) {
|
|
39198
|
-
const implementedInterfaces = new _object_oriented_1.ObjectOriented(input.scope).findInterfaces(enclosingDefinition);
|
|
39199
|
-
if (cdef.getFriends().some(friend => implementedInterfaces.some(implemented => implemented.name.toUpperCase() === friend.toUpperCase()))) {
|
|
39200
|
-
return undefined;
|
|
39201
|
-
}
|
|
39202
|
-
}
|
|
39203
|
-
// subclasses of friends also have friendship
|
|
39204
|
-
let enclosingSup = enclosingDefinition === null || enclosingDefinition === void 0 ? void 0 : enclosingDefinition.getSuperClass();
|
|
39205
|
-
while (enclosingSup !== undefined) {
|
|
39206
|
-
if (cdef.getFriends().some(f => f.toUpperCase() === enclosingSup.toUpperCase()) ||
|
|
39207
|
-
input.scope.isLocalFriend(cdef.getName(), enclosingSup)) {
|
|
39208
|
-
return undefined;
|
|
39209
|
-
}
|
|
39210
|
-
enclosingSup = (_a = input.scope.findClassDefinition(enclosingSup)) === null || _a === void 0 ? void 0 : _a.getSuperClass();
|
|
39211
|
-
}
|
|
39212
39324
|
if (createVis === visibility_1.Visibility.Protected) {
|
|
39213
39325
|
// subclasses are also allowed
|
|
39214
|
-
let sup = (
|
|
39326
|
+
let sup = (_a = input.scope.findClassDefinition(enclosingClass)) === null || _a === void 0 ? void 0 : _a.getSuperClass();
|
|
39215
39327
|
while (sup !== undefined) {
|
|
39216
39328
|
if (sup.toUpperCase() === cdef.getName().toUpperCase()) {
|
|
39217
39329
|
return undefined;
|
|
39218
39330
|
}
|
|
39219
|
-
sup = (
|
|
39331
|
+
sup = (_b = input.scope.findClassDefinition(sup)) === null || _b === void 0 ? void 0 : _b.getSuperClass();
|
|
39220
39332
|
}
|
|
39221
39333
|
}
|
|
39222
39334
|
return cdef.getName() + " cannot be instantiated, class is defined as " +
|
|
@@ -39480,6 +39592,7 @@ const source_1 = __webpack_require__(/*! ../expressions/source */ "../core/build
|
|
|
39480
39592
|
const dynamic_1 = __webpack_require__(/*! ../expressions/dynamic */ "../core/build/src/abap/5_syntax/expressions/dynamic.js");
|
|
39481
39593
|
const database_table_1 = __webpack_require__(/*! ../expressions/database_table */ "../core/build/src/abap/5_syntax/expressions/database_table.js");
|
|
39482
39594
|
const _check_database_fields_1 = __webpack_require__(/*! ../expressions/_check_database_fields */ "../core/build/src/abap/5_syntax/expressions/_check_database_fields.js");
|
|
39595
|
+
const sql_in_1 = __webpack_require__(/*! ../expressions/sql_in */ "../core/build/src/abap/5_syntax/expressions/sql_in.js");
|
|
39483
39596
|
class DeleteDatabase {
|
|
39484
39597
|
runSyntax(node, input) {
|
|
39485
39598
|
for (const s of node.findAllExpressions(Expressions.Source)) {
|
|
@@ -39491,6 +39604,12 @@ class DeleteDatabase {
|
|
|
39491
39604
|
for (const d of node.findAllExpressions(Expressions.Dynamic)) {
|
|
39492
39605
|
dynamic_1.Dynamic.runSyntax(d, input);
|
|
39493
39606
|
}
|
|
39607
|
+
for (const compare of node.findAllExpressions(Expressions.SQLCompare)) {
|
|
39608
|
+
const sqlin = compare.findDirectExpression(Expressions.SQLIn);
|
|
39609
|
+
if (sqlin !== undefined) {
|
|
39610
|
+
sql_in_1.SQLIn.runSyntax(sqlin, input);
|
|
39611
|
+
}
|
|
39612
|
+
}
|
|
39494
39613
|
const dbtab = node.findFirstExpression(Expressions.DatabaseTable);
|
|
39495
39614
|
if (dbtab !== undefined) {
|
|
39496
39615
|
const dbSource = database_table_1.DatabaseTable.runSyntax(dbtab, input);
|
|
@@ -40495,13 +40614,17 @@ const expressions_1 = __webpack_require__(/*! ../../2_statements/expressions */
|
|
|
40495
40614
|
const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "../core/build/src/abap/5_syntax/_syntax_input.js");
|
|
40496
40615
|
class Form {
|
|
40497
40616
|
runSyntax(node, input) {
|
|
40498
|
-
|
|
40499
|
-
const name =
|
|
40500
|
-
if (name === undefined) {
|
|
40617
|
+
const nameExpression = node.findDirectExpression(expressions_1.FormName);
|
|
40618
|
+
const name = nameExpression === null || nameExpression === void 0 ? void 0 : nameExpression.concatTokens();
|
|
40619
|
+
if (nameExpression === undefined || name === undefined) {
|
|
40501
40620
|
const message = "Form, could not find name";
|
|
40502
40621
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
40503
40622
|
return;
|
|
40504
40623
|
}
|
|
40624
|
+
if (name.length > 30) {
|
|
40625
|
+
const message = "FORM name longer than 30 characters";
|
|
40626
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, nameExpression.getFirstToken(), message));
|
|
40627
|
+
}
|
|
40505
40628
|
input.scope.push(_scope_type_1.ScopeType.Form, name, node.getFirstToken().getStart(), input.filename);
|
|
40506
40629
|
const form = new form_definition_1.FormDefinition(node, input);
|
|
40507
40630
|
input.scope.addList(form.getUsingParameters());
|
|
@@ -40561,7 +40684,7 @@ const Expressions = __importStar(__webpack_require__(/*! ../../2_statements/expr
|
|
|
40561
40684
|
const source_1 = __webpack_require__(/*! ../expressions/source */ "../core/build/src/abap/5_syntax/expressions/source.js");
|
|
40562
40685
|
class Format {
|
|
40563
40686
|
runSyntax(node, input) {
|
|
40564
|
-
for (const s of node.
|
|
40687
|
+
for (const s of node.findAllExpressionsMulti([Expressions.Source, Expressions.SimpleSource3])) {
|
|
40565
40688
|
source_1.Source.runSyntax(s, input);
|
|
40566
40689
|
}
|
|
40567
40690
|
}
|
|
@@ -43386,6 +43509,11 @@ class Parameter {
|
|
|
43386
43509
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
43387
43510
|
return;
|
|
43388
43511
|
}
|
|
43512
|
+
if (this.hasUserCommand(node) && this.hasLength(node)) {
|
|
43513
|
+
const message = "USER-COMMAND and LENGTH not possible together";
|
|
43514
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
43515
|
+
return;
|
|
43516
|
+
}
|
|
43389
43517
|
const bfound = new basic_types_1.BasicTypes(input).parseType(node);
|
|
43390
43518
|
if (bfound) {
|
|
43391
43519
|
input.scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(nameToken, input.filename, bfound));
|
|
@@ -43397,6 +43525,30 @@ class Parameter {
|
|
|
43397
43525
|
const magicToken = new tokens_1.Identifier(nameToken.getStart(), magicName);
|
|
43398
43526
|
input.scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(magicToken, input.filename, basic_1.VoidType.get("PARAMETER-MAGIC")));
|
|
43399
43527
|
}
|
|
43528
|
+
// "USER-COMMAND" is lexed as three tokens
|
|
43529
|
+
hasUserCommand(node) {
|
|
43530
|
+
const tokens = node.getTokens();
|
|
43531
|
+
for (let i = 0; i < tokens.length - 2; i++) {
|
|
43532
|
+
if (tokens[i].getStr().toUpperCase() === "USER"
|
|
43533
|
+
&& tokens[i + 1].getStr() === "-"
|
|
43534
|
+
&& tokens[i + 2].getStr().toUpperCase() === "COMMAND") {
|
|
43535
|
+
return true;
|
|
43536
|
+
}
|
|
43537
|
+
}
|
|
43538
|
+
return false;
|
|
43539
|
+
}
|
|
43540
|
+
// "VISIBLE LENGTH" is not the same as "LENGTH"
|
|
43541
|
+
hasLength(node) {
|
|
43542
|
+
var _a;
|
|
43543
|
+
const tokens = node.getTokens();
|
|
43544
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
43545
|
+
if (tokens[i].getStr().toUpperCase() === "LENGTH"
|
|
43546
|
+
&& ((_a = tokens[i - 1]) === null || _a === void 0 ? void 0 : _a.getStr().toUpperCase()) !== "VISIBLE") {
|
|
43547
|
+
return true;
|
|
43548
|
+
}
|
|
43549
|
+
}
|
|
43550
|
+
return false;
|
|
43551
|
+
}
|
|
43400
43552
|
}
|
|
43401
43553
|
exports.Parameter = Parameter;
|
|
43402
43554
|
//# sourceMappingURL=parameter.js.map
|
|
@@ -69851,7 +70003,7 @@ class Registry {
|
|
|
69851
70003
|
}
|
|
69852
70004
|
static abaplintVersion() {
|
|
69853
70005
|
// magic, see build script "version.js"
|
|
69854
|
-
return "2.120.
|
|
70006
|
+
return "2.120.30";
|
|
69855
70007
|
}
|
|
69856
70008
|
getDDICReferences() {
|
|
69857
70009
|
return this.ddicReferences;
|
|
@@ -72538,6 +72690,11 @@ class CDSCheckSyntaxConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
|
72538
72690
|
exports.CDSCheckSyntaxConf = CDSCheckSyntaxConf;
|
|
72539
72691
|
const KNOWN_QUAN_DATA_ELEMENTS = ["MENGE_D"];
|
|
72540
72692
|
const KNOWN_CURR_DATA_ELEMENTS = ["BWERT", "DZWERT"];
|
|
72693
|
+
// Reserved names, cannot be used as element names, see DDIC table TRESE
|
|
72694
|
+
const RESERVED_ELEMENT_NAMES = ["BEGIN", "NUMBER", "POSITION"];
|
|
72695
|
+
const MAX_LABEL_LENGTH = 40;
|
|
72696
|
+
// Annotations which are not supported in CDS view entities
|
|
72697
|
+
const VIEW_ENTITY_FORBIDDEN_ANNOTATIONS = ["Semantics.unitOfMeasure"];
|
|
72541
72698
|
class CDSCheckSyntax {
|
|
72542
72699
|
constructor() {
|
|
72543
72700
|
this.conf = new CDSCheckSyntaxConf();
|
|
@@ -72579,6 +72736,9 @@ Missing objects are only reported when their names match the configured errorNam
|
|
|
72579
72736
|
this.checkTypes(tree, ddic, issues, file);
|
|
72580
72737
|
this.checkRootProjection(tree, ddic, issues, file);
|
|
72581
72738
|
this.checkFieldAnnotations(tree, ddic, issues, file);
|
|
72739
|
+
this.checkLabels(tree, issues, file);
|
|
72740
|
+
this.checkViewEntityAnnotations(tree, issues, file);
|
|
72741
|
+
this.checkReservedNames(tree, issues, file);
|
|
72582
72742
|
this.checkFields(tree, sources, object, issues, file);
|
|
72583
72743
|
return issues;
|
|
72584
72744
|
}
|
|
@@ -72763,6 +72923,62 @@ Missing objects are only reported when their names match the configured errorNam
|
|
|
72763
72923
|
|| a.toUpperCase().includes("@SEMANTICS:{CURRENCYCODE:TRUE"));
|
|
72764
72924
|
}
|
|
72765
72925
|
}
|
|
72926
|
+
checkLabels(tree, issues, file) {
|
|
72927
|
+
for (const annotation of tree.findAllExpressionsRecursive(expressions_1.CDSAnnotation)) {
|
|
72928
|
+
const concatenated = annotation.concatTokens();
|
|
72929
|
+
if (/@\s*<?\s*EndUserText/i.test(concatenated) === false) {
|
|
72930
|
+
continue;
|
|
72931
|
+
}
|
|
72932
|
+
const expression = /label\s*:\s*'((?:[^']|'')*)'/gi;
|
|
72933
|
+
let match = expression.exec(concatenated);
|
|
72934
|
+
while (match !== null) {
|
|
72935
|
+
const label = match[1].replace(/''/g, "'");
|
|
72936
|
+
if (label.length > MAX_LABEL_LENGTH) {
|
|
72937
|
+
const message = `CDS label is ${label.length} characters, maximum is ${MAX_LABEL_LENGTH}`;
|
|
72938
|
+
issues.push(issue_1.Issue.atToken(file, annotation.getFirstToken(), message, this.getMetadata().key, this.conf.severity));
|
|
72939
|
+
}
|
|
72940
|
+
match = expression.exec(concatenated);
|
|
72941
|
+
}
|
|
72942
|
+
}
|
|
72943
|
+
}
|
|
72944
|
+
checkViewEntityAnnotations(tree, issues, file) {
|
|
72945
|
+
const view = tree.findFirstExpression(expressions_1.CDSDefineView);
|
|
72946
|
+
if (view === undefined || view.findDirectTokenByText("ENTITY") === undefined) {
|
|
72947
|
+
return;
|
|
72948
|
+
}
|
|
72949
|
+
for (const annotation of tree.findAllExpressionsRecursive(expressions_1.CDSAnnotation)) {
|
|
72950
|
+
const normalized = annotation.concatTokens().replace(/\s/g, "").toUpperCase().replace(/^@</, "@");
|
|
72951
|
+
for (const forbidden of VIEW_ENTITY_FORBIDDEN_ANNOTATIONS) {
|
|
72952
|
+
const upper = forbidden.toUpperCase();
|
|
72953
|
+
if (normalized.startsWith("@" + upper) === false
|
|
72954
|
+
&& normalized.startsWith("@" + upper.replace(".", ":{")) === false) {
|
|
72955
|
+
continue;
|
|
72956
|
+
}
|
|
72957
|
+
const message = `Annotation ${forbidden} is not allowed in view entities`;
|
|
72958
|
+
issues.push(issue_1.Issue.atToken(file, annotation.getFirstToken(), message, this.getMetadata().key, this.conf.severity));
|
|
72959
|
+
}
|
|
72960
|
+
}
|
|
72961
|
+
}
|
|
72962
|
+
checkReservedNames(tree, issues, file) {
|
|
72963
|
+
var _a, _b;
|
|
72964
|
+
for (const element of tree.findAllExpressionsRecursive(expressions_1.CDSElement)) {
|
|
72965
|
+
if (element.findDirectTokenByText("INCLUDE") !== undefined) {
|
|
72966
|
+
continue;
|
|
72967
|
+
}
|
|
72968
|
+
let nameNode = (_a = element.findDirectExpression(expressions_1.CDSAs)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(expressions_1.CDSName);
|
|
72969
|
+
if (nameNode === undefined) {
|
|
72970
|
+
const names = ((_b = element.findDirectExpression(expressions_1.CDSPrefixedName)) === null || _b === void 0 ? void 0 : _b.findDirectExpressions(expressions_1.CDSName)) || [];
|
|
72971
|
+
nameNode = names[names.length - 1];
|
|
72972
|
+
}
|
|
72973
|
+
if (nameNode === undefined) {
|
|
72974
|
+
continue;
|
|
72975
|
+
}
|
|
72976
|
+
const name = this.name(nameNode);
|
|
72977
|
+
if (RESERVED_ELEMENT_NAMES.includes(name.toUpperCase())) {
|
|
72978
|
+
issues.push(issue_1.Issue.atToken(file, nameNode.getFirstToken(), `CDS element name "${name}" is reserved`, this.getMetadata().key, this.conf.severity));
|
|
72979
|
+
}
|
|
72980
|
+
}
|
|
72981
|
+
}
|
|
72766
72982
|
checkFields(tree, sources, object, issues, file) {
|
|
72767
72983
|
var _a;
|
|
72768
72984
|
const associationNames = new Set();
|
|
@@ -75226,6 +75442,7 @@ class CloudTypes {
|
|
|
75226
75442
|
|| obj instanceof Objects.BehaviorDefinition
|
|
75227
75443
|
|| obj instanceof Objects.BusinessCatalog
|
|
75228
75444
|
|| obj instanceof Objects.BusinessCatalogAppAssignment
|
|
75445
|
+
|| obj instanceof Objects.BusinessConfigurationMaintenanceObject
|
|
75229
75446
|
|| obj instanceof Objects.CDSMetadataExtension
|
|
75230
75447
|
|| obj instanceof Objects.Class
|
|
75231
75448
|
|| obj instanceof Objects.CDSType
|
|
@@ -75242,11 +75459,13 @@ class CloudTypes {
|
|
|
75242
75459
|
|| obj instanceof Objects.EventBinding
|
|
75243
75460
|
|| obj instanceof Objects.EventConsumer
|
|
75244
75461
|
|| obj instanceof Objects.FunctionGroup
|
|
75462
|
+
|| obj instanceof Objects.GatewayODataGroupAndAssignment
|
|
75245
75463
|
|| obj instanceof Objects.HttpService
|
|
75246
75464
|
|| obj instanceof Objects.IAMApp
|
|
75247
75465
|
|| obj instanceof Objects.InboundService
|
|
75248
75466
|
|| obj instanceof Objects.Interface
|
|
75249
75467
|
|| obj instanceof Objects.LockObject
|
|
75468
|
+
|| obj instanceof Objects.MaintenanceAndTransportObject
|
|
75250
75469
|
|| obj instanceof Objects.MessageClass
|
|
75251
75470
|
|| obj instanceof Objects.NumberRange
|
|
75252
75471
|
|| obj instanceof Objects.OutboundService
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/cli",
|
|
3
|
-
"version": "2.120.
|
|
3
|
+
"version": "2.120.30",
|
|
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.30",
|
|
43
43
|
"@types/chai": "^4.3.20",
|
|
44
44
|
"@types/minimist": "^1.2.5",
|
|
45
45
|
"@types/mocha": "^10.0.10",
|