@abaplint/transpiler-cli 2.13.60 → 2.13.61
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 +717 -53
- package/package.json +2 -2
package/build/bundle.js
CHANGED
|
@@ -4229,10 +4229,10 @@ exports.ClassName = ClassName;
|
|
|
4229
4229
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
4230
4230
|
exports.Color = void 0;
|
|
4231
4231
|
const combi_1 = __webpack_require__(/*! ../combi */ "./node_modules/@abaplint/core/build/src/abap/2_statements/combi.js");
|
|
4232
|
-
const
|
|
4232
|
+
const simple_source3_1 = __webpack_require__(/*! ./simple_source3 */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/simple_source3.js");
|
|
4233
4233
|
class Color extends combi_1.Expression {
|
|
4234
4234
|
getRunnable() {
|
|
4235
|
-
const eq = (0, combi_1.seq)("=",
|
|
4235
|
+
const eq = (0, combi_1.seq)("=", simple_source3_1.SimpleSource3);
|
|
4236
4236
|
const integers = (0, combi_1.altPrio)("1", "2", "3", "4", "5", "6", "7");
|
|
4237
4237
|
const texts = (0, combi_1.altPrio)("COL_BACKGROUND", "COL_HEADING", "COL_NORMAL", "COL_TOTAL", "COL_KEY", "COL_POSITIVE", "COL_NEGATIVE", "COL_GROUP");
|
|
4238
4238
|
const value = (0, combi_1.alt)(eq, (0, combi_1.altPrio)("ON", "OFF", "COLOR OFF", (0, combi_1.altPrio)(integers, texts)));
|
|
@@ -27124,6 +27124,31 @@ class ObjectOriented {
|
|
|
27124
27124
|
}
|
|
27125
27125
|
return ret;
|
|
27126
27126
|
}
|
|
27127
|
+
// does the supplied class have friendship with "friendName"?
|
|
27128
|
+
// note that interfaces of the friend, and subclasses of the friend also have friendship
|
|
27129
|
+
hasFriendship(cd, friendName) {
|
|
27130
|
+
var _a;
|
|
27131
|
+
const friends = cd.getFriends().map(f => f.toUpperCase());
|
|
27132
|
+
const isFriend = (name) => friends.includes(name.toUpperCase()) || this.scope.isLocalFriend(cd.getName(), name);
|
|
27133
|
+
if (isFriend(friendName)) {
|
|
27134
|
+
return true;
|
|
27135
|
+
}
|
|
27136
|
+
const friendDefinition = this.scope.findClassDefinition(friendName);
|
|
27137
|
+
if (friendDefinition === undefined) {
|
|
27138
|
+
return false;
|
|
27139
|
+
}
|
|
27140
|
+
if (this.findInterfaces(friendDefinition).some(i => friends.includes(i.name.toUpperCase()))) {
|
|
27141
|
+
return true;
|
|
27142
|
+
}
|
|
27143
|
+
let sup = friendDefinition.getSuperClass();
|
|
27144
|
+
while (sup !== undefined) {
|
|
27145
|
+
if (isFriend(sup)) {
|
|
27146
|
+
return true;
|
|
27147
|
+
}
|
|
27148
|
+
sup = (_a = this.scope.findClassDefinition(sup)) === null || _a === void 0 ? void 0 : _a.getSuperClass();
|
|
27149
|
+
}
|
|
27150
|
+
return false;
|
|
27151
|
+
}
|
|
27127
27152
|
searchEvent(def, name) {
|
|
27128
27153
|
if (def === undefined || name === undefined) {
|
|
27129
27154
|
return undefined;
|
|
@@ -27132,6 +27157,11 @@ class ObjectOriented {
|
|
|
27132
27157
|
if (found) {
|
|
27133
27158
|
return found;
|
|
27134
27159
|
}
|
|
27160
|
+
if (name.includes("~")) {
|
|
27161
|
+
// event of an implemented interface, ie. "if_name~event_name"
|
|
27162
|
+
const [interfaceName, eventName] = name.split("~");
|
|
27163
|
+
return this.searchEvent(this.scope.findInterfaceDefinition(interfaceName), eventName);
|
|
27164
|
+
}
|
|
27135
27165
|
for (const a of def.getAliases() || []) {
|
|
27136
27166
|
if (a.getName().toUpperCase() === name.toUpperCase()) {
|
|
27137
27167
|
const comp = a.getComponent();
|
|
@@ -28123,7 +28153,10 @@ class TypeUtils {
|
|
|
28123
28153
|
|| source instanceof basic_1.DataType
|
|
28124
28154
|
|| source instanceof basic_1.UnknownType;
|
|
28125
28155
|
}
|
|
28126
|
-
if (source instanceof basic_1.
|
|
28156
|
+
if (source instanceof cgeneric_type_1.CGenericType && target instanceof basic_1.StringType) {
|
|
28157
|
+
return false;
|
|
28158
|
+
}
|
|
28159
|
+
else if (source instanceof basic_1.CharacterType) {
|
|
28127
28160
|
if (target instanceof basic_1.CharacterType) {
|
|
28128
28161
|
if (((_b = source.getAbstractTypeData()) === null || _b === void 0 ? void 0 : _b.derivedFromConstant) === true) {
|
|
28129
28162
|
return source.getLength() <= target.getLength();
|
|
@@ -28166,6 +28199,11 @@ class TypeUtils {
|
|
|
28166
28199
|
return false;
|
|
28167
28200
|
}
|
|
28168
28201
|
}
|
|
28202
|
+
else if (source instanceof basic_1.DateType || source instanceof basic_1.TimeType) {
|
|
28203
|
+
if (target instanceof basic_1.CharacterType || target instanceof basic_1.StringType) {
|
|
28204
|
+
return false;
|
|
28205
|
+
}
|
|
28206
|
+
}
|
|
28169
28207
|
else if (source instanceof basic_1.StringType) {
|
|
28170
28208
|
if (target instanceof basic_1.StructureType && this.structureContainsString(target)) {
|
|
28171
28209
|
return false;
|
|
@@ -28192,6 +28230,11 @@ class TypeUtils {
|
|
|
28192
28230
|
}
|
|
28193
28231
|
return false;
|
|
28194
28232
|
}
|
|
28233
|
+
else if (target instanceof basic_1.TableType
|
|
28234
|
+
|| target instanceof basic_1.DataReference
|
|
28235
|
+
|| target instanceof basic_1.ObjectReferenceType) {
|
|
28236
|
+
return false;
|
|
28237
|
+
}
|
|
28195
28238
|
return true;
|
|
28196
28239
|
}
|
|
28197
28240
|
else if (source instanceof basic_1.StructureType) {
|
|
@@ -28216,7 +28259,8 @@ class TypeUtils {
|
|
|
28216
28259
|
}
|
|
28217
28260
|
else if (target instanceof basic_1.VoidType
|
|
28218
28261
|
|| target instanceof basic_1.AnyType
|
|
28219
|
-
|| target instanceof basic_1.DataType
|
|
28262
|
+
|| target instanceof basic_1.DataType
|
|
28263
|
+
|| target instanceof basic_1.UnknownType) {
|
|
28220
28264
|
return true;
|
|
28221
28265
|
}
|
|
28222
28266
|
return false;
|
|
@@ -28227,7 +28271,9 @@ class TypeUtils {
|
|
|
28227
28271
|
}
|
|
28228
28272
|
}
|
|
28229
28273
|
else if (source instanceof basic_1.IntegerType) {
|
|
28230
|
-
if (target instanceof basic_1.StringType
|
|
28274
|
+
if (target instanceof basic_1.StringType
|
|
28275
|
+
|| target instanceof basic_1.DateType
|
|
28276
|
+
|| target instanceof basic_1.CharacterType) {
|
|
28231
28277
|
return false;
|
|
28232
28278
|
}
|
|
28233
28279
|
else if (target instanceof basic_1.Integer8Type || target instanceof basic_1.PackedType) {
|
|
@@ -28305,6 +28351,29 @@ class TypeUtils {
|
|
|
28305
28351
|
}
|
|
28306
28352
|
return this.isAssignable(source, target);
|
|
28307
28353
|
}
|
|
28354
|
+
// Typing with the classic STRUCTURE addition, ie. "FORM foo USING bar STRUCTURE zkey",
|
|
28355
|
+
// is not a compatibility check: ABAP only checks the fragment view up to the end of the
|
|
28356
|
+
// formal structure, so the actual parameter is allowed to be longer. For TABLES parameters
|
|
28357
|
+
// the table key is not part of the check at all.
|
|
28358
|
+
isAssignableStructureTyping(source, target, node) {
|
|
28359
|
+
if (source instanceof basic_1.StructureType && target instanceof basic_1.StructureType) {
|
|
28360
|
+
const sourceComponents = source.getComponents();
|
|
28361
|
+
const targetComponents = target.getComponents();
|
|
28362
|
+
if (sourceComponents.length < targetComponents.length) {
|
|
28363
|
+
return false;
|
|
28364
|
+
}
|
|
28365
|
+
for (let i = 0; i < targetComponents.length; i++) {
|
|
28366
|
+
if (this.isAssignableStrict(sourceComponents[i].type, targetComponents[i].type) === false) {
|
|
28367
|
+
return false;
|
|
28368
|
+
}
|
|
28369
|
+
}
|
|
28370
|
+
return true;
|
|
28371
|
+
}
|
|
28372
|
+
else if (source instanceof basic_1.TableType && target instanceof basic_1.TableType) {
|
|
28373
|
+
return this.isAssignableStructureTyping(source.getRowType(), target.getRowType());
|
|
28374
|
+
}
|
|
28375
|
+
return this.isAssignableStrict(source, target, node);
|
|
28376
|
+
}
|
|
28308
28377
|
isAssignable(source, target) {
|
|
28309
28378
|
if (source === undefined || target === undefined) {
|
|
28310
28379
|
return true;
|
|
@@ -28313,6 +28382,9 @@ class TypeUtils {
|
|
|
28313
28382
|
console.dir(source);
|
|
28314
28383
|
console.dir(target);
|
|
28315
28384
|
*/
|
|
28385
|
+
if (source instanceof basic_1.UTCLongType || target instanceof basic_1.UTCLongType) {
|
|
28386
|
+
return this.isUTCLongAssignable(source, target);
|
|
28387
|
+
}
|
|
28316
28388
|
if (target instanceof basic_1.TableType) {
|
|
28317
28389
|
if (target.isWithHeader()) {
|
|
28318
28390
|
return this.isAssignable(source, target.getRowType());
|
|
@@ -28464,6 +28536,33 @@ class TypeUtils {
|
|
|
28464
28536
|
}
|
|
28465
28537
|
return true;
|
|
28466
28538
|
}
|
|
28539
|
+
// utclong can only be converted to and from character like types
|
|
28540
|
+
isUTCLongAssignable(source, target) {
|
|
28541
|
+
if (this.isGenericOrVoid(source) || this.isGenericOrVoid(target)) {
|
|
28542
|
+
return true;
|
|
28543
|
+
}
|
|
28544
|
+
else if (source instanceof basic_1.UTCLongType && target instanceof basic_1.UTCLongType) {
|
|
28545
|
+
return true;
|
|
28546
|
+
}
|
|
28547
|
+
else if (source instanceof basic_1.UTCLongType) {
|
|
28548
|
+
return this.isTextLike(target);
|
|
28549
|
+
}
|
|
28550
|
+
return this.isTextLike(source);
|
|
28551
|
+
}
|
|
28552
|
+
isGenericOrVoid(type) {
|
|
28553
|
+
return type instanceof basic_1.VoidType
|
|
28554
|
+
|| type instanceof basic_1.AnyType
|
|
28555
|
+
|| type instanceof basic_1.DataType
|
|
28556
|
+
|| type instanceof basic_1.UnknownType;
|
|
28557
|
+
}
|
|
28558
|
+
isTextLike(type) {
|
|
28559
|
+
return type instanceof basic_1.CharacterType
|
|
28560
|
+
|| type instanceof basic_1.StringType
|
|
28561
|
+
|| type instanceof basic_1.CLikeType
|
|
28562
|
+
|| type instanceof basic_1.CSequenceType
|
|
28563
|
+
|| type instanceof cgeneric_type_1.CGenericType
|
|
28564
|
+
|| type instanceof basic_1.SimpleType;
|
|
28565
|
+
}
|
|
28467
28566
|
}
|
|
28468
28567
|
exports.TypeUtils = TypeUtils;
|
|
28469
28568
|
//# sourceMappingURL=_type_utils.js.map
|
|
@@ -28546,6 +28645,7 @@ const types_1 = __webpack_require__(/*! ../types */ "./node_modules/@abaplint/co
|
|
|
28546
28645
|
const expressions_1 = __webpack_require__(/*! ../2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js");
|
|
28547
28646
|
const _builtin_1 = __webpack_require__(/*! ./_builtin */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_builtin.js");
|
|
28548
28647
|
const position_1 = __webpack_require__(/*! ../../position */ "./node_modules/@abaplint/core/build/src/position.js");
|
|
28648
|
+
const _syntax_input_1 = __webpack_require__(/*! ./_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
|
|
28549
28649
|
class BasicTypes {
|
|
28550
28650
|
constructor(input) {
|
|
28551
28651
|
this.input = input;
|
|
@@ -29028,7 +29128,7 @@ class BasicTypes {
|
|
|
29028
29128
|
return Types.VoidType.get((_f = node.findFirstExpression(Expressions.TypeStructure)) === null || _f === void 0 ? void 0 : _f.concatTokens());
|
|
29029
29129
|
}
|
|
29030
29130
|
else if (text.startsWith("LIKE LINE OF ")) {
|
|
29031
|
-
|
|
29131
|
+
let name = (_g = node.findFirstExpression(Expressions.FieldChain)) === null || _g === void 0 ? void 0 : _g.concatTokens();
|
|
29032
29132
|
let e = node.findFirstExpression(Expressions.Type);
|
|
29033
29133
|
if (e === undefined) {
|
|
29034
29134
|
e = node.findFirstExpression(Expressions.FormParamType);
|
|
@@ -29036,19 +29136,32 @@ class BasicTypes {
|
|
|
29036
29136
|
if (e === undefined) {
|
|
29037
29137
|
e = node.findFirstExpression(Expressions.FieldChain);
|
|
29038
29138
|
}
|
|
29139
|
+
if (e === undefined) {
|
|
29140
|
+
// old style, eg "LIKE LINE OF tab OCCURS 0 WITH HEADER LINE", it is parsed as TypeName
|
|
29141
|
+
e = typeName;
|
|
29142
|
+
name = typeName === null || typeName === void 0 ? void 0 : typeName.concatTokens();
|
|
29143
|
+
}
|
|
29039
29144
|
const type = this.resolveLikeName(e, false);
|
|
29145
|
+
let row = undefined;
|
|
29040
29146
|
if (type === undefined) {
|
|
29041
29147
|
return new Types.UnknownType("Type error, could not resolve \"" + name + "\", parseType");
|
|
29042
29148
|
}
|
|
29043
29149
|
else if (type instanceof Types.TableType) {
|
|
29044
|
-
|
|
29150
|
+
row = type.getRowType();
|
|
29045
29151
|
}
|
|
29046
29152
|
else if (type instanceof Types.VoidType) {
|
|
29047
|
-
|
|
29153
|
+
row = type;
|
|
29048
29154
|
}
|
|
29049
29155
|
else {
|
|
29050
29156
|
return new Types.UnknownType("Type error, not a table type " + name);
|
|
29051
29157
|
}
|
|
29158
|
+
if (this.isOccurs(node)) {
|
|
29159
|
+
return new Types.TableType(row, {
|
|
29160
|
+
withHeader: text.includes(" WITH HEADER LINE"),
|
|
29161
|
+
keyType: Types.TableKeyType.default
|
|
29162
|
+
}, qualifiedName);
|
|
29163
|
+
}
|
|
29164
|
+
return row;
|
|
29052
29165
|
}
|
|
29053
29166
|
else if (text.startsWith("LIKE REF TO ")) {
|
|
29054
29167
|
const name = (_h = node.findFirstExpression(Expressions.FieldChain)) === null || _h === void 0 ? void 0 : _h.concatTokens();
|
|
@@ -29486,6 +29599,13 @@ class BasicTypes {
|
|
|
29486
29599
|
}
|
|
29487
29600
|
const chain = val.findFirstExpression(Expressions.SimpleFieldChain);
|
|
29488
29601
|
if (chain) {
|
|
29602
|
+
// todo, hardcoded for now, should be a generic check that the chain is a constant
|
|
29603
|
+
const concat = chain.concatTokens().toUpperCase();
|
|
29604
|
+
if (concat === "SY-DATUM" || concat === "SY-UZEIT") {
|
|
29605
|
+
const message = "VALUE, " + concat.toLowerCase() + " is not a constant";
|
|
29606
|
+
this.input.issues.push((0, _syntax_input_1.syntaxIssue)(this.input, chain.getFirstToken(), message));
|
|
29607
|
+
return undefined;
|
|
29608
|
+
}
|
|
29489
29609
|
return this.resolveConstantValue(chain);
|
|
29490
29610
|
}
|
|
29491
29611
|
throw new Error("findValue, unexpected");
|
|
@@ -31856,18 +31976,27 @@ class FormParam {
|
|
|
31856
31976
|
else {
|
|
31857
31977
|
type = new basic_1.UnknownType("todo, FORM STRUCTURES typing");
|
|
31858
31978
|
}
|
|
31859
|
-
return new _typed_identifier_1.TypedIdentifier(nameToken, input.filename, type, ["form_parameter" /* IdentifierMeta.FormParameter */]);
|
|
31979
|
+
return new _typed_identifier_1.TypedIdentifier(nameToken, input.filename, type, ["form_parameter" /* IdentifierMeta.FormParameter */, "form_parameter_structure" /* IdentifierMeta.FormParameterStructure */]);
|
|
31860
31980
|
}
|
|
31861
31981
|
if (node.getChildren().length === 1 && nameToken) {
|
|
31862
31982
|
// untyped FORM parameter
|
|
31863
31983
|
return new _typed_identifier_1.TypedIdentifier(nameToken, input.filename, basic_1.AnyType.get(), ["form_parameter" /* IdentifierMeta.FormParameter */]);
|
|
31864
31984
|
}
|
|
31865
31985
|
let bfound = new basic_types_1.BasicTypes(input).parseType(node);
|
|
31866
|
-
const
|
|
31986
|
+
const typeName = (_c = node.findFirstExpression(expressions_1.TypeName)) === null || _c === void 0 ? void 0 : _c.concatTokens().toUpperCase();
|
|
31867
31987
|
const hasExplicitLength = node.findFirstExpression(expressions_1.Length) !== undefined
|
|
31868
31988
|
|| node.findFirstExpression(expressions_1.ConstantFieldLength) !== undefined;
|
|
31869
|
-
|
|
31870
|
-
|
|
31989
|
+
// the length cannot be specified for FORM parameters, so these types are generic
|
|
31990
|
+
if (hasExplicitLength === false) {
|
|
31991
|
+
if (typeName === "C" && bfound instanceof basic_1.CharacterType) {
|
|
31992
|
+
bfound = basic_1.CGenericType.get();
|
|
31993
|
+
}
|
|
31994
|
+
else if (typeName === "X" && bfound instanceof basic_1.HexType) {
|
|
31995
|
+
bfound = basic_1.XGenericType.get();
|
|
31996
|
+
}
|
|
31997
|
+
else if (typeName === "P" && bfound instanceof basic_1.PackedType) {
|
|
31998
|
+
bfound = basic_1.PGenericType.get();
|
|
31999
|
+
}
|
|
31871
32000
|
}
|
|
31872
32001
|
if (nameToken && bfound) {
|
|
31873
32002
|
return new _typed_identifier_1.TypedIdentifier(nameToken, input.filename, bfound, ["form_parameter" /* IdentifierMeta.FormParameter */]);
|
|
@@ -32759,6 +32888,8 @@ const _reference_1 = __webpack_require__(/*! ../_reference */ "./node_modules/@a
|
|
|
32759
32888
|
const component_name_1 = __webpack_require__(/*! ./component_name */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/component_name.js");
|
|
32760
32889
|
const attribute_name_1 = __webpack_require__(/*! ./attribute_name */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/attribute_name.js");
|
|
32761
32890
|
const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
|
|
32891
|
+
const visibility_1 = __webpack_require__(/*! ../../4_file_information/visibility */ "./node_modules/@abaplint/core/build/src/abap/4_file_information/visibility.js");
|
|
32892
|
+
const class_definition_1 = __webpack_require__(/*! ../../types/class_definition */ "./node_modules/@abaplint/core/build/src/abap/types/class_definition.js");
|
|
32762
32893
|
class MethodCallChain {
|
|
32763
32894
|
static runSyntax(node, input, targetType) {
|
|
32764
32895
|
var _a, _b;
|
|
@@ -32807,6 +32938,12 @@ class MethodCallChain {
|
|
|
32807
32938
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, methodToken, message));
|
|
32808
32939
|
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
32809
32940
|
}
|
|
32941
|
+
const notVisible = method ? this.checkVisibility(method, def, foundDef, input) : undefined;
|
|
32942
|
+
if (notVisible !== undefined) {
|
|
32943
|
+
const message = `Method "${methodName}" is ${notVisible} and cannot be accessed`;
|
|
32944
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, methodToken, message));
|
|
32945
|
+
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
32946
|
+
}
|
|
32810
32947
|
const voidedName = context instanceof basic_1.VoidType ? context.getVoided() : undefined;
|
|
32811
32948
|
const extra = helper.methodReferenceExtras(foundDef, className || voidedName);
|
|
32812
32949
|
input.scope.addReference(methodToken, method, _reference_1.ReferenceType.MethodReference, input.filename, extra);
|
|
@@ -32849,6 +32986,47 @@ class MethodCallChain {
|
|
|
32849
32986
|
return context;
|
|
32850
32987
|
}
|
|
32851
32988
|
//////////////////////////////////////
|
|
32989
|
+
// returns the visibility as text if the method cannot be accessed from the current scope
|
|
32990
|
+
static checkVisibility(method, def, foundDef, input) {
|
|
32991
|
+
var _a, _b, _c;
|
|
32992
|
+
const visibility = method.getVisibility();
|
|
32993
|
+
if (visibility === visibility_1.Visibility.Public || foundDef === undefined) {
|
|
32994
|
+
return undefined;
|
|
32995
|
+
}
|
|
32996
|
+
else if (!(foundDef instanceof class_definition_1.ClassDefinition)) {
|
|
32997
|
+
// interface members are always public
|
|
32998
|
+
return undefined;
|
|
32999
|
+
}
|
|
33000
|
+
const name = foundDef.getName().toUpperCase();
|
|
33001
|
+
const enclosing = (_a = input.scope.getEnclosingClassName()) === null || _a === void 0 ? void 0 : _a.toUpperCase();
|
|
33002
|
+
if (enclosing === undefined || enclosing === name) {
|
|
33003
|
+
return undefined;
|
|
33004
|
+
}
|
|
33005
|
+
// friendship with the class used at the call site also gives access to inherited members
|
|
33006
|
+
const helper = new _object_oriented_1.ObjectOriented(input.scope);
|
|
33007
|
+
const visited = [];
|
|
33008
|
+
let current = def instanceof class_definition_1.ClassDefinition ? def : foundDef;
|
|
33009
|
+
while (current !== undefined && visited.includes(current.getName().toUpperCase()) === false) {
|
|
33010
|
+
visited.push(current.getName().toUpperCase());
|
|
33011
|
+
if (helper.hasFriendship(current, enclosing)) {
|
|
33012
|
+
return undefined;
|
|
33013
|
+
}
|
|
33014
|
+
const sup = current.getSuperClass();
|
|
33015
|
+
current = sup === undefined ? undefined : input.scope.findClassDefinition(sup);
|
|
33016
|
+
}
|
|
33017
|
+
if (visibility === visibility_1.Visibility.Protected) {
|
|
33018
|
+
// subclasses can access protected members
|
|
33019
|
+
let sup = (_b = input.scope.findClassDefinition(enclosing)) === null || _b === void 0 ? void 0 : _b.getSuperClass();
|
|
33020
|
+
while (sup !== undefined) {
|
|
33021
|
+
if (sup.toUpperCase() === name) {
|
|
33022
|
+
return undefined;
|
|
33023
|
+
}
|
|
33024
|
+
sup = (_c = input.scope.findClassDefinition(sup)) === null || _c === void 0 ? void 0 : _c.getSuperClass();
|
|
33025
|
+
}
|
|
33026
|
+
return "protected";
|
|
33027
|
+
}
|
|
33028
|
+
return "private";
|
|
33029
|
+
}
|
|
32852
33030
|
static findTop(first, input, targetType) {
|
|
32853
33031
|
var _a;
|
|
32854
33032
|
if (first.get() instanceof Expressions.ClassName) {
|
|
@@ -35517,6 +35695,7 @@ const basic_1 = __webpack_require__(/*! ../../types/basic */ "./node_modules/@ab
|
|
|
35517
35695
|
const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
|
|
35518
35696
|
const sql_set_op_group_1 = __webpack_require__(/*! ./sql_set_op_group */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/sql_set_op_group.js");
|
|
35519
35697
|
const sql_source_1 = __webpack_require__(/*! ./sql_source */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/sql_source.js");
|
|
35698
|
+
const RANGE_COMPONENTS = ["SIGN", "OPTION", "LOW", "HIGH"];
|
|
35520
35699
|
class SQLIn {
|
|
35521
35700
|
static runSyntax(node, input) {
|
|
35522
35701
|
const setop = node.findDirectExpression(Expressions.SQLSetOpGroup);
|
|
@@ -35536,6 +35715,12 @@ class SQLIn {
|
|
|
35536
35715
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
35537
35716
|
return;
|
|
35538
35717
|
}
|
|
35718
|
+
if (intype instanceof basic_1.TableType && this.isRangeRow(intype.getRowType()) === false) {
|
|
35719
|
+
const name = insource.concatTokens().replace(/^@/, "").replace(/\[\]$/, "");
|
|
35720
|
+
const message = `row structure of ${name} is not correct`;
|
|
35721
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
35722
|
+
return;
|
|
35723
|
+
}
|
|
35539
35724
|
}
|
|
35540
35725
|
return;
|
|
35541
35726
|
}
|
|
@@ -35546,6 +35731,16 @@ class SQLIn {
|
|
|
35546
35731
|
sql_source_1.SQLSource.runSyntax(s, input);
|
|
35547
35732
|
}
|
|
35548
35733
|
}
|
|
35734
|
+
// "IN itab" expects a ranges table, ie. the row must have SIGN, OPTION, LOW and HIGH
|
|
35735
|
+
static isRangeRow(rowType) {
|
|
35736
|
+
if (rowType instanceof basic_1.VoidType || rowType instanceof basic_1.UnknownType || rowType instanceof basic_1.AnyType) {
|
|
35737
|
+
return true;
|
|
35738
|
+
}
|
|
35739
|
+
else if (!(rowType instanceof basic_1.StructureType)) {
|
|
35740
|
+
return false;
|
|
35741
|
+
}
|
|
35742
|
+
return RANGE_COMPONENTS.every(c => rowType.getComponentByName(c) !== undefined);
|
|
35743
|
+
}
|
|
35549
35744
|
}
|
|
35550
35745
|
exports.SQLIn = SQLIn;
|
|
35551
35746
|
//# sourceMappingURL=sql_in.js.map
|
|
@@ -39624,7 +39819,7 @@ class CreateObject {
|
|
|
39624
39819
|
this.validateParameters(cdef, node, input);
|
|
39625
39820
|
}
|
|
39626
39821
|
static checkInstantiationAllowed(cdef, input) {
|
|
39627
|
-
var _a, _b
|
|
39822
|
+
var _a, _b;
|
|
39628
39823
|
const createVis = cdef.getCreateVisibility();
|
|
39629
39824
|
if (createVis === visibility_1.Visibility.Public) {
|
|
39630
39825
|
return undefined;
|
|
@@ -39637,34 +39832,17 @@ class CreateObject {
|
|
|
39637
39832
|
if (enclosingClass.toUpperCase() === cdef.getName().toUpperCase()) {
|
|
39638
39833
|
return undefined;
|
|
39639
39834
|
}
|
|
39640
|
-
if (
|
|
39641
|
-
input.scope.isLocalFriend(cdef.getName(), enclosingClass)) {
|
|
39835
|
+
if (new _object_oriented_1.ObjectOriented(input.scope).hasFriendship(cdef, enclosingClass)) {
|
|
39642
39836
|
return undefined;
|
|
39643
39837
|
}
|
|
39644
|
-
const enclosingDefinition = input.scope.findClassDefinition(enclosingClass);
|
|
39645
|
-
if (enclosingDefinition !== undefined) {
|
|
39646
|
-
const implementedInterfaces = new _object_oriented_1.ObjectOriented(input.scope).findInterfaces(enclosingDefinition);
|
|
39647
|
-
if (cdef.getFriends().some(friend => implementedInterfaces.some(implemented => implemented.name.toUpperCase() === friend.toUpperCase()))) {
|
|
39648
|
-
return undefined;
|
|
39649
|
-
}
|
|
39650
|
-
}
|
|
39651
|
-
// subclasses of friends also have friendship
|
|
39652
|
-
let enclosingSup = enclosingDefinition === null || enclosingDefinition === void 0 ? void 0 : enclosingDefinition.getSuperClass();
|
|
39653
|
-
while (enclosingSup !== undefined) {
|
|
39654
|
-
if (cdef.getFriends().some(f => f.toUpperCase() === enclosingSup.toUpperCase()) ||
|
|
39655
|
-
input.scope.isLocalFriend(cdef.getName(), enclosingSup)) {
|
|
39656
|
-
return undefined;
|
|
39657
|
-
}
|
|
39658
|
-
enclosingSup = (_a = input.scope.findClassDefinition(enclosingSup)) === null || _a === void 0 ? void 0 : _a.getSuperClass();
|
|
39659
|
-
}
|
|
39660
39838
|
if (createVis === visibility_1.Visibility.Protected) {
|
|
39661
39839
|
// subclasses are also allowed
|
|
39662
|
-
let sup = (
|
|
39840
|
+
let sup = (_a = input.scope.findClassDefinition(enclosingClass)) === null || _a === void 0 ? void 0 : _a.getSuperClass();
|
|
39663
39841
|
while (sup !== undefined) {
|
|
39664
39842
|
if (sup.toUpperCase() === cdef.getName().toUpperCase()) {
|
|
39665
39843
|
return undefined;
|
|
39666
39844
|
}
|
|
39667
|
-
sup = (
|
|
39845
|
+
sup = (_b = input.scope.findClassDefinition(sup)) === null || _b === void 0 ? void 0 : _b.getSuperClass();
|
|
39668
39846
|
}
|
|
39669
39847
|
}
|
|
39670
39848
|
return cdef.getName() + " cannot be instantiated, class is defined as " +
|
|
@@ -39928,6 +40106,7 @@ const source_1 = __webpack_require__(/*! ../expressions/source */ "./node_module
|
|
|
39928
40106
|
const dynamic_1 = __webpack_require__(/*! ../expressions/dynamic */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/dynamic.js");
|
|
39929
40107
|
const database_table_1 = __webpack_require__(/*! ../expressions/database_table */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/database_table.js");
|
|
39930
40108
|
const _check_database_fields_1 = __webpack_require__(/*! ../expressions/_check_database_fields */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_database_fields.js");
|
|
40109
|
+
const sql_in_1 = __webpack_require__(/*! ../expressions/sql_in */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/sql_in.js");
|
|
39931
40110
|
class DeleteDatabase {
|
|
39932
40111
|
runSyntax(node, input) {
|
|
39933
40112
|
for (const s of node.findAllExpressions(Expressions.Source)) {
|
|
@@ -39939,6 +40118,12 @@ class DeleteDatabase {
|
|
|
39939
40118
|
for (const d of node.findAllExpressions(Expressions.Dynamic)) {
|
|
39940
40119
|
dynamic_1.Dynamic.runSyntax(d, input);
|
|
39941
40120
|
}
|
|
40121
|
+
for (const compare of node.findAllExpressions(Expressions.SQLCompare)) {
|
|
40122
|
+
const sqlin = compare.findDirectExpression(Expressions.SQLIn);
|
|
40123
|
+
if (sqlin !== undefined) {
|
|
40124
|
+
sql_in_1.SQLIn.runSyntax(sqlin, input);
|
|
40125
|
+
}
|
|
40126
|
+
}
|
|
39942
40127
|
const dbtab = node.findFirstExpression(Expressions.DatabaseTable);
|
|
39943
40128
|
if (dbtab !== undefined) {
|
|
39944
40129
|
const dbSource = database_table_1.DatabaseTable.runSyntax(dbtab, input);
|
|
@@ -40943,13 +41128,17 @@ const expressions_1 = __webpack_require__(/*! ../../2_statements/expressions */
|
|
|
40943
41128
|
const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
|
|
40944
41129
|
class Form {
|
|
40945
41130
|
runSyntax(node, input) {
|
|
40946
|
-
|
|
40947
|
-
const name =
|
|
40948
|
-
if (name === undefined) {
|
|
41131
|
+
const nameExpression = node.findDirectExpression(expressions_1.FormName);
|
|
41132
|
+
const name = nameExpression === null || nameExpression === void 0 ? void 0 : nameExpression.concatTokens();
|
|
41133
|
+
if (nameExpression === undefined || name === undefined) {
|
|
40949
41134
|
const message = "Form, could not find name";
|
|
40950
41135
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
40951
41136
|
return;
|
|
40952
41137
|
}
|
|
41138
|
+
if (name.length > 30) {
|
|
41139
|
+
const message = "FORM name longer than 30 characters";
|
|
41140
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, nameExpression.getFirstToken(), message));
|
|
41141
|
+
}
|
|
40953
41142
|
input.scope.push(_scope_type_1.ScopeType.Form, name, node.getFirstToken().getStart(), input.filename);
|
|
40954
41143
|
const form = new form_definition_1.FormDefinition(node, input);
|
|
40955
41144
|
input.scope.addList(form.getUsingParameters());
|
|
@@ -41009,7 +41198,7 @@ const Expressions = __importStar(__webpack_require__(/*! ../../2_statements/expr
|
|
|
41009
41198
|
const source_1 = __webpack_require__(/*! ../expressions/source */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/source.js");
|
|
41010
41199
|
class Format {
|
|
41011
41200
|
runSyntax(node, input) {
|
|
41012
|
-
for (const s of node.
|
|
41201
|
+
for (const s of node.findAllExpressionsMulti([Expressions.Source, Expressions.SimpleSource3])) {
|
|
41013
41202
|
source_1.Source.runSyntax(s, input);
|
|
41014
41203
|
}
|
|
41015
41204
|
}
|
|
@@ -43834,6 +44023,16 @@ class Parameter {
|
|
|
43834
44023
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
43835
44024
|
return;
|
|
43836
44025
|
}
|
|
44026
|
+
const radioGroup = node.findFirstExpression(Expressions.RadioGroupName);
|
|
44027
|
+
if (radioGroup && radioGroup.concatTokens().length > 4) {
|
|
44028
|
+
const message = "Radio button group name too long, " + radioGroup.concatTokens();
|
|
44029
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, radioGroup.getFirstToken(), message));
|
|
44030
|
+
}
|
|
44031
|
+
if (this.hasUserCommand(node) && this.hasLength(node)) {
|
|
44032
|
+
const message = "USER-COMMAND and LENGTH not possible together";
|
|
44033
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
44034
|
+
return;
|
|
44035
|
+
}
|
|
43837
44036
|
const bfound = new basic_types_1.BasicTypes(input).parseType(node);
|
|
43838
44037
|
if (bfound) {
|
|
43839
44038
|
input.scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(nameToken, input.filename, bfound));
|
|
@@ -43845,6 +44044,30 @@ class Parameter {
|
|
|
43845
44044
|
const magicToken = new tokens_1.Identifier(nameToken.getStart(), magicName);
|
|
43846
44045
|
input.scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(magicToken, input.filename, basic_1.VoidType.get("PARAMETER-MAGIC")));
|
|
43847
44046
|
}
|
|
44047
|
+
// "USER-COMMAND" is lexed as three tokens
|
|
44048
|
+
hasUserCommand(node) {
|
|
44049
|
+
const tokens = node.getTokens();
|
|
44050
|
+
for (let i = 0; i < tokens.length - 2; i++) {
|
|
44051
|
+
if (tokens[i].getStr().toUpperCase() === "USER"
|
|
44052
|
+
&& tokens[i + 1].getStr() === "-"
|
|
44053
|
+
&& tokens[i + 2].getStr().toUpperCase() === "COMMAND") {
|
|
44054
|
+
return true;
|
|
44055
|
+
}
|
|
44056
|
+
}
|
|
44057
|
+
return false;
|
|
44058
|
+
}
|
|
44059
|
+
// "VISIBLE LENGTH" is not the same as "LENGTH"
|
|
44060
|
+
hasLength(node) {
|
|
44061
|
+
var _a;
|
|
44062
|
+
const tokens = node.getTokens();
|
|
44063
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
44064
|
+
if (tokens[i].getStr().toUpperCase() === "LENGTH"
|
|
44065
|
+
&& ((_a = tokens[i - 1]) === null || _a === void 0 ? void 0 : _a.getStr().toUpperCase()) !== "VISIBLE") {
|
|
44066
|
+
return true;
|
|
44067
|
+
}
|
|
44068
|
+
}
|
|
44069
|
+
return false;
|
|
44070
|
+
}
|
|
43848
44071
|
}
|
|
43849
44072
|
exports.Parameter = Parameter;
|
|
43850
44073
|
//# sourceMappingURL=parameter.js.map
|
|
@@ -43902,6 +44125,7 @@ const target_1 = __webpack_require__(/*! ../expressions/target */ "./node_module
|
|
|
43902
44125
|
const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
|
|
43903
44126
|
const assert_error_1 = __webpack_require__(/*! ../assert_error */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/assert_error.js");
|
|
43904
44127
|
const dynamic_1 = __webpack_require__(/*! ../expressions/dynamic */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/dynamic.js");
|
|
44128
|
+
const _type_utils_1 = __webpack_require__(/*! ../_type_utils */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_type_utils.js");
|
|
43905
44129
|
class Perform {
|
|
43906
44130
|
runSyntax(node, input) {
|
|
43907
44131
|
if (!(node.get() instanceof Statements.Perform)) {
|
|
@@ -43909,19 +44133,22 @@ class Perform {
|
|
|
43909
44133
|
}
|
|
43910
44134
|
////////////////////////////
|
|
43911
44135
|
// check parameters are defined
|
|
44136
|
+
const changing = [];
|
|
43912
44137
|
for (const c of node.findDirectExpressions(Expressions.PerformChanging)) {
|
|
43913
44138
|
for (const s of c.findDirectExpressions(Expressions.Target)) {
|
|
43914
|
-
target_1.Target.runSyntax(s, input);
|
|
44139
|
+
changing.push({ node: s, type: target_1.Target.runSyntax(s, input) });
|
|
43915
44140
|
}
|
|
43916
44141
|
}
|
|
44142
|
+
const tables = [];
|
|
43917
44143
|
for (const t of node.findDirectExpressions(Expressions.PerformTables)) {
|
|
43918
44144
|
for (const s of t.findDirectExpressions(Expressions.Source)) {
|
|
43919
|
-
source_1.Source.runSyntax(s, input);
|
|
44145
|
+
tables.push({ node: s, type: source_1.Source.runSyntax(s, input) });
|
|
43920
44146
|
}
|
|
43921
44147
|
}
|
|
44148
|
+
const using = [];
|
|
43922
44149
|
for (const u of node.findDirectExpressions(Expressions.PerformUsing)) {
|
|
43923
44150
|
for (const s of u.findDirectExpressions(Expressions.SimpleSource3)) {
|
|
43924
|
-
source_1.Source.runSyntax(s, input);
|
|
44151
|
+
using.push({ node: s, type: source_1.Source.runSyntax(s, input) });
|
|
43925
44152
|
}
|
|
43926
44153
|
}
|
|
43927
44154
|
////////////////////////////
|
|
@@ -43946,7 +44173,40 @@ class Perform {
|
|
|
43946
44173
|
return;
|
|
43947
44174
|
}
|
|
43948
44175
|
input.scope.addReference(expr.getFirstToken(), found, _reference_1.ReferenceType.FormReference, input.filename);
|
|
43949
|
-
|
|
44176
|
+
////////////////////////////
|
|
44177
|
+
// check parameters match
|
|
44178
|
+
// USING and CHANGING are interchangeable, the actual parameters form a single positional list
|
|
44179
|
+
if (this.checkParameters(node, tables, found.getTablesParameters(), "TABLES", input) === false) {
|
|
44180
|
+
return;
|
|
44181
|
+
}
|
|
44182
|
+
const formal = found.getUsingParameters().concat(found.getChangingParameters());
|
|
44183
|
+
this.checkParameters(node, using.concat(changing), formal, "USING/CHANGING", input);
|
|
44184
|
+
}
|
|
44185
|
+
// returns false if an issue was reported
|
|
44186
|
+
checkParameters(node, actual, formal, kind, input) {
|
|
44187
|
+
if (actual.length !== formal.length) {
|
|
44188
|
+
const message = `PERFORM, expected ${formal.length} ${kind} parameters, found ${actual.length}`;
|
|
44189
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
44190
|
+
return false;
|
|
44191
|
+
}
|
|
44192
|
+
const typeUtils = new _type_utils_1.TypeUtils(input.scope);
|
|
44193
|
+
for (let i = 0; i < actual.length; i++) {
|
|
44194
|
+
const { node: source, type } = actual[i];
|
|
44195
|
+
if (type === undefined) {
|
|
44196
|
+
continue;
|
|
44197
|
+
}
|
|
44198
|
+
const parameter = formal[i];
|
|
44199
|
+
const structureTyping = parameter.getMeta().includes("form_parameter_structure" /* IdentifierMeta.FormParameterStructure */);
|
|
44200
|
+
const assignable = structureTyping
|
|
44201
|
+
? typeUtils.isAssignableStructureTyping(type, parameter.getType(), source)
|
|
44202
|
+
: typeUtils.isAssignableStrict(type, parameter.getType(), source);
|
|
44203
|
+
if (assignable === false) {
|
|
44204
|
+
const message = `PERFORM parameter type not compatible, ${parameter.getName()}`;
|
|
44205
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, source.getFirstToken(), message));
|
|
44206
|
+
return false;
|
|
44207
|
+
}
|
|
44208
|
+
}
|
|
44209
|
+
return true;
|
|
43950
44210
|
}
|
|
43951
44211
|
}
|
|
43952
44212
|
exports.Perform = Perform;
|
|
@@ -51927,6 +52187,7 @@ const constants_1 = __webpack_require__(/*! ../5_syntax/structures/constants */
|
|
|
51927
52187
|
const type_definitions_1 = __webpack_require__(/*! ./type_definitions */ "./node_modules/@abaplint/core/build/src/abap/types/type_definitions.js");
|
|
51928
52188
|
const types_1 = __webpack_require__(/*! ../5_syntax/structures/types */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/structures/types.js");
|
|
51929
52189
|
const type_1 = __webpack_require__(/*! ../5_syntax/statements/type */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/statements/type.js");
|
|
52190
|
+
const _syntax_input_1 = __webpack_require__(/*! ../5_syntax/_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
|
|
51930
52191
|
const _reference_1 = __webpack_require__(/*! ../5_syntax/_reference */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_reference.js");
|
|
51931
52192
|
const alias_1 = __webpack_require__(/*! ./alias */ "./node_modules/@abaplint/core/build/src/abap/types/alias.js");
|
|
51932
52193
|
class Attributes {
|
|
@@ -52148,6 +52409,13 @@ class Attributes {
|
|
|
52148
52409
|
if (foundAttribute) {
|
|
52149
52410
|
input.scope.addNamedIdentifier(aliasName.getStr(), foundAttribute);
|
|
52150
52411
|
}
|
|
52412
|
+
const component = compName.split("~")[1];
|
|
52413
|
+
if (foundType === undefined
|
|
52414
|
+
&& foundAttribute === undefined
|
|
52415
|
+
&& this.existsInInterface(idef, component, input, []) === false) {
|
|
52416
|
+
const message = "Component " + component + " not found in interface " + idef.getName();
|
|
52417
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, compToken, message));
|
|
52418
|
+
}
|
|
52151
52419
|
}
|
|
52152
52420
|
else if (this.declaredInterfaces.includes(name.toUpperCase()) || input.scope.getDDIC().inErrorNamespace(name) === false) {
|
|
52153
52421
|
input.scope.addReference(compToken, undefined, _reference_1.ReferenceType.ObjectOrientedVoidReference, input.filename);
|
|
@@ -52157,6 +52425,33 @@ class Attributes {
|
|
|
52157
52425
|
}
|
|
52158
52426
|
}
|
|
52159
52427
|
}
|
|
52428
|
+
/** does the component exist in the interface, or in one of its aliases or included interfaces? */
|
|
52429
|
+
existsInInterface(idef, component, input, visited) {
|
|
52430
|
+
const upperName = idef.getName().toUpperCase();
|
|
52431
|
+
if (visited.includes(upperName)) {
|
|
52432
|
+
return false;
|
|
52433
|
+
}
|
|
52434
|
+
visited.push(upperName);
|
|
52435
|
+
const upper = component.toUpperCase();
|
|
52436
|
+
if (idef.getTypeDefinitions().getByName(component) !== undefined
|
|
52437
|
+
|| idef.getAttributes().findByName(component) !== undefined
|
|
52438
|
+
|| idef.getMethodDefinitions().getByName(component) !== undefined
|
|
52439
|
+
|| idef.getEvents().some(e => e.getName().toUpperCase() === upper)
|
|
52440
|
+
|| idef.getAliases().some(a => a.getName().toUpperCase() === upper)) {
|
|
52441
|
+
return true;
|
|
52442
|
+
}
|
|
52443
|
+
for (const i of idef.getImplementing()) {
|
|
52444
|
+
const sub = input.scope.findInterfaceDefinition(i.name);
|
|
52445
|
+
if (sub === undefined) {
|
|
52446
|
+
// voided or not found, assume the component exists
|
|
52447
|
+
return true;
|
|
52448
|
+
}
|
|
52449
|
+
else if (this.existsInInterface(sub, component, input, visited)) {
|
|
52450
|
+
return true;
|
|
52451
|
+
}
|
|
52452
|
+
}
|
|
52453
|
+
return false;
|
|
52454
|
+
}
|
|
52160
52455
|
parseAttribute(node, visibility, input) {
|
|
52161
52456
|
let found = undefined;
|
|
52162
52457
|
const s = node.get();
|
|
@@ -52788,7 +53083,8 @@ class FormDefinition extends _identifier_1.Identifier {
|
|
|
52788
53083
|
else if (!(type instanceof basic_1.UnknownType) && !(type instanceof basic_1.VoidType)) {
|
|
52789
53084
|
type = new basic_1.UnknownType("FORM TABLES type must be table type");
|
|
52790
53085
|
}
|
|
52791
|
-
|
|
53086
|
+
// keep the meta from FormParam, so STRUCTURE typing can be recognized later
|
|
53087
|
+
ret.push(new _typed_identifier_1.TypedIdentifier(p.getToken(), input.filename, type, p.getMeta()));
|
|
52792
53088
|
}
|
|
52793
53089
|
}
|
|
52794
53090
|
return ret;
|
|
@@ -70299,7 +70595,7 @@ class Registry {
|
|
|
70299
70595
|
}
|
|
70300
70596
|
static abaplintVersion() {
|
|
70301
70597
|
// magic, see build script "version.js"
|
|
70302
|
-
return "2.120.
|
|
70598
|
+
return "2.120.37";
|
|
70303
70599
|
}
|
|
70304
70600
|
getDDICReferences() {
|
|
70305
70601
|
return this.ddicReferences;
|
|
@@ -72986,6 +73282,11 @@ class CDSCheckSyntaxConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
|
72986
73282
|
exports.CDSCheckSyntaxConf = CDSCheckSyntaxConf;
|
|
72987
73283
|
const KNOWN_QUAN_DATA_ELEMENTS = ["MENGE_D"];
|
|
72988
73284
|
const KNOWN_CURR_DATA_ELEMENTS = ["BWERT", "DZWERT"];
|
|
73285
|
+
// Reserved names, cannot be used as element names, see DDIC table TRESE
|
|
73286
|
+
const RESERVED_ELEMENT_NAMES = ["BEGIN", "NUMBER", "POSITION"];
|
|
73287
|
+
const MAX_LABEL_LENGTH = 40;
|
|
73288
|
+
// Annotations which are not supported in CDS view entities
|
|
73289
|
+
const VIEW_ENTITY_FORBIDDEN_ANNOTATIONS = ["Semantics.unitOfMeasure"];
|
|
72989
73290
|
class CDSCheckSyntax {
|
|
72990
73291
|
constructor() {
|
|
72991
73292
|
this.conf = new CDSCheckSyntaxConf();
|
|
@@ -73027,6 +73328,9 @@ Missing objects are only reported when their names match the configured errorNam
|
|
|
73027
73328
|
this.checkTypes(tree, ddic, issues, file);
|
|
73028
73329
|
this.checkRootProjection(tree, ddic, issues, file);
|
|
73029
73330
|
this.checkFieldAnnotations(tree, ddic, issues, file);
|
|
73331
|
+
this.checkLabels(tree, issues, file);
|
|
73332
|
+
this.checkViewEntityAnnotations(tree, issues, file);
|
|
73333
|
+
this.checkReservedNames(tree, issues, file);
|
|
73030
73334
|
this.checkFields(tree, sources, object, issues, file);
|
|
73031
73335
|
return issues;
|
|
73032
73336
|
}
|
|
@@ -73211,6 +73515,62 @@ Missing objects are only reported when their names match the configured errorNam
|
|
|
73211
73515
|
|| a.toUpperCase().includes("@SEMANTICS:{CURRENCYCODE:TRUE"));
|
|
73212
73516
|
}
|
|
73213
73517
|
}
|
|
73518
|
+
checkLabels(tree, issues, file) {
|
|
73519
|
+
for (const annotation of tree.findAllExpressionsRecursive(expressions_1.CDSAnnotation)) {
|
|
73520
|
+
const concatenated = annotation.concatTokens();
|
|
73521
|
+
if (/@\s*<?\s*EndUserText/i.test(concatenated) === false) {
|
|
73522
|
+
continue;
|
|
73523
|
+
}
|
|
73524
|
+
const expression = /label\s*:\s*'((?:[^']|'')*)'/gi;
|
|
73525
|
+
let match = expression.exec(concatenated);
|
|
73526
|
+
while (match !== null) {
|
|
73527
|
+
const label = match[1].replace(/''/g, "'");
|
|
73528
|
+
if (label.length > MAX_LABEL_LENGTH) {
|
|
73529
|
+
const message = `CDS label is ${label.length} characters, maximum is ${MAX_LABEL_LENGTH}`;
|
|
73530
|
+
issues.push(issue_1.Issue.atToken(file, annotation.getFirstToken(), message, this.getMetadata().key, this.conf.severity));
|
|
73531
|
+
}
|
|
73532
|
+
match = expression.exec(concatenated);
|
|
73533
|
+
}
|
|
73534
|
+
}
|
|
73535
|
+
}
|
|
73536
|
+
checkViewEntityAnnotations(tree, issues, file) {
|
|
73537
|
+
const view = tree.findFirstExpression(expressions_1.CDSDefineView);
|
|
73538
|
+
if (view === undefined || view.findDirectTokenByText("ENTITY") === undefined) {
|
|
73539
|
+
return;
|
|
73540
|
+
}
|
|
73541
|
+
for (const annotation of tree.findAllExpressionsRecursive(expressions_1.CDSAnnotation)) {
|
|
73542
|
+
const normalized = annotation.concatTokens().replace(/\s/g, "").toUpperCase().replace(/^@</, "@");
|
|
73543
|
+
for (const forbidden of VIEW_ENTITY_FORBIDDEN_ANNOTATIONS) {
|
|
73544
|
+
const upper = forbidden.toUpperCase();
|
|
73545
|
+
if (normalized.startsWith("@" + upper) === false
|
|
73546
|
+
&& normalized.startsWith("@" + upper.replace(".", ":{")) === false) {
|
|
73547
|
+
continue;
|
|
73548
|
+
}
|
|
73549
|
+
const message = `Annotation ${forbidden} is not allowed in view entities`;
|
|
73550
|
+
issues.push(issue_1.Issue.atToken(file, annotation.getFirstToken(), message, this.getMetadata().key, this.conf.severity));
|
|
73551
|
+
}
|
|
73552
|
+
}
|
|
73553
|
+
}
|
|
73554
|
+
checkReservedNames(tree, issues, file) {
|
|
73555
|
+
var _a, _b;
|
|
73556
|
+
for (const element of tree.findAllExpressionsRecursive(expressions_1.CDSElement)) {
|
|
73557
|
+
if (element.findDirectTokenByText("INCLUDE") !== undefined) {
|
|
73558
|
+
continue;
|
|
73559
|
+
}
|
|
73560
|
+
let nameNode = (_a = element.findDirectExpression(expressions_1.CDSAs)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(expressions_1.CDSName);
|
|
73561
|
+
if (nameNode === undefined) {
|
|
73562
|
+
const names = ((_b = element.findDirectExpression(expressions_1.CDSPrefixedName)) === null || _b === void 0 ? void 0 : _b.findDirectExpressions(expressions_1.CDSName)) || [];
|
|
73563
|
+
nameNode = names[names.length - 1];
|
|
73564
|
+
}
|
|
73565
|
+
if (nameNode === undefined) {
|
|
73566
|
+
continue;
|
|
73567
|
+
}
|
|
73568
|
+
const name = this.name(nameNode);
|
|
73569
|
+
if (RESERVED_ELEMENT_NAMES.includes(name.toUpperCase())) {
|
|
73570
|
+
issues.push(issue_1.Issue.atToken(file, nameNode.getFirstToken(), `CDS element name "${name}" is reserved`, this.getMetadata().key, this.conf.severity));
|
|
73571
|
+
}
|
|
73572
|
+
}
|
|
73573
|
+
}
|
|
73214
73574
|
checkFields(tree, sources, object, issues, file) {
|
|
73215
73575
|
var _a;
|
|
73216
73576
|
const associationNames = new Set();
|
|
@@ -73439,7 +73799,8 @@ class CDSFieldOrder {
|
|
|
73439
73799
|
}
|
|
73440
73800
|
getAssociationNames(tree) {
|
|
73441
73801
|
const names = new Set();
|
|
73442
|
-
|
|
73802
|
+
const found = [...tree.findAllExpressions(expressions_1.CDSAssociation), ...tree.findAllExpressions(expressions_1.CDSComposition)];
|
|
73803
|
+
for (const assoc of found) {
|
|
73443
73804
|
const relation = assoc.findDirectExpression(expressions_1.CDSRelation);
|
|
73444
73805
|
if (relation === undefined) {
|
|
73445
73806
|
continue;
|
|
@@ -73557,7 +73918,6 @@ const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/c
|
|
|
73557
73918
|
const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
|
|
73558
73919
|
const objects_1 = __webpack_require__(/*! ../objects */ "./node_modules/@abaplint/core/build/src/objects/index.js");
|
|
73559
73920
|
const expressions_1 = __webpack_require__(/*! ../cds/expressions */ "./node_modules/@abaplint/core/build/src/cds/expressions/index.js");
|
|
73560
|
-
const cds_name_1 = __webpack_require__(/*! ../cds/expressions/cds_name */ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_name.js");
|
|
73561
73921
|
class CDSNamingConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
73562
73922
|
constructor() {
|
|
73563
73923
|
super(...arguments);
|
|
@@ -73629,7 +73989,7 @@ https://help.sap.com/docs/SAP_S4HANA_ON-PREMISE/ee6ff9b281d8448f96b4fe6c89f2bdc8
|
|
|
73629
73989
|
if (file === undefined) {
|
|
73630
73990
|
return [];
|
|
73631
73991
|
}
|
|
73632
|
-
const name =
|
|
73992
|
+
const name = o.getDefinitionName();
|
|
73633
73993
|
if (name === undefined) {
|
|
73634
73994
|
return [];
|
|
73635
73995
|
}
|
|
@@ -73646,13 +74006,6 @@ https://help.sap.com/docs/SAP_S4HANA_ON-PREMISE/ee6ff9b281d8448f96b4fe6c89f2bdc8
|
|
|
73646
74006
|
}
|
|
73647
74007
|
return [];
|
|
73648
74008
|
}
|
|
73649
|
-
getCDSName(tree) {
|
|
73650
|
-
const nameNodes = tree.findDirectExpressions(cds_name_1.CDSName);
|
|
73651
|
-
if (nameNodes.length > 0) {
|
|
73652
|
-
return nameNodes[0].getFirstToken().getStr();
|
|
73653
|
-
}
|
|
73654
|
-
return undefined;
|
|
73655
|
-
}
|
|
73656
74009
|
getAllowedPrefixes(tree) {
|
|
73657
74010
|
const root = tree.get();
|
|
73658
74011
|
if (root instanceof expressions_1.CDSExtendView) {
|
|
@@ -75674,6 +76027,7 @@ class CloudTypes {
|
|
|
75674
76027
|
|| obj instanceof Objects.BehaviorDefinition
|
|
75675
76028
|
|| obj instanceof Objects.BusinessCatalog
|
|
75676
76029
|
|| obj instanceof Objects.BusinessCatalogAppAssignment
|
|
76030
|
+
|| obj instanceof Objects.BusinessConfigurationMaintenanceObject
|
|
75677
76031
|
|| obj instanceof Objects.CDSMetadataExtension
|
|
75678
76032
|
|| obj instanceof Objects.Class
|
|
75679
76033
|
|| obj instanceof Objects.CDSType
|
|
@@ -75690,11 +76044,13 @@ class CloudTypes {
|
|
|
75690
76044
|
|| obj instanceof Objects.EventBinding
|
|
75691
76045
|
|| obj instanceof Objects.EventConsumer
|
|
75692
76046
|
|| obj instanceof Objects.FunctionGroup
|
|
76047
|
+
|| obj instanceof Objects.GatewayODataGroupAndAssignment
|
|
75693
76048
|
|| obj instanceof Objects.HttpService
|
|
75694
76049
|
|| obj instanceof Objects.IAMApp
|
|
75695
76050
|
|| obj instanceof Objects.InboundService
|
|
75696
76051
|
|| obj instanceof Objects.Interface
|
|
75697
76052
|
|| obj instanceof Objects.LockObject
|
|
76053
|
+
|| obj instanceof Objects.MaintenanceAndTransportObject
|
|
75698
76054
|
|| obj instanceof Objects.MessageClass
|
|
75699
76055
|
|| obj instanceof Objects.NumberRange
|
|
75700
76056
|
|| obj instanceof Objects.OutboundService
|
|
@@ -84460,6 +84816,7 @@ __exportStar(__webpack_require__(/*! ./newline_between_methods */ "./node_module
|
|
|
84460
84816
|
__exportStar(__webpack_require__(/*! ./no_aliases */ "./node_modules/@abaplint/core/build/src/rules/no_aliases.js"), exports);
|
|
84461
84817
|
__exportStar(__webpack_require__(/*! ./no_chained_assignment */ "./node_modules/@abaplint/core/build/src/rules/no_chained_assignment.js"), exports);
|
|
84462
84818
|
__exportStar(__webpack_require__(/*! ./no_comments_between_methods */ "./node_modules/@abaplint/core/build/src/rules/no_comments_between_methods.js"), exports);
|
|
84819
|
+
__exportStar(__webpack_require__(/*! ./no_dynamic_stuff */ "./node_modules/@abaplint/core/build/src/rules/no_dynamic_stuff.js"), exports);
|
|
84463
84820
|
__exportStar(__webpack_require__(/*! ./no_external_form_calls */ "./node_modules/@abaplint/core/build/src/rules/no_external_form_calls.js"), exports);
|
|
84464
84821
|
__exportStar(__webpack_require__(/*! ./no_inline_in_optional_branches */ "./node_modules/@abaplint/core/build/src/rules/no_inline_in_optional_branches.js"), exports);
|
|
84465
84822
|
__exportStar(__webpack_require__(/*! ./no_macros */ "./node_modules/@abaplint/core/build/src/rules/no_macros.js"), exports);
|
|
@@ -84539,6 +84896,7 @@ __exportStar(__webpack_require__(/*! ./when_others_last */ "./node_modules/@abap
|
|
|
84539
84896
|
__exportStar(__webpack_require__(/*! ./whitespace_end */ "./node_modules/@abaplint/core/build/src/rules/whitespace_end.js"), exports);
|
|
84540
84897
|
__exportStar(__webpack_require__(/*! ./xml_consistency */ "./node_modules/@abaplint/core/build/src/rules/xml_consistency.js"), exports);
|
|
84541
84898
|
__exportStar(__webpack_require__(/*! ./no_exclamation_escape */ "./node_modules/@abaplint/core/build/src/rules/no_exclamation_escape.js"), exports);
|
|
84899
|
+
__exportStar(__webpack_require__(/*! ./xml_bom */ "./node_modules/@abaplint/core/build/src/rules/xml_bom.js"), exports);
|
|
84542
84900
|
__exportStar(__webpack_require__(/*! ./no_exclamation_escape */ "./node_modules/@abaplint/core/build/src/rules/no_exclamation_escape.js"), exports);
|
|
84543
84901
|
//# sourceMappingURL=index.js.map
|
|
84544
84902
|
|
|
@@ -88572,6 +88930,250 @@ exports.NoCommentsBetweenMethods = NoCommentsBetweenMethods;
|
|
|
88572
88930
|
|
|
88573
88931
|
/***/ },
|
|
88574
88932
|
|
|
88933
|
+
/***/ "./node_modules/@abaplint/core/build/src/rules/no_dynamic_stuff.js"
|
|
88934
|
+
/*!*************************************************************************!*\
|
|
88935
|
+
!*** ./node_modules/@abaplint/core/build/src/rules/no_dynamic_stuff.js ***!
|
|
88936
|
+
\*************************************************************************/
|
|
88937
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
88938
|
+
|
|
88939
|
+
"use strict";
|
|
88940
|
+
|
|
88941
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
88942
|
+
if (k2 === undefined) k2 = k;
|
|
88943
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
88944
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
88945
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
88946
|
+
}
|
|
88947
|
+
Object.defineProperty(o, k2, desc);
|
|
88948
|
+
}) : (function(o, m, k, k2) {
|
|
88949
|
+
if (k2 === undefined) k2 = k;
|
|
88950
|
+
o[k2] = m[k];
|
|
88951
|
+
}));
|
|
88952
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
88953
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
88954
|
+
}) : function(o, v) {
|
|
88955
|
+
o["default"] = v;
|
|
88956
|
+
});
|
|
88957
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
88958
|
+
var ownKeys = function(o) {
|
|
88959
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
88960
|
+
var ar = [];
|
|
88961
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
88962
|
+
return ar;
|
|
88963
|
+
};
|
|
88964
|
+
return ownKeys(o);
|
|
88965
|
+
};
|
|
88966
|
+
return function (mod) {
|
|
88967
|
+
if (mod && mod.__esModule) return mod;
|
|
88968
|
+
var result = {};
|
|
88969
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
88970
|
+
__setModuleDefault(result, mod);
|
|
88971
|
+
return result;
|
|
88972
|
+
};
|
|
88973
|
+
})();
|
|
88974
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
88975
|
+
exports.NoDynamicStuff = exports.NoDynamicStuffConf = void 0;
|
|
88976
|
+
const Statements = __importStar(__webpack_require__(/*! ../abap/2_statements/statements */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/index.js"));
|
|
88977
|
+
const Expressions = __importStar(__webpack_require__(/*! ../abap/2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js"));
|
|
88978
|
+
const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "./node_modules/@abaplint/core/build/src/rules/_abap_rule.js");
|
|
88979
|
+
const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
|
|
88980
|
+
const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
|
|
88981
|
+
const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
|
|
88982
|
+
class NoDynamicStuffConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
88983
|
+
constructor() {
|
|
88984
|
+
super(...arguments);
|
|
88985
|
+
/** Detects dynamic method calls, ie. CALL METHOD (name), SET HANDLER and CALL BADI */
|
|
88986
|
+
this.callMethod = true;
|
|
88987
|
+
/** Detects dynamic CALL FUNCTION, ie. the function module name is not a literal */
|
|
88988
|
+
this.callFunction = true;
|
|
88989
|
+
/** Detects CALL DATABASE PROCEDURE, the procedure name is always dynamic */
|
|
88990
|
+
this.callDatabaseProcedure = true;
|
|
88991
|
+
/** Detects dynamic CALL TRANSFORMATION */
|
|
88992
|
+
this.callTransformation = true;
|
|
88993
|
+
/** Detects dynamic CALL TRANSACTION, ie. the transaction code is not a literal */
|
|
88994
|
+
this.callTransaction = true;
|
|
88995
|
+
/** Detects dynamic PERFORM */
|
|
88996
|
+
this.perform = true;
|
|
88997
|
+
/** Detects dynamic SUBMIT */
|
|
88998
|
+
this.submit = true;
|
|
88999
|
+
/** Detects dynamic CREATE OBJECT */
|
|
89000
|
+
this.createObject = true;
|
|
89001
|
+
/** Detects dynamic CREATE DATA */
|
|
89002
|
+
this.createData = true;
|
|
89003
|
+
/** Detects dynamic GET BADI */
|
|
89004
|
+
this.getBadi = true;
|
|
89005
|
+
/** Detects dynamic ASSIGN, including ASSIGN COMPONENT */
|
|
89006
|
+
this.assign = true;
|
|
89007
|
+
/** Detects dynamic internal table access, ie. dynamic WHERE, keys, SORT BY and TRANSPORTING */
|
|
89008
|
+
this.internalTable = true;
|
|
89009
|
+
/** Detects dynamic EXPORT and IMPORT */
|
|
89010
|
+
this.exportImport = true;
|
|
89011
|
+
}
|
|
89012
|
+
}
|
|
89013
|
+
exports.NoDynamicStuffConf = NoDynamicStuffConf;
|
|
89014
|
+
class NoDynamicStuff extends _abap_rule_1.ABAPRule {
|
|
89015
|
+
constructor() {
|
|
89016
|
+
super(...arguments);
|
|
89017
|
+
this.conf = new NoDynamicStuffConf();
|
|
89018
|
+
}
|
|
89019
|
+
getMetadata() {
|
|
89020
|
+
return {
|
|
89021
|
+
key: "no_dynamic_stuff",
|
|
89022
|
+
title: "No dynamic stuff",
|
|
89023
|
+
shortDescription: `Detects dynamic calls and other dynamic language constructs`,
|
|
89024
|
+
extendedInformation: `Dynamic constructs cannot be checked statically, they are not found by
|
|
89025
|
+
where-used lists and refactorings, and they can introduce injection vulnerabilities.
|
|
89026
|
+
|
|
89027
|
+
Dynamic tokens are also reported when containing a literal, eg. CALL METHOD go_calendar->('RESET_DAY_INFO'),
|
|
89028
|
+
the syntax check does not resolve these either, so they behave like any other dynamic token.
|
|
89029
|
+
|
|
89030
|
+
Dynamic SQL is reported by rule dangerous_statement.`,
|
|
89031
|
+
tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Security],
|
|
89032
|
+
badExample: `CALL METHOD (lv_class)=>(lv_method).
|
|
89033
|
+
CALL METHOD go_calendar->('RESET_DAY_INFO').
|
|
89034
|
+
CALL FUNCTION lv_function_module.
|
|
89035
|
+
CREATE OBJECT ref TYPE (lv_class).
|
|
89036
|
+
ASSIGN (lv_name) TO <fs>.
|
|
89037
|
+
SORT tab BY (lv_field).`,
|
|
89038
|
+
goodExample: `cl_class=>method( ).
|
|
89039
|
+
go_calendar->reset_day_info( ).
|
|
89040
|
+
CALL FUNCTION 'ZFOO'.
|
|
89041
|
+
CREATE OBJECT ref TYPE cl_class.
|
|
89042
|
+
ASSIGN foo TO <fs>.
|
|
89043
|
+
SORT tab BY field.`,
|
|
89044
|
+
};
|
|
89045
|
+
}
|
|
89046
|
+
getConfig() {
|
|
89047
|
+
return this.conf;
|
|
89048
|
+
}
|
|
89049
|
+
setConfig(conf) {
|
|
89050
|
+
this.conf = conf;
|
|
89051
|
+
}
|
|
89052
|
+
runParsed(file) {
|
|
89053
|
+
const issues = [];
|
|
89054
|
+
for (const statementNode of file.getStatements()) {
|
|
89055
|
+
const found = this.check(statementNode);
|
|
89056
|
+
if (found !== undefined) {
|
|
89057
|
+
issues.push(issue_1.Issue.atStatement(file, statementNode, "Dynamic " + found, this.getMetadata().key, this.conf.severity));
|
|
89058
|
+
}
|
|
89059
|
+
}
|
|
89060
|
+
return issues;
|
|
89061
|
+
}
|
|
89062
|
+
check(node) {
|
|
89063
|
+
const statement = node.get();
|
|
89064
|
+
// note that MethodSource is also used by SET HANDLER and CALL BADI
|
|
89065
|
+
if (this.conf.callMethod === true && this.dynamicMethodSource(node) === true) {
|
|
89066
|
+
return "method call";
|
|
89067
|
+
}
|
|
89068
|
+
if (statement instanceof Statements.CallFunction) {
|
|
89069
|
+
if (this.conf.callFunction === true
|
|
89070
|
+
&& this.notLiteral(node.findDirectExpression(Expressions.FunctionName))) {
|
|
89071
|
+
return "CALL FUNCTION";
|
|
89072
|
+
}
|
|
89073
|
+
}
|
|
89074
|
+
else if (statement instanceof Statements.CallDatabase) {
|
|
89075
|
+
if (this.conf.callDatabaseProcedure === true) {
|
|
89076
|
+
return "CALL DATABASE PROCEDURE";
|
|
89077
|
+
}
|
|
89078
|
+
}
|
|
89079
|
+
else if (statement instanceof Statements.CallTransformation) {
|
|
89080
|
+
if (this.conf.callTransformation === true && this.hasDynamic(node)) {
|
|
89081
|
+
return "CALL TRANSFORMATION";
|
|
89082
|
+
}
|
|
89083
|
+
}
|
|
89084
|
+
else if (statement instanceof Statements.CallTransaction) {
|
|
89085
|
+
// the transaction code is a Source, ie. there is no parenthesized dynamic variant
|
|
89086
|
+
if (this.conf.callTransaction === true
|
|
89087
|
+
&& this.notLiteral(node.findDirectExpression(Expressions.Source))) {
|
|
89088
|
+
return "CALL TRANSACTION";
|
|
89089
|
+
}
|
|
89090
|
+
}
|
|
89091
|
+
else if (statement instanceof Statements.Perform) {
|
|
89092
|
+
if (this.conf.perform === true && this.hasDynamic(node)) {
|
|
89093
|
+
return "PERFORM";
|
|
89094
|
+
}
|
|
89095
|
+
}
|
|
89096
|
+
else if (statement instanceof Statements.Submit) {
|
|
89097
|
+
if (this.conf.submit === true && this.hasDynamic(node)) {
|
|
89098
|
+
return "SUBMIT";
|
|
89099
|
+
}
|
|
89100
|
+
}
|
|
89101
|
+
else if (statement instanceof Statements.CreateObject) {
|
|
89102
|
+
if (this.conf.createObject === true && this.hasDynamic(node)) {
|
|
89103
|
+
return "CREATE OBJECT";
|
|
89104
|
+
}
|
|
89105
|
+
}
|
|
89106
|
+
else if (statement instanceof Statements.CreateData) {
|
|
89107
|
+
if (this.conf.createData === true && this.hasDynamic(node)) {
|
|
89108
|
+
return "CREATE DATA";
|
|
89109
|
+
}
|
|
89110
|
+
}
|
|
89111
|
+
else if (statement instanceof Statements.GetBadi) {
|
|
89112
|
+
if (this.conf.getBadi === true && this.hasDynamic(node)) {
|
|
89113
|
+
return "GET BADI";
|
|
89114
|
+
}
|
|
89115
|
+
}
|
|
89116
|
+
else if (statement instanceof Statements.Assign
|
|
89117
|
+
|| statement instanceof Statements.AssignLocalCopy) {
|
|
89118
|
+
if (this.conf.assign === true
|
|
89119
|
+
&& (this.hasDynamic(node) || this.dynamicAssignComponent(node))) {
|
|
89120
|
+
return "ASSIGN";
|
|
89121
|
+
}
|
|
89122
|
+
}
|
|
89123
|
+
else if (statement instanceof Statements.Export) {
|
|
89124
|
+
if (this.conf.exportImport === true && this.hasDynamic(node)) {
|
|
89125
|
+
return "EXPORT";
|
|
89126
|
+
}
|
|
89127
|
+
}
|
|
89128
|
+
else if (statement instanceof Statements.Import) {
|
|
89129
|
+
if (this.conf.exportImport === true && this.hasDynamic(node)) {
|
|
89130
|
+
return "IMPORT";
|
|
89131
|
+
}
|
|
89132
|
+
}
|
|
89133
|
+
else if (statement instanceof Statements.At
|
|
89134
|
+
|| statement instanceof Statements.DeleteInternal
|
|
89135
|
+
|| statement instanceof Statements.InsertInternal
|
|
89136
|
+
|| statement instanceof Statements.Loop
|
|
89137
|
+
|| statement instanceof Statements.ModifyInternal
|
|
89138
|
+
|| statement instanceof Statements.ReadTable
|
|
89139
|
+
|| statement instanceof Statements.Sort
|
|
89140
|
+
|| statement instanceof Statements.SortDataset) {
|
|
89141
|
+
if (this.conf.internalTable === true && this.hasDynamic(node)) {
|
|
89142
|
+
return "internal table access";
|
|
89143
|
+
}
|
|
89144
|
+
}
|
|
89145
|
+
return undefined;
|
|
89146
|
+
}
|
|
89147
|
+
dynamicMethodSource(node) {
|
|
89148
|
+
for (const source of node.findAllExpressions(Expressions.MethodSource)) {
|
|
89149
|
+
// Dynamic is always a direct child of MethodSource, dynamics further down
|
|
89150
|
+
// are parameters of the method call and not part of the method name
|
|
89151
|
+
if (source.findDirectExpression(Expressions.Dynamic) !== undefined) {
|
|
89152
|
+
return true;
|
|
89153
|
+
}
|
|
89154
|
+
}
|
|
89155
|
+
return false;
|
|
89156
|
+
}
|
|
89157
|
+
dynamicAssignComponent(node) {
|
|
89158
|
+
var _a;
|
|
89159
|
+
const component = (_a = node.findDirectExpression(Expressions.AssignSource)) === null || _a === void 0 ? void 0 : _a.findExpressionAfterToken("COMPONENT");
|
|
89160
|
+
return component !== undefined && this.isLiteral(component) === false;
|
|
89161
|
+
}
|
|
89162
|
+
hasDynamic(node) {
|
|
89163
|
+
return node.findFirstExpression(Expressions.Dynamic) !== undefined;
|
|
89164
|
+
}
|
|
89165
|
+
notLiteral(node) {
|
|
89166
|
+
return node !== undefined && this.isLiteral(node) === false;
|
|
89167
|
+
}
|
|
89168
|
+
isLiteral(node) {
|
|
89169
|
+
return node.findDirectExpression(Expressions.Constant) !== undefined;
|
|
89170
|
+
}
|
|
89171
|
+
}
|
|
89172
|
+
exports.NoDynamicStuff = NoDynamicStuff;
|
|
89173
|
+
//# sourceMappingURL=no_dynamic_stuff.js.map
|
|
89174
|
+
|
|
89175
|
+
/***/ },
|
|
89176
|
+
|
|
88575
89177
|
/***/ "./node_modules/@abaplint/core/build/src/rules/no_exclamation_escape.js"
|
|
88576
89178
|
/*!******************************************************************************!*\
|
|
88577
89179
|
!*** ./node_modules/@abaplint/core/build/src/rules/no_exclamation_escape.js ***!
|
|
@@ -99765,6 +100367,64 @@ exports.WhitespaceEnd = WhitespaceEnd;
|
|
|
99765
100367
|
|
|
99766
100368
|
/***/ },
|
|
99767
100369
|
|
|
100370
|
+
/***/ "./node_modules/@abaplint/core/build/src/rules/xml_bom.js"
|
|
100371
|
+
/*!****************************************************************!*\
|
|
100372
|
+
!*** ./node_modules/@abaplint/core/build/src/rules/xml_bom.js ***!
|
|
100373
|
+
\****************************************************************/
|
|
100374
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
100375
|
+
|
|
100376
|
+
"use strict";
|
|
100377
|
+
|
|
100378
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
100379
|
+
exports.XMLBOM = exports.XMLBOMConf = void 0;
|
|
100380
|
+
const edit_helper_1 = __webpack_require__(/*! ../edit_helper */ "./node_modules/@abaplint/core/build/src/edit_helper.js");
|
|
100381
|
+
const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
|
|
100382
|
+
const position_1 = __webpack_require__(/*! ../position */ "./node_modules/@abaplint/core/build/src/position.js");
|
|
100383
|
+
const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
|
|
100384
|
+
const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
|
|
100385
|
+
class XMLBOMConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
100386
|
+
}
|
|
100387
|
+
exports.XMLBOMConf = XMLBOMConf;
|
|
100388
|
+
class XMLBOM {
|
|
100389
|
+
constructor() {
|
|
100390
|
+
this.conf = new XMLBOMConf();
|
|
100391
|
+
}
|
|
100392
|
+
getMetadata() {
|
|
100393
|
+
return {
|
|
100394
|
+
key: "xml_bom",
|
|
100395
|
+
title: "XML UTF-8 byte order mark",
|
|
100396
|
+
shortDescription: "Checks that XML files start with a UTF-8 byte order mark",
|
|
100397
|
+
extendedInformation: "Checks that each XML file has a UTF-8 byte order mark (BOM) at its beginning.",
|
|
100398
|
+
tags: [_irule_1.RuleTag.Syntax, _irule_1.RuleTag.Quickfix],
|
|
100399
|
+
};
|
|
100400
|
+
}
|
|
100401
|
+
getConfig() {
|
|
100402
|
+
return this.conf;
|
|
100403
|
+
}
|
|
100404
|
+
setConfig(conf) {
|
|
100405
|
+
this.conf = conf;
|
|
100406
|
+
}
|
|
100407
|
+
initialize(_reg) {
|
|
100408
|
+
return this;
|
|
100409
|
+
}
|
|
100410
|
+
run(obj) {
|
|
100411
|
+
const file = obj.getXMLFile();
|
|
100412
|
+
if (file === undefined || file.getRaw().startsWith("\uFEFF")) {
|
|
100413
|
+
return [];
|
|
100414
|
+
}
|
|
100415
|
+
return [this.createIssue(file)];
|
|
100416
|
+
}
|
|
100417
|
+
createIssue(file) {
|
|
100418
|
+
const start = new position_1.Position(1, 1);
|
|
100419
|
+
const fix = edit_helper_1.EditHelper.insertAt(file, start, "\uFEFF");
|
|
100420
|
+
return issue_1.Issue.atRange(file, start, start, "XML file must start with a UTF-8 byte order mark", this.getMetadata().key, this.conf.severity, fix);
|
|
100421
|
+
}
|
|
100422
|
+
}
|
|
100423
|
+
exports.XMLBOM = XMLBOM;
|
|
100424
|
+
//# sourceMappingURL=xml_bom.js.map
|
|
100425
|
+
|
|
100426
|
+
/***/ },
|
|
100427
|
+
|
|
99768
100428
|
/***/ "./node_modules/@abaplint/core/build/src/rules/xml_consistency.js"
|
|
99769
100429
|
/*!************************************************************************!*\
|
|
99770
100430
|
!*** ./node_modules/@abaplint/core/build/src/rules/xml_consistency.js ***!
|
|
@@ -100497,6 +101157,10 @@ exports.DECLARATION_STUFF = [
|
|
|
100497
101157
|
Statements.DataBegin,
|
|
100498
101158
|
Statements.Constant,
|
|
100499
101159
|
Statements.ConstantBegin,
|
|
101160
|
+
Statements.Static,
|
|
101161
|
+
Statements.StaticBegin,
|
|
101162
|
+
Statements.FieldSymbol,
|
|
101163
|
+
Statements.Ranges,
|
|
100500
101164
|
Statements.Tables,
|
|
100501
101165
|
Statements.Include, // this is not super correct, but anyhow
|
|
100502
101166
|
Statements.Parameter,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/transpiler-cli",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.61",
|
|
4
4
|
"description": "Transpiler - Command Line Interface",
|
|
5
5
|
"funding": "https://github.com/sponsors/larshp",
|
|
6
6
|
"bin": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"author": "abaplint",
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@abaplint/core": "^2.120.
|
|
30
|
+
"@abaplint/core": "^2.120.37",
|
|
31
31
|
"@abaplint/transpiler": "^2.13.60",
|
|
32
32
|
"@types/glob": "^8.1.0",
|
|
33
33
|
"@types/node": "^24.13.3",
|