@abaplint/core 2.120.3 → 2.120.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/abaplint.d.ts +7 -2
- package/build/src/abap/5_syntax/expressions/cond_body.js +1 -1
- package/build/src/abap/5_syntax/expressions/source.js +6 -3
- package/build/src/abap/5_syntax/expressions/switch_body.js +3 -3
- package/build/src/abap/5_syntax/statements/call_transformation.js +2 -1
- package/build/src/abap/5_syntax/statements/catch.js +28 -19
- package/build/src/abap/5_syntax/statements/constant.js +11 -0
- package/build/src/abap/5_syntax/statements/data.js +11 -0
- package/build/src/abap/5_syntax/syntax.js +6 -5
- package/build/src/cds/expressions/cds_aggregate.js +1 -1
- package/build/src/cds/expressions/cds_annotation_simple.js +3 -2
- package/build/src/cds/expressions/cds_association.js +2 -2
- package/build/src/cds/expressions/cds_case.js +1 -1
- package/build/src/cds/expressions/cds_cast.js +1 -1
- package/build/src/cds/expressions/cds_composition.js +3 -2
- package/build/src/cds/expressions/cds_condition.js +1 -1
- package/build/src/cds/expressions/cds_define_custom.js +1 -1
- package/build/src/cds/expressions/cds_define_external_entity.js +2 -2
- package/build/src/cds/expressions/cds_define_hierarchy.js +2 -2
- package/build/src/cds/expressions/cds_define_projection.js +8 -3
- package/build/src/cds/expressions/cds_define_view.js +3 -3
- package/build/src/cds/expressions/cds_element.js +3 -3
- package/build/src/cds/expressions/cds_extend_view.js +12 -2
- package/build/src/cds/expressions/cds_function.js +2 -1
- package/build/src/cds/expressions/cds_function_input.js +3 -2
- package/build/src/cds/expressions/cds_name.js +6 -2
- package/build/src/cds/expressions/cds_parameters_select.js +2 -1
- package/build/src/cds/expressions/cds_paren_select.js +14 -0
- package/build/src/cds/expressions/cds_prefixed_name.js +8 -4
- package/build/src/cds/expressions/cds_relation.js +7 -2
- package/build/src/cds/expressions/cds_select.js +3 -2
- package/build/src/cds/expressions/cds_table_field.js +4 -5
- package/build/src/cds/expressions/cds_with_parameters.js +3 -1
- package/build/src/cds/expressions/index.js +1 -0
- package/build/src/registry.js +1 -1
- package/build/src/rules/unused_variables.js +60 -53
- package/package.json +1 -1
package/build/abaplint.d.ts
CHANGED
|
@@ -1024,6 +1024,10 @@ declare class CDSParametersSelect extends Expression {
|
|
|
1024
1024
|
getRunnable(): IStatementRunnable;
|
|
1025
1025
|
}
|
|
1026
1026
|
|
|
1027
|
+
declare class CDSParenSelect extends Expression {
|
|
1028
|
+
getRunnable(): IStatementRunnable;
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1027
1031
|
export declare class CDSParser {
|
|
1028
1032
|
parse(file: IFile | undefined): ExpressionNode | undefined;
|
|
1029
1033
|
}
|
|
@@ -2767,6 +2771,7 @@ declare namespace ExpressionsCDS {
|
|
|
2767
2771
|
CDSDefineProjection,
|
|
2768
2772
|
CDSDefineTableEntity,
|
|
2769
2773
|
CDSDefineTableFunction,
|
|
2774
|
+
CDSParenSelect,
|
|
2770
2775
|
CDSDefineView,
|
|
2771
2776
|
CDSElement,
|
|
2772
2777
|
CDSExtendView,
|
|
@@ -7845,8 +7850,8 @@ export declare class SyntaxLogic {
|
|
|
7845
7850
|
private issues;
|
|
7846
7851
|
private readonly object;
|
|
7847
7852
|
private readonly reg;
|
|
7848
|
-
private
|
|
7849
|
-
private
|
|
7853
|
+
private scope;
|
|
7854
|
+
private helpers;
|
|
7850
7855
|
constructor(reg: IRegistry, object: ABAPObject);
|
|
7851
7856
|
run(): ISyntaxResult;
|
|
7852
7857
|
private traverseObject;
|
|
@@ -57,7 +57,7 @@ class CondBody {
|
|
|
57
57
|
type = source_1.Source.runSyntax(s, input, targetType);
|
|
58
58
|
}
|
|
59
59
|
else {
|
|
60
|
-
source_1.Source.runSyntax(s, input, targetType);
|
|
60
|
+
source_1.Source.runSyntax(s, input, targetType !== null && targetType !== void 0 ? targetType : type);
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
if (scoped === true) {
|
|
@@ -71,7 +71,7 @@ const assert_error_1 = require("../assert_error");
|
|
|
71
71
|
*/
|
|
72
72
|
// TODO: refactor all these method parameters to objects, this is getting messy
|
|
73
73
|
class Source {
|
|
74
|
-
static runSyntax(node, input, targetType, writeReference = false, allowGenericDeference = false) {
|
|
74
|
+
static runSyntax(node, input, targetType, writeReference = false, allowGenericDeference = false, readReference = true) {
|
|
75
75
|
var _a;
|
|
76
76
|
if (node === undefined) {
|
|
77
77
|
return undefined;
|
|
@@ -117,7 +117,7 @@ class Source {
|
|
|
117
117
|
case "SWITCH":
|
|
118
118
|
{
|
|
119
119
|
const foundType = this.determineType(node, input, targetType);
|
|
120
|
-
const bodyType = switch_body_1.SwitchBody.runSyntax(node.findDirectExpression(Expressions.SwitchBody), input);
|
|
120
|
+
const bodyType = switch_body_1.SwitchBody.runSyntax(node.findDirectExpression(Expressions.SwitchBody), input, foundType);
|
|
121
121
|
if (foundType === undefined || foundType.isGeneric()) {
|
|
122
122
|
this.addIfInferred(node, input, bodyType);
|
|
123
123
|
}
|
|
@@ -249,7 +249,10 @@ class Source {
|
|
|
249
249
|
return undefined;
|
|
250
250
|
}
|
|
251
251
|
let context = new unknown_type_1.UnknownType("todo, Source type");
|
|
252
|
-
const type = [
|
|
252
|
+
const type = [];
|
|
253
|
+
if (readReference) {
|
|
254
|
+
type.push(_reference_1.ReferenceType.DataReadReference);
|
|
255
|
+
}
|
|
253
256
|
if (writeReference) {
|
|
254
257
|
type.push(_reference_1.ReferenceType.DataWriteReference);
|
|
255
258
|
}
|
|
@@ -39,7 +39,7 @@ const source_1 = require("./source");
|
|
|
39
39
|
const _syntax_input_1 = require("../_syntax_input");
|
|
40
40
|
const basic_1 = require("../../types/basic");
|
|
41
41
|
class SwitchBody {
|
|
42
|
-
static runSyntax(node, input) {
|
|
42
|
+
static runSyntax(node, input, targetType) {
|
|
43
43
|
if (node === undefined) {
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
@@ -49,12 +49,12 @@ class SwitchBody {
|
|
|
49
49
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
50
50
|
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
51
51
|
}
|
|
52
|
-
const type = source_1.Source.runSyntax(thenSource, input);
|
|
52
|
+
const type = source_1.Source.runSyntax(thenSource, input, targetType);
|
|
53
53
|
for (const s of node.findDirectExpressions(Expressions.Source)) {
|
|
54
54
|
if (s === thenSource) {
|
|
55
55
|
continue;
|
|
56
56
|
}
|
|
57
|
-
source_1.Source.runSyntax(s, input);
|
|
57
|
+
source_1.Source.runSyntax(s, input, targetType !== null && targetType !== void 0 ? targetType : type);
|
|
58
58
|
}
|
|
59
59
|
return type;
|
|
60
60
|
}
|
|
@@ -45,7 +45,8 @@ class CallTransformation {
|
|
|
45
45
|
const resultParameters = node.findExpressionAfterToken("RESULT");
|
|
46
46
|
const resultSources = new Set((resultParameters === null || resultParameters === void 0 ? void 0 : resultParameters.findAllExpressions(Expressions.SimpleSource3)) || []);
|
|
47
47
|
for (const s of node.findAllExpressions(Expressions.SimpleSource3)) {
|
|
48
|
-
|
|
48
|
+
const isResult = resultSources.has(s);
|
|
49
|
+
source_1.Source.runSyntax(s, input, undefined, isResult, false, isResult === false);
|
|
49
50
|
}
|
|
50
51
|
for (const d of node.findAllExpressions(Expressions.Dynamic)) {
|
|
51
52
|
dynamic_1.Dynamic.runSyntax(d, input);
|
|
@@ -36,7 +36,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.Catch = void 0;
|
|
37
37
|
const Expressions = __importStar(require("../../2_statements/expressions"));
|
|
38
38
|
const _typed_identifier_1 = require("../../types/_typed_identifier");
|
|
39
|
-
const unknown_type_1 = require("../../types/basic/unknown_type");
|
|
40
39
|
const basic_1 = require("../../types/basic");
|
|
41
40
|
const target_1 = require("../expressions/target");
|
|
42
41
|
const _reference_1 = require("../_reference");
|
|
@@ -44,7 +43,7 @@ const _syntax_input_1 = require("../_syntax_input");
|
|
|
44
43
|
const _type_utils_1 = require("../_type_utils");
|
|
45
44
|
class Catch {
|
|
46
45
|
runSyntax(node, input) {
|
|
47
|
-
var _a
|
|
46
|
+
var _a;
|
|
48
47
|
const names = new Set();
|
|
49
48
|
for (const c of node.findDirectExpressions(Expressions.ClassName)) {
|
|
50
49
|
const token = c.getFirstToken();
|
|
@@ -60,7 +59,6 @@ class Catch {
|
|
|
60
59
|
else {
|
|
61
60
|
const message = "CATCH, unknown class " + className;
|
|
62
61
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, token, message));
|
|
63
|
-
return;
|
|
64
62
|
}
|
|
65
63
|
if (names.has(className)) {
|
|
66
64
|
const message = "Duplicate class name in CATCH: " + className;
|
|
@@ -70,23 +68,18 @@ class Catch {
|
|
|
70
68
|
names.add(className);
|
|
71
69
|
}
|
|
72
70
|
const target = node.findDirectExpression(Expressions.Target);
|
|
73
|
-
const firstClassName = (_a = node.findDirectExpression(Expressions.ClassName)) === null || _a === void 0 ? void 0 : _a.getFirstToken().getStr();
|
|
74
71
|
if (target === null || target === void 0 ? void 0 : target.findDirectExpression(Expressions.InlineData)) {
|
|
75
|
-
const token = (
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
else if (token) {
|
|
88
|
-
const message = "Catch, could not determine type for \"" + token.getStr() + "\"";
|
|
89
|
-
const identifier = new _typed_identifier_1.TypedIdentifier(token, input.filename, new unknown_type_1.UnknownType(message), ["inline" /* IdentifierMeta.InlineDefinition */]);
|
|
72
|
+
const token = (_a = target.findFirstExpression(Expressions.TargetField)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
|
|
73
|
+
if (token) {
|
|
74
|
+
const classNames = Array.from(names);
|
|
75
|
+
const unknownClass = classNames.find(name => input.scope.findClassDefinition(name) === undefined);
|
|
76
|
+
const commonSuperclass = unknownClass === undefined
|
|
77
|
+
? this.findCommonSuperclass(classNames, input)
|
|
78
|
+
: undefined;
|
|
79
|
+
const type = commonSuperclass
|
|
80
|
+
? new basic_1.ObjectReferenceType(commonSuperclass)
|
|
81
|
+
: basic_1.VoidType.get(unknownClass || classNames.join(" "));
|
|
82
|
+
const identifier = new _typed_identifier_1.TypedIdentifier(token, input.filename, type, ["inline" /* IdentifierMeta.InlineDefinition */]);
|
|
90
83
|
input.scope.addIdentifier(identifier);
|
|
91
84
|
input.scope.addReference(token, identifier, _reference_1.ReferenceType.DataWriteReference, input.filename);
|
|
92
85
|
}
|
|
@@ -110,6 +103,22 @@ class Catch {
|
|
|
110
103
|
}
|
|
111
104
|
}
|
|
112
105
|
}
|
|
106
|
+
findCommonSuperclass(classNames, input) {
|
|
107
|
+
var _a;
|
|
108
|
+
const lineages = [];
|
|
109
|
+
for (const className of classNames) {
|
|
110
|
+
const lineage = [];
|
|
111
|
+
let current = input.scope.findClassDefinition(className);
|
|
112
|
+
const visited = new Set();
|
|
113
|
+
while (current && visited.has(current.getName().toUpperCase()) === false) {
|
|
114
|
+
lineage.push(current);
|
|
115
|
+
visited.add(current.getName().toUpperCase());
|
|
116
|
+
current = input.scope.findClassDefinition(current.getSuperClass());
|
|
117
|
+
}
|
|
118
|
+
lineages.push(lineage);
|
|
119
|
+
}
|
|
120
|
+
return (_a = lineages[0]) === null || _a === void 0 ? void 0 : _a.find(candidate => lineages.every(lineage => lineage.some(item => item.getName().toUpperCase() === candidate.getName().toUpperCase())));
|
|
121
|
+
}
|
|
113
122
|
}
|
|
114
123
|
exports.Catch = Catch;
|
|
115
124
|
//# sourceMappingURL=catch.js.map
|
|
@@ -53,6 +53,10 @@ class Constant {
|
|
|
53
53
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, found.getToken(), message));
|
|
54
54
|
return new _typed_identifier_1.TypedIdentifier(found.getToken(), input.filename, basic_2.VoidType.get(_syntax_input_1.CheckSyntaxKey), meta, val);
|
|
55
55
|
}
|
|
56
|
+
if (this.isNameTooLong(found.getName())) {
|
|
57
|
+
const message = "CONSTANTS name too long, " + found.getName();
|
|
58
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, found.getToken(), message));
|
|
59
|
+
}
|
|
56
60
|
return new _typed_identifier_1.TypedIdentifier(found.getToken(), input.filename, found.getType(), meta, val);
|
|
57
61
|
}
|
|
58
62
|
const fallback = node.findFirstExpression(Expressions.DefinitionName);
|
|
@@ -61,10 +65,17 @@ class Constant {
|
|
|
61
65
|
const message = "not possible to have a name with only digits";
|
|
62
66
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, fallback.getFirstToken(), message));
|
|
63
67
|
}
|
|
68
|
+
if (this.isNameTooLong(fallback.concatTokens())) {
|
|
69
|
+
const message = "CONSTANTS name too long, " + fallback.concatTokens();
|
|
70
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, fallback.getFirstToken(), message));
|
|
71
|
+
}
|
|
64
72
|
return new _typed_identifier_1.TypedIdentifier(fallback.getFirstToken(), input.filename, new basic_1.UnknownType("constant, fallback"));
|
|
65
73
|
}
|
|
66
74
|
throw new assert_error_1.AssertError("Statement Constant: unexpected structure");
|
|
67
75
|
}
|
|
76
|
+
isNameTooLong(name) {
|
|
77
|
+
return name.length > 30;
|
|
78
|
+
}
|
|
68
79
|
isOnlyDigits(name) {
|
|
69
80
|
return /^[0-9]+$/.test(name);
|
|
70
81
|
}
|
|
@@ -51,6 +51,10 @@ class Data {
|
|
|
51
51
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, id.getToken(), message));
|
|
52
52
|
return new _typed_identifier_1.TypedIdentifier(id.getToken(), input.filename, basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey));
|
|
53
53
|
}
|
|
54
|
+
if (id && this.isNameTooLong(id.getName())) {
|
|
55
|
+
const message = "DATA name too long, " + id.getName();
|
|
56
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, id.getToken(), message));
|
|
57
|
+
}
|
|
54
58
|
if ((id === null || id === void 0 ? void 0 : id.getType().isGeneric()) === true
|
|
55
59
|
&& (id === null || id === void 0 ? void 0 : id.getType().containsVoid()) === false) {
|
|
56
60
|
const message = "DATA definition cannot be generic, " + (name === null || name === void 0 ? void 0 : name.concatTokens());
|
|
@@ -64,10 +68,17 @@ class Data {
|
|
|
64
68
|
const message = "not possible to have a name with only digits";
|
|
65
69
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, name.getFirstToken(), message));
|
|
66
70
|
}
|
|
71
|
+
if (this.isNameTooLong(name.concatTokens())) {
|
|
72
|
+
const message = "DATA name too long, " + name.concatTokens();
|
|
73
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, name.getFirstToken(), message));
|
|
74
|
+
}
|
|
67
75
|
return new _typed_identifier_1.TypedIdentifier(name.getFirstToken(), input.filename, new unknown_type_1.UnknownType("data, fallback"));
|
|
68
76
|
}
|
|
69
77
|
return undefined;
|
|
70
78
|
}
|
|
79
|
+
isNameTooLong(name) {
|
|
80
|
+
return name.length > 30;
|
|
81
|
+
}
|
|
71
82
|
isOnlyDigits(name) {
|
|
72
83
|
return /^[0-9]+$/.test(name);
|
|
73
84
|
}
|
|
@@ -335,16 +335,17 @@ class SyntaxLogic {
|
|
|
335
335
|
this.reg = reg;
|
|
336
336
|
this.issues = [];
|
|
337
337
|
this.object = object;
|
|
338
|
-
this.scope = _current_scope_1.CurrentScope.buildDefault(this.reg, object);
|
|
339
|
-
this.helpers = {
|
|
340
|
-
oooc: new _object_oriented_1.ObjectOriented(this.scope),
|
|
341
|
-
proc: new _procedural_1.Procedural(this.reg, this.scope),
|
|
342
|
-
};
|
|
343
338
|
}
|
|
344
339
|
run() {
|
|
345
340
|
if (this.object.syntaxResult !== undefined) {
|
|
346
341
|
return this.object.syntaxResult;
|
|
347
342
|
}
|
|
343
|
+
// the scope is built here instead of in the constructor, cached results must stay cheap
|
|
344
|
+
this.scope = _current_scope_1.CurrentScope.buildDefault(this.reg, this.object);
|
|
345
|
+
this.helpers = {
|
|
346
|
+
oooc: new _object_oriented_1.ObjectOriented(this.scope),
|
|
347
|
+
proc: new _procedural_1.Procedural(this.reg, this.scope),
|
|
348
|
+
};
|
|
348
349
|
this.issues = [];
|
|
349
350
|
this.reg.getDDICReferences().clear(this.object);
|
|
350
351
|
this.reg.getMSAGReferences().clear(this.object);
|
|
@@ -7,7 +7,7 @@ class CDSAggregate extends combi_1.Expression {
|
|
|
7
7
|
getRunnable() {
|
|
8
8
|
const fieldAsType = (0, combi_1.seq)(_1.CDSPrefixedName, "AS", _1.CDSType);
|
|
9
9
|
const funcAsType = (0, combi_1.seq)(_1.CDSFunction, "AS", _1.CDSType);
|
|
10
|
-
const value = (0, combi_1.altPrio)(_1.CDSArithmetics, _1.CDSCast, _1.CDSCase, funcAsType, _1.CDSFunction, fieldAsType, _1.CDSPrefixedName, _1.CDSString, "*");
|
|
10
|
+
const value = (0, combi_1.altPrio)(_1.CDSArithmetics, _1.CDSArithParen, _1.CDSCast, _1.CDSCase, funcAsType, _1.CDSFunction, fieldAsType, _1.CDSPrefixedName, _1.CDSString, "*");
|
|
11
11
|
return (0, combi_1.seq)((0, combi_1.altPrio)("MAX", "MIN", "SUM", "AVG", "COUNT"), "(", (0, combi_1.optPrio)((0, combi_1.altPrio)("DISTINCT", "ALL")), value, (0, combi_1.opt)((0, combi_1.seq)("AS", _1.CDSType)), ")");
|
|
12
12
|
}
|
|
13
13
|
}
|
|
@@ -8,9 +8,10 @@ class CDSAnnotationSimple extends combi_1.Expression {
|
|
|
8
8
|
getRunnable() {
|
|
9
9
|
const ident = (0, combi_1.regex)(/^[\w_]+$/);
|
|
10
10
|
// #(expr) where expr can be: identifier, dotted path, string, or concatenation with +
|
|
11
|
-
const
|
|
11
|
+
const funcCall = (0, combi_1.seq)(ident, "(", (0, combi_1.altPrio)(_1.CDSString, cds_prefixed_name_1.CDSPrefixedName, ident), ")");
|
|
12
|
+
const hashArg = (0, combi_1.altPrio)(_1.CDSString, funcCall, cds_prefixed_name_1.CDSPrefixedName, ident);
|
|
12
13
|
const hashExpr = (0, combi_1.seq)(hashArg, (0, combi_1.starPrio)((0, combi_1.seq)("+", hashArg)));
|
|
13
|
-
const value = (0, combi_1.altPrio)(_1.CDSString, "true", "false", "null", (0, combi_1.seq)("-", (0, combi_1.regex)(/^\d+$/), ".", (0, combi_1.regex)(/^\d+$/)), (0, combi_1.seq)("-", (0, combi_1.regex)(/^\d+$/)), (0, combi_1.seq)((0, combi_1.regex)(/^\d+$/), ".", (0, combi_1.regex)(/^\d+$/)), (0, combi_1.regex)(/^\d+$/), (0, combi_1.seq)("#", "(", hashExpr, ")"), (0, combi_1.regex)(/^#[\w_]+$/));
|
|
14
|
+
const value = (0, combi_1.altPrio)(_1.CDSString, "true", "false", "null", (0, combi_1.seq)("-", (0, combi_1.regex)(/^\d+$/), ".", (0, combi_1.regex)(/^\d+[eE]$/), (0, combi_1.altPrio)("+", "-"), (0, combi_1.regex)(/^\d+$/)), (0, combi_1.seq)((0, combi_1.regex)(/^\d+$/), ".", (0, combi_1.regex)(/^\d+[eE]$/), (0, combi_1.altPrio)("+", "-"), (0, combi_1.regex)(/^\d+$/)), (0, combi_1.seq)("-", (0, combi_1.regex)(/^\d+$/), ".", (0, combi_1.regex)(/^\d+$/)), (0, combi_1.seq)("-", (0, combi_1.regex)(/^\d+$/)), (0, combi_1.seq)((0, combi_1.regex)(/^\d+$/), ".", (0, combi_1.regex)(/^\d+$/)), (0, combi_1.regex)(/^\d+$/), (0, combi_1.seq)("#", "(", hashExpr, ")"), (0, combi_1.regex)(/^#[\w_]+$/));
|
|
14
15
|
return value;
|
|
15
16
|
}
|
|
16
17
|
}
|
|
@@ -13,9 +13,9 @@ class CDSAssociation extends combi_1.Expression {
|
|
|
13
13
|
const numericCardinality = (0, combi_1.seq)("[", cardNum, (0, combi_1.optPrio)((0, combi_1.seq)(".", ".", cardNum)), "]");
|
|
14
14
|
// Text-based OF form: "association of one to many Target on ..." — text cardinality includes "TO"
|
|
15
15
|
const ofTextSide = (0, combi_1.altPrio)((0, combi_1.seq)("EXACT", "ONE"), "ONE", "MANY");
|
|
16
|
-
const ofTextForm = (0, combi_1.seq)("ASSOCIATION", "OF", ofTextSide, "TO", ofTextSide, _1.CDSRelation, "ON", _1.CDSCondition);
|
|
16
|
+
const ofTextForm = (0, combi_1.seq)("ASSOCIATION", "OF", ofTextSide, "TO", ofTextSide, _1.CDSRelation, "ON", _1.CDSCondition, (0, combi_1.opt)((0, combi_1.seq)("WITH", "DEFAULT", "FILTER", _1.CDSCondition)));
|
|
17
17
|
// Numeric OF form: "association of [0..1] to Target on ..."
|
|
18
|
-
const ofNumericForm = (0, combi_1.seq)("ASSOCIATION", "OF", numericCardinality, "TO", _1.CDSRelation, "ON", _1.CDSCondition);
|
|
18
|
+
const ofNumericForm = (0, combi_1.seq)("ASSOCIATION", "OF", numericCardinality, "TO", _1.CDSRelation, "ON", _1.CDSCondition, (0, combi_1.opt)((0, combi_1.seq)("WITH", "DEFAULT", "FILTER", _1.CDSCondition)));
|
|
19
19
|
// "association [0..1] to Target as _Alias on condition" — standard form
|
|
20
20
|
const parentForm = (0, combi_1.seq)("ASSOCIATION", "TO", "PARENT", _1.CDSRelation);
|
|
21
21
|
const standardForm = (0, combi_1.seq)("ASSOCIATION", (0, combi_1.optPrio)(cds_cardinality_1.CDSCardinality), "TO", (0, combi_1.opt)((0, combi_1.altPrio)(textCardinality, "PARENT")), _1.CDSRelation, "ON", _1.CDSCondition, (0, combi_1.opt)((0, combi_1.seq)("WITH", "DEFAULT", "FILTER", _1.CDSCondition)));
|
|
@@ -11,7 +11,7 @@ class CDSCase extends combi_1.Expression {
|
|
|
11
11
|
// CDSArithmetics is still tried after for arithmetic like (-1)*Amount or (2*A)-B.
|
|
12
12
|
const caseParen = (0, combi_1.seq)("(", CDSCase, ")");
|
|
13
13
|
const value = (0, combi_1.altPrio)(_1.CDSString, CDSCase, caseParen, _1.CDSArithmetics, _1.CDSCast, _1.CDSAggregate, _1.CDSArithParen, _1.CDSFunction, _1.CDSInteger, _1.CDSPrefixedName);
|
|
14
|
-
const simple = (0, combi_1.seq)((0, combi_1.altPrio)(_1.CDSArithmetics, _1.CDSArithParen, _1.CDSAggregate, _1.CDSFunction, _1.CDSPrefixedName), (0, combi_1.plusPrio)((0, combi_1.seq)("WHEN", value, "THEN", value)));
|
|
14
|
+
const simple = (0, combi_1.seq)((0, combi_1.altPrio)(_1.CDSString, _1.CDSCast, _1.CDSArithmetics, _1.CDSArithParen, _1.CDSAggregate, _1.CDSFunction, _1.CDSPrefixedName), (0, combi_1.plusPrio)((0, combi_1.seq)("WHEN", value, "THEN", value)));
|
|
15
15
|
const complex = (0, combi_1.plusPrio)((0, combi_1.seq)("WHEN", _1.CDSCondition, "THEN", value));
|
|
16
16
|
return (0, combi_1.seq)("CASE", (0, combi_1.altPrio)(complex, simple), (0, combi_1.optPrio)((0, combi_1.seq)("ELSE", value)), "END");
|
|
17
17
|
}
|
|
@@ -6,7 +6,7 @@ const combi_1 = require("../../abap/2_statements/combi");
|
|
|
6
6
|
class CDSCast extends combi_1.Expression {
|
|
7
7
|
getRunnable() {
|
|
8
8
|
// CDSArithmetics before CDSFunction/CDSAggregate: handles function()*n, cast()*n, sum()*n patterns
|
|
9
|
-
const first = (0, combi_1.altPrio)(_1.CDSArithmetics, _1.CDSFunction, _1.CDSArithParen, _1.CDSCase, _1.CDSAggregate, CDSCast, _1.
|
|
9
|
+
const first = (0, combi_1.altPrio)(_1.CDSArithmetics, _1.CDSFunction, _1.CDSArithParen, _1.CDSCase, _1.CDSAggregate, CDSCast, _1.CDSInteger, _1.CDSString, _1.CDSPrefixedName);
|
|
10
10
|
return (0, combi_1.seq)("CAST", "(", first, "AS", _1.CDSType, (0, combi_1.optPrio)((0, combi_1.seq)("PRESERVING", "TYPE")), ")");
|
|
11
11
|
}
|
|
12
12
|
}
|
|
@@ -7,8 +7,9 @@ const cds_cardinality_1 = require("./cds_cardinality");
|
|
|
7
7
|
class CDSComposition extends combi_1.Expression {
|
|
8
8
|
getRunnable() {
|
|
9
9
|
const num = (0, combi_1.altPrio)("ONE", "MANY");
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
const exactNum = (0, combi_1.seq)((0, combi_1.opt)("EXACT"), num);
|
|
11
|
+
// Text cardinality after OF: "of exact one to exact one", "of exact one to many", "of one to many", or bare "of many" / "of one"
|
|
12
|
+
const textCardinality = (0, combi_1.altPrio)((0, combi_1.seq)(exactNum, "TO", exactNum), (0, combi_1.seq)((0, combi_1.opt)("EXACT"), num));
|
|
12
13
|
// Numeric cardinality [n..m] before OF: any non-negative integer or *
|
|
13
14
|
const cardNum = (0, combi_1.altPrio)((0, combi_1.regex)(/^\d+$/), "*");
|
|
14
15
|
const numericCardinality = (0, combi_1.seq)("[", cardNum, (0, combi_1.optPrio)((0, combi_1.seq)(".", ".", cardNum)), "]");
|
|
@@ -8,7 +8,7 @@ class CDSCondition extends combi_1.Expression {
|
|
|
8
8
|
getRunnable() {
|
|
9
9
|
// CDSArithmetics before CDSCast/CDSFunction so cast(A)-cast(B) is handled as arithmetic, not two separate casts
|
|
10
10
|
// CDSCase allows nested case expressions on either side of a comparison
|
|
11
|
-
const left = (0, combi_1.altPrio)(_1.CDSString, _1.CDSArithmetics, _1.CDSCast, _1.CDSFunction, _1.CDSAggregate, _1.CDSCase, _1.CDSArithParen, _1.CDSPrefixedName);
|
|
11
|
+
const left = (0, combi_1.altPrio)(_1.CDSString, _1.CDSArithmetics, _1.CDSCast, _1.CDSFunction, _1.CDSAggregate, _1.CDSCase, _1.CDSArithParen, cds_integer_1.CDSInteger, _1.CDSPrefixedName);
|
|
12
12
|
const nonLikeOperators = (0, combi_1.altPrio)("=", (0, combi_1.seq)("!", "="), (0, combi_1.seq)("<", ">"), (0, combi_1.seq)(">", "="), (0, combi_1.seq)("<", "="), "<", ">");
|
|
13
13
|
const likeOperators = (0, combi_1.altPrio)("LIKE", "NOT LIKE");
|
|
14
14
|
// Right side of comparison: simple values first, then parenthesized, then full arithmetic last.
|
|
@@ -9,7 +9,7 @@ class CDSDefineCustom extends combi_1.Expression {
|
|
|
9
9
|
getRunnable() {
|
|
10
10
|
const field = (0, combi_1.seq)((0, combi_1.optPrio)((0, combi_1.str)("KEY")), cds_name_1.CDSName, ":", cds_type_1.CDSType, ";");
|
|
11
11
|
const compsiOrAssoci = (0, combi_1.seq)(cds_name_1.CDSName, ":", (0, combi_1.alt)(_1.CDSComposition, _1.CDSAssociation), ";");
|
|
12
|
-
return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.opt)("DEFINE"), (0, combi_1.opt)("ROOT"), (0, combi_1.str)("CUSTOM ENTITY"), cds_name_1.CDSName, (0, combi_1.opt)(_1.CDSWithParameters), (0, combi_1.str)("{"), (0, combi_1.plus)((0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.alt)(field, compsiOrAssoci))), (0, combi_1.str)("}"), (0, combi_1.opt)(";"));
|
|
12
|
+
return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.opt)((0, combi_1.str)("DEFINE")), (0, combi_1.opt)((0, combi_1.str)("ROOT")), (0, combi_1.str)("CUSTOM ENTITY"), cds_name_1.CDSName, (0, combi_1.opt)(_1.CDSWithParameters), (0, combi_1.str)("{"), (0, combi_1.plus)((0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.alt)(field, compsiOrAssoci))), (0, combi_1.str)("}"), (0, combi_1.opt)(";"));
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
exports.CDSDefineCustom = CDSDefineCustom;
|
|
@@ -5,7 +5,7 @@ const _1 = require(".");
|
|
|
5
5
|
const combi_1 = require("../../abap/2_statements/combi");
|
|
6
6
|
class CDSDefineExternalEntity extends combi_1.Expression {
|
|
7
7
|
getRunnable() {
|
|
8
|
-
const extNameValue = (0, combi_1.alt)(_1.CDSName, (0, combi_1.regex)(/^"[^"]*"$/));
|
|
8
|
+
const extNameValue = (0, combi_1.alt)(_1.CDSName, (0, combi_1.regex)(/^"(?:[^"]|"")*"$/));
|
|
9
9
|
const externalName = (0, combi_1.seq)("EXTERNAL", "NAME", extNameValue);
|
|
10
10
|
const nullability = (0, combi_1.optPrio)((0, combi_1.alt)("NOT NULL", "NULL"));
|
|
11
11
|
const field = (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.optPrio)((0, combi_1.str)("KEY")), _1.CDSName, ":", _1.CDSType, nullability, (0, combi_1.optPrio)(externalName), ";");
|
|
@@ -13,7 +13,7 @@ class CDSDefineExternalEntity extends combi_1.Expression {
|
|
|
13
13
|
const body = (0, combi_1.plus)((0, combi_1.alt)(field, assocOrComp));
|
|
14
14
|
const externalEntity = (0, combi_1.seq)((0, combi_1.opt)("WRITABLE"), "EXTERNAL", "ENTITY", _1.CDSName, (0, combi_1.opt)(externalName), (0, combi_1.opt)(_1.CDSWithParameters));
|
|
15
15
|
const staticEntity = (0, combi_1.seq)("STATIC", "ENTITY", _1.CDSName, (0, combi_1.opt)(externalName));
|
|
16
|
-
return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.opt)("DEFINE"), (0, combi_1.alt)(externalEntity, staticEntity), (0, combi_1.str)("{"), body, (0, combi_1.str)("}"), (0, combi_1.opt)((0, combi_1.seq)("WITH", "FEDERATED", "DATA", (0, combi_1.optPrio)((0, combi_1.alt)((0, combi_1.seq)("PROVIDED", "AT", "RUNTIME"), (0, combi_1.seq)("PROVIDED", "BY", _1.CDSName))))), (0, combi_1.opt)(";"));
|
|
16
|
+
return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.opt)("DEFINE"), (0, combi_1.opt)("ROOT"), (0, combi_1.alt)(externalEntity, staticEntity), (0, combi_1.str)("{"), body, (0, combi_1.str)("}"), (0, combi_1.opt)((0, combi_1.seq)("WITH", "FEDERATED", "DATA", (0, combi_1.optPrio)((0, combi_1.alt)((0, combi_1.seq)("PROVIDED", "AT", "RUNTIME"), (0, combi_1.seq)("PROVIDED", "BY", _1.CDSName))), (0, combi_1.optPrio)((0, combi_1.seq)("ON", "UNLINKED", (0, combi_1.altPrio)("FAIL", "IGNORE"))))), (0, combi_1.opt)(";"));
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
exports.CDSDefineExternalEntity = CDSDefineExternalEntity;
|
|
@@ -11,10 +11,10 @@ class CDSDefineHierarchy extends combi_1.Expression {
|
|
|
11
11
|
const siblingsOrder = (0, combi_1.seq)("SIBLINGS", "ORDER", "BY", siblingsOrderField, (0, combi_1.star)((0, combi_1.seq)(",", siblingsOrderField)));
|
|
12
12
|
const directory = (0, combi_1.seq)("DIRECTORY", _1.CDSName, "FILTER", "BY", _1.CDSCondition);
|
|
13
13
|
// DATE PERIOD: period from <field> to <field> [valid from :p to :p]
|
|
14
|
-
const datePeriod = (0, combi_1.seq)("PERIOD", "FROM", _1.CDSName, "TO", _1.CDSName, (0, combi_1.opt)((0, combi_1.seq)("VALID", "FROM", _1.CDSPrefixedName, "TO", _1.CDSPrefixedName)));
|
|
14
|
+
const datePeriod = (0, combi_1.seq)("PERIOD", "FROM", _1.CDSName, "TO", _1.CDSName, (0, combi_1.opt)((0, combi_1.seq)("VALID", "FROM", (0, combi_1.altPrio)(_1.CDSString, _1.CDSPrefixedName), "TO", (0, combi_1.altPrio)(_1.CDSString, _1.CDSPrefixedName))));
|
|
15
15
|
const depthValue = (0, combi_1.altPrio)(_1.CDSString, _1.CDSInteger, _1.CDSPrefixedName);
|
|
16
16
|
const loadMode = (0, combi_1.altPrio)("BULK", "INCREMENTAL", _1.CDSPrefixedName);
|
|
17
|
-
const hierarchyBody = (0, combi_1.seq)("SOURCE", _1.CDSName, (0, combi_1.opt)(_1.CDSParametersSelect), "CHILD", "TO", "PARENT", "ASSOCIATION", _1.CDSName, (0, combi_1.opt)(directory), (0, combi_1.opt)(datePeriod), (0, combi_1.opt)((0, combi_1.seq)("START", "WHERE", _1.CDSCondition)), (0, combi_1.opt)(siblingsOrder), (0, combi_1.opt)((0, combi_1.seq)("
|
|
17
|
+
const hierarchyBody = (0, combi_1.seq)("SOURCE", _1.CDSName, (0, combi_1.opt)(_1.CDSParametersSelect), "CHILD", "TO", "PARENT", "ASSOCIATION", _1.CDSName, (0, combi_1.opt)((0, combi_1.altPrio)((0, combi_1.seq)((0, combi_1.opt)(directory), datePeriod, (0, combi_1.opt)(directory)), (0, combi_1.seq)(datePeriod, (0, combi_1.opt)(directory)), directory)), (0, combi_1.opt)((0, combi_1.seq)("START", "WHERE", _1.CDSCondition)), (0, combi_1.opt)(siblingsOrder), (0, combi_1.opt)((0, combi_1.seq)("DEPTH", depthValue)), (0, combi_1.opt)((0, combi_1.seq)("NODETYPE", _1.CDSName)), (0, combi_1.opt)((0, combi_1.seq)("LOAD", loadMode)), (0, combi_1.opt)((0, combi_1.seq)("MULTIPLE", "PARENTS", (0, combi_1.altPrio)("NOT ALLOWED", "ALLOWED", (0, combi_1.seq)("LEAVES", (0, combi_1.optPrio)("ONLY"))))), (0, combi_1.opt)((0, combi_1.seq)("ORPHANS", (0, combi_1.altPrio)("IGNORE", "ROOT", "ERROR"))), (0, combi_1.opt)((0, combi_1.seq)("CYCLES", (0, combi_1.altPrio)("BREAKUP", "ERROR"))), (0, combi_1.opt)((0, combi_1.seq)("GENERATE", "SPANTREE")), (0, combi_1.opt)((0, combi_1.seq)("CACHE", (0, combi_1.altPrio)("ON", "OFF", "FORCE"))));
|
|
18
18
|
return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.opt)("DEFINE"), "HIERARCHY", _1.CDSName, (0, combi_1.opt)(_1.CDSWithParameters), "AS", "PARENT", "CHILD", "HIERARCHY", "(", hierarchyBody, ")", "{", (0, combi_1.seq)(field, (0, combi_1.star)((0, combi_1.seq)(",", field))), "}", (0, combi_1.opt)(";"));
|
|
19
19
|
}
|
|
20
20
|
}
|
|
@@ -6,9 +6,14 @@ const __1 = require("../..");
|
|
|
6
6
|
const combi_1 = require("../../abap/2_statements/combi");
|
|
7
7
|
class CDSDefineProjection extends combi_1.Expression {
|
|
8
8
|
getRunnable() {
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
9
|
+
const redefineCard = (0, combi_1.altPrio)("EXACT ONE TO EXACT ONE", "EXACT ONE TO MANY", "EXACT ONE TO ONE", "MANY TO EXACT ONE", "MANY TO MANY", "MANY TO ONE", "ONE TO EXACT ONE", "ONE TO MANY", "ONE TO ONE", "TO EXACT ONE", "TO ONE", "TO MANY", _1.CDSInteger, "*");
|
|
10
|
+
const redefineAssocFilter = (0, combi_1.seq)("[", (0, combi_1.optPrio)((0, combi_1.seq)(redefineCard, ":")), _1.CDSCondition, "]");
|
|
11
|
+
const redefineAssoc = (0, combi_1.seq)("REDEFINE", "ASSOCIATION", _1.CDSPrefixedName, (0, combi_1.optPrio)(redefineAssocFilter), (0, combi_1.opt)(_1.CDSAs), "REDIRECTED", "TO", (0, combi_1.optPrio)((0, combi_1.altPrio)((0, combi_1.seq)("COMPOSITION", "CHILD"), "PARENT")), _1.CDSName);
|
|
12
|
+
const typedLiteralVal = (0, combi_1.seq)(_1.CDSType, _1.CDSString);
|
|
13
|
+
const aspectValue = (0, combi_1.altPrio)(typedLiteralVal, _1.CDSString, _1.CDSPrefixedName);
|
|
14
|
+
const aspectBinding = (0, combi_1.seq)(_1.CDSPrefixedName, "=", ">", aspectValue);
|
|
15
|
+
const bindAspect = (0, combi_1.seq)("BIND", "ASPECT", _1.CDSName, "(", aspectBinding, (0, combi_1.starPrio)((0, combi_1.seq)(",", aspectBinding)), ")", (0, combi_1.optPrio)((0, combi_1.seq)("AS", _1.CDSName)));
|
|
16
|
+
return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.opt)("DEFINE"), (0, combi_1.opt)("TRANSIENT"), (0, combi_1.opt)("ROOT"), "VIEW", (0, combi_1.ver)(__1.Release.v755, (0, combi_1.opt)("ENTITY")), _1.CDSName, (0, combi_1.opt)(_1.CDSProviderContract), (0, combi_1.opt)(_1.CDSWithParameters), "AS PROJECTION ON", _1.CDSName, (0, combi_1.opt)(_1.CDSParametersSelect), (0, combi_1.opt)(_1.CDSAs), (0, combi_1.star)((0, combi_1.altPrio)(_1.CDSAssociation, redefineAssoc)), (0, combi_1.starPrio)(bindAspect), (0, combi_1.str)("{"), (0, combi_1.seq)(_1.CDSElement, (0, combi_1.star)((0, combi_1.seq)(",", _1.CDSElement)), (0, combi_1.opt)(",")), (0, combi_1.str)("}"), (0, combi_1.opt)(_1.CDSWhere), (0, combi_1.opt)(";"));
|
|
12
17
|
}
|
|
13
18
|
}
|
|
14
19
|
exports.CDSDefineProjection = CDSDefineProjection;
|
|
@@ -10,9 +10,9 @@ const cds_with_parameters_1 = require("./cds_with_parameters");
|
|
|
10
10
|
class CDSDefineView extends combi_1.Expression {
|
|
11
11
|
getRunnable() {
|
|
12
12
|
const columnAlias = (0, combi_1.seq)("(", cds_name_1.CDSName, (0, combi_1.star)((0, combi_1.seq)(",", cds_name_1.CDSName)), ")");
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const topLevelSelect = (0, combi_1.altPrio)((0, combi_1.seq)(
|
|
13
|
+
const unionBranch = (0, combi_1.altPrio)(_1.CDSParenSelect, cds_select_1.CDSSelect);
|
|
14
|
+
const unionOps = (0, combi_1.star)((0, combi_1.altPrio)((0, combi_1.seq)("UNION", (0, combi_1.opt)("ALL"), unionBranch), (0, combi_1.seq)("EXCEPT", unionBranch), (0, combi_1.seq)("INTERSECT", unionBranch)));
|
|
15
|
+
const topLevelSelect = (0, combi_1.altPrio)((0, combi_1.seq)(_1.CDSParenSelect, unionOps), (0, combi_1.seq)(cds_select_1.CDSSelect, unionOps));
|
|
16
16
|
return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.opt)("DEFINE"), (0, combi_1.opt)("ROOT"), (0, combi_1.opt)("WRITABLE"), "VIEW", (0, combi_1.ver)(__1.Release.v755, (0, combi_1.opt)("ENTITY")), cds_name_1.CDSName, (0, combi_1.opt)(columnAlias), (0, combi_1.opt)(cds_with_parameters_1.CDSWithParameters), "AS", topLevelSelect, (0, combi_1.opt)((0, combi_1.seq)("WITH", "HIERARCHY", cds_name_1.CDSName)), (0, combi_1.opt)(";"));
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -7,16 +7,16 @@ const cds_as_1 = require("./cds_as");
|
|
|
7
7
|
const cds_cast_1 = require("./cds_cast");
|
|
8
8
|
class CDSElement extends combi_1.Expression {
|
|
9
9
|
getRunnable() {
|
|
10
|
-
const redirected = (0, combi_1.seq)(": REDIRECTED TO", (0, combi_1.optPrio)((0, combi_1.altPrio)("PARENT", "COMPOSITION CHILD")), _1.CDSName);
|
|
10
|
+
const redirected = (0, combi_1.seq)(": REDIRECTED TO", (0, combi_1.optPrio)((0, combi_1.altPrio)("PARENT", "COMPOSITION CHILD")), _1.CDSName, (0, combi_1.optPrio)(_1.CDSParametersSelect));
|
|
11
11
|
const colonThing = (0, combi_1.seq)(":", (0, combi_1.altPrio)(_1.CDSType, _1.CDSName, "LOCALIZED"));
|
|
12
12
|
const extensionWildcard = (0, combi_1.seq)("$extension", ".", "*");
|
|
13
13
|
const excludingNames = (0, combi_1.seq)(_1.CDSName, (0, combi_1.starPrio)((0, combi_1.seq)(",", _1.CDSName)));
|
|
14
14
|
const excluding = (0, combi_1.seq)("EXCLUDING", "{", excludingNames, "}");
|
|
15
|
-
const includeElement = (0, combi_1.seq)("INCLUDE", _1.CDSPrefixedName, (0, combi_1.optPrio)(excluding), (0, combi_1.optPrio)("SIGNATURE ONLY"));
|
|
15
|
+
const includeElement = (0, combi_1.seq)("INCLUDE", (0, combi_1.stopBefore1)("AS", "KEY", "VIRTUAL", "}"), _1.CDSPrefixedName, (0, combi_1.optPrio)((0, combi_1.altPrio)((0, combi_1.seq)("SIGNATURE ONLY", (0, combi_1.optPrio)(excluding)), (0, combi_1.seq)(excluding, (0, combi_1.optPrio)("SIGNATURE ONLY")))));
|
|
16
16
|
const typedVirtual = (0, combi_1.seq)("VIRTUAL", _1.CDSName, ":", _1.CDSType);
|
|
17
17
|
const pathSegment = (0, combi_1.seq)(".", (0, combi_1.altPrio)(_1.CDSString, _1.CDSName, "*"), (0, combi_1.optPrio)((0, combi_1.altPrio)(_1.CDSParametersSelect, _1.CDSParameters)));
|
|
18
18
|
const funcWithPath = (0, combi_1.seq)(_1.CDSFunction, (0, combi_1.plusPrio)(pathSegment));
|
|
19
|
-
const body = (0, combi_1.altPrio)(extensionWildcard, includeElement, _1.CDSArithmetics, _1.CDSAggregate, _1.CDSString, _1.CDSArithParen, funcWithPath, _1.CDSFunction, cds_cast_1.CDSCast, _1.CDSCase, (0, combi_1.seq)("(", _1.CDSCase, ")"), (0, combi_1.seq)(_1.CDSPrefixedName, (0, combi_1.optPrio)(cds_as_1.CDSAs), (0, combi_1.optPrio)((0, combi_1.altPrio)(redirected, colonThing)))
|
|
19
|
+
const body = (0, combi_1.altPrio)(extensionWildcard, includeElement, _1.CDSArithmetics, _1.CDSAggregate, _1.CDSString, _1.CDSArithParen, funcWithPath, _1.CDSFunction, cds_cast_1.CDSCast, _1.CDSCase, (0, combi_1.seq)("(", _1.CDSCase, ")"), _1.CDSInteger, (0, combi_1.seq)(_1.CDSPrefixedName, (0, combi_1.optPrio)(cds_as_1.CDSAs), (0, combi_1.optPrio)((0, combi_1.altPrio)(redirected, colonThing))));
|
|
20
20
|
const elementBody = (0, combi_1.altPrio)(typedVirtual, (0, combi_1.seq)((0, combi_1.altPrio)("KEY", "VIRTUAL"), body), body);
|
|
21
21
|
return (0, combi_1.seq)((0, combi_1.starPrio)(_1.CDSAnnotation), elementBody, (0, combi_1.optPrio)(cds_as_1.CDSAs), (0, combi_1.starPrio)(_1.CDSAnnotation));
|
|
22
22
|
}
|
|
@@ -7,10 +7,20 @@ class CDSExtendView extends combi_1.Expression {
|
|
|
7
7
|
getRunnable() {
|
|
8
8
|
const namedot = (0, combi_1.seq)(_1.CDSName, (0, combi_1.optPrio)((0, combi_1.seq)(".", _1.CDSName)), (0, combi_1.optPrio)(_1.CDSAs));
|
|
9
9
|
const valueNested = (0, combi_1.seq)("{", namedot, (0, combi_1.star)((0, combi_1.seq)(",", namedot)), "}");
|
|
10
|
-
const
|
|
10
|
+
const redefineCard = (0, combi_1.altPrio)("EXACT ONE TO EXACT ONE", "EXACT ONE TO MANY", "EXACT ONE TO ONE", "MANY TO EXACT ONE", "MANY TO MANY", "MANY TO ONE", "ONE TO EXACT ONE", "ONE TO MANY", "ONE TO ONE", "TO EXACT ONE", "TO ONE", "TO MANY", _1.CDSInteger, "*");
|
|
11
|
+
const redefineAssocFilter = (0, combi_1.seq)("[", (0, combi_1.optPrio)((0, combi_1.seq)(redefineCard, ":")), _1.CDSCondition, "]");
|
|
12
|
+
const redefineAssoc = (0, combi_1.seq)("REDEFINE", "ASSOCIATION", _1.CDSPrefixedName, (0, combi_1.optPrio)(redefineAssocFilter), (0, combi_1.opt)(_1.CDSAs), "REDIRECTED", "TO", (0, combi_1.optPrio)((0, combi_1.altPrio)((0, combi_1.seq)("COMPOSITION", "CHILD"), "PARENT")), _1.CDSName);
|
|
11
13
|
const elementList = (0, combi_1.seq)(_1.CDSElement, (0, combi_1.star)((0, combi_1.seq)(",", _1.CDSElement)), (0, combi_1.opt)(","));
|
|
12
14
|
const elementNested = (0, combi_1.seq)("{", (0, combi_1.altPrio)("*", elementList), "}");
|
|
13
|
-
const
|
|
15
|
+
const unionElemList = (0, combi_1.seq)(_1.CDSElement, (0, combi_1.star)((0, combi_1.seq)(",", _1.CDSElement)), (0, combi_1.opt)(","));
|
|
16
|
+
const unionBranchBody = (0, combi_1.seq)((0, combi_1.star)((0, combi_1.altPrio)(_1.CDSAssociation, _1.CDSComposition)), "{", (0, combi_1.altPrio)("*", unionElemList), "}", (0, combi_1.optPrio)(_1.CDSGroupBy));
|
|
17
|
+
const parenUnionBody = (0, combi_1.seq)("(", (0, combi_1.star)((0, combi_1.altPrio)(_1.CDSAssociation, _1.CDSComposition)), "{", (0, combi_1.seq)(_1.CDSElement, (0, combi_1.star)((0, combi_1.seq)(",", _1.CDSElement)), (0, combi_1.opt)(",")), "}", (0, combi_1.star)((0, combi_1.seq)("UNION", (0, combi_1.opt)("ALL"), (0, combi_1.star)((0, combi_1.altPrio)(_1.CDSAssociation, _1.CDSComposition)), "{", (0, combi_1.seq)(_1.CDSElement, (0, combi_1.star)((0, combi_1.seq)(",", _1.CDSElement)), (0, combi_1.opt)(",")), "}")), ")");
|
|
18
|
+
const unionSuffix = (0, combi_1.seq)((0, combi_1.optPrio)(_1.CDSGroupBy), (0, combi_1.star)((0, combi_1.seq)("UNION", (0, combi_1.opt)("ALL"), (0, combi_1.altPrio)(parenUnionBody, unionBranchBody))));
|
|
19
|
+
const typedLiteralVal = (0, combi_1.seq)(_1.CDSType, _1.CDSString);
|
|
20
|
+
const aspectValue = (0, combi_1.altPrio)(typedLiteralVal, _1.CDSString, _1.CDSPrefixedName);
|
|
21
|
+
const aspectBinding = (0, combi_1.seq)(_1.CDSPrefixedName, "=", ">", aspectValue);
|
|
22
|
+
const bindAspect = (0, combi_1.seq)("BIND", "ASPECT", _1.CDSName, "(", aspectBinding, (0, combi_1.starPrio)((0, combi_1.seq)(",", aspectBinding)), ")", (0, combi_1.optPrio)((0, combi_1.seq)("AS", _1.CDSName)));
|
|
23
|
+
const extendView = (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.str)("EXTEND VIEW"), (0, combi_1.opt)((0, combi_1.str)("ENTITY")), _1.CDSName, (0, combi_1.str)("WITH"), (0, combi_1.opt)(_1.CDSName), (0, combi_1.star)(redefineAssoc), (0, combi_1.star)((0, combi_1.altPrio)(_1.CDSAssociation, _1.CDSComposition)), (0, combi_1.starPrio)(bindAspect), (0, combi_1.altPrio)(parenUnionBody, elementNested, valueNested), unionSuffix, (0, combi_1.opt)(";"));
|
|
14
24
|
const field = (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.optPrio)((0, combi_1.str)("KEY")), _1.CDSName, ":", _1.CDSType, ";");
|
|
15
25
|
const assocOrComp = (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), _1.CDSName, ":", (0, combi_1.alt)(_1.CDSComposition, _1.CDSAssociation), ";");
|
|
16
26
|
const entityBody = (0, combi_1.seq)("{", (0, combi_1.plus)((0, combi_1.alt)(field, assocOrComp)), "}");
|
|
@@ -58,6 +58,7 @@ class CDSFunction extends combi_1.Expression {
|
|
|
58
58
|
const occurrencesRegexpr = (0, combi_1.seq)("OCCURRENCES_REGEXPR", "(", conversionInputs, ")");
|
|
59
59
|
const substrRegexpr = (0, combi_1.seq)("SUBSTR_REGEXPR", "(", conversionInputs, ")");
|
|
60
60
|
const locateRegexpr = (0, combi_1.seq)("LOCATE_REGEXPR", "(", conversionInputs, ")");
|
|
61
|
+
const sqrt = (0, combi_1.seq)("SQRT", "(", _1.CDSFunctionInput, ")");
|
|
61
62
|
const extFuncName = (0, combi_1.regex)(/^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)+$/i);
|
|
62
63
|
const genericArgs = (0, combi_1.seq)(_1.CDSFunctionInput, (0, combi_1.starPrio)((0, combi_1.seq)(",", _1.CDSFunctionInput)));
|
|
63
64
|
const namedArgValue = (0, combi_1.altPrio)((0, combi_1.seq)("INTERVAL", _1.CDSFunctionInput, _1.CDSName), _1.CDSFunctionInput, _1.CDSName);
|
|
@@ -65,7 +66,7 @@ class CDSFunction extends combi_1.Expression {
|
|
|
65
66
|
const namedArgColon = (0, combi_1.seq)(_1.CDSName, ":", namedArgValue);
|
|
66
67
|
const namedArgs = (0, combi_1.seq)((0, combi_1.altPrio)(namedArgArrow, namedArgColon), (0, combi_1.starPrio)((0, combi_1.seq)(",", (0, combi_1.altPrio)(namedArgArrow, namedArgColon))));
|
|
67
68
|
const genericFunc = (0, combi_1.seq)(extFuncName, "(", (0, combi_1.optPrio)((0, combi_1.altPrio)(namedArgs, genericArgs)), ")");
|
|
68
|
-
return (0, combi_1.altPrio)(substring, coalesce, tstmp_to_dats, concat, tstmp_to_tims, upper, lower, abs, ceil, floor, round, div, division, concat_with_space, dats_is_valid, tims_is_valid, dats_days_between, tstmp_add_seconds, tstmp_seconds_between, tstmp_current_utctimestamp, tstmp_is_valid, utcl_current, abap_system_timezone, abap_user_timezone, bintohex, hextobin, dats_add_days, dats_add_months, tstmp_to_dst, dats_tims_to_tstmp, mod, left, right, lpad, rpad, instr, length, ltrim, rtrim, replace, unitConversion, currencyConversion, decimalShift, fltp_to_dec, ratioOf, replaceRegexpr, matchesRegexpr, occurrencesRegexpr, substrRegexpr, locateRegexpr, curr_to_decfloat_amount, genericFunc);
|
|
69
|
+
return (0, combi_1.altPrio)(substring, coalesce, tstmp_to_dats, concat, tstmp_to_tims, upper, lower, abs, ceil, floor, round, div, division, concat_with_space, dats_is_valid, tims_is_valid, dats_days_between, tstmp_add_seconds, tstmp_seconds_between, tstmp_current_utctimestamp, tstmp_is_valid, utcl_current, abap_system_timezone, abap_user_timezone, bintohex, hextobin, dats_add_days, dats_add_months, tstmp_to_dst, dats_tims_to_tstmp, mod, left, right, lpad, rpad, instr, length, ltrim, rtrim, replace, unitConversion, currencyConversion, decimalShift, fltp_to_dec, ratioOf, replaceRegexpr, matchesRegexpr, occurrencesRegexpr, substrRegexpr, locateRegexpr, curr_to_decfloat_amount, sqrt, genericFunc);
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
exports.CDSFunction = CDSFunction;
|
|
@@ -5,8 +5,9 @@ const _1 = require(".");
|
|
|
5
5
|
const combi_1 = require("../../abap/2_statements/combi");
|
|
6
6
|
class CDSFunctionInput extends combi_1.Expression {
|
|
7
7
|
getRunnable() {
|
|
8
|
-
const
|
|
9
|
-
|
|
8
|
+
const positional = (0, combi_1.altPrio)(_1.CDSArithmetics, _1.CDSArithParen, _1.CDSAggregate, _1.CDSCast, _1.CDSFunction, _1.CDSCase, _1.CDSString, _1.CDSPrefixedName, _1.CDSInteger);
|
|
9
|
+
const named = (0, combi_1.seq)(_1.CDSName, "=", ">", positional);
|
|
10
|
+
return (0, combi_1.altPrio)(named, positional);
|
|
10
11
|
}
|
|
11
12
|
}
|
|
12
13
|
exports.CDSFunctionInput = CDSFunctionInput;
|
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CDSName = void 0;
|
|
4
4
|
const combi_1 = require("../../abap/2_statements/combi");
|
|
5
|
+
const KEYWORDS = ["AS", "ON", "WHERE", "WITH", "UNION", "GROUP", "HAVING",
|
|
6
|
+
"AND", "OR", "BETWEEN", "LIKE", "IN", "EXISTS",
|
|
7
|
+
"WHEN", "THEN", "ELSE", "END", "CASE", "CAST"];
|
|
5
8
|
class CDSName extends combi_1.Expression {
|
|
6
9
|
getRunnable() {
|
|
7
|
-
const
|
|
8
|
-
|
|
10
|
+
const word = (0, combi_1.regex)(/^\$?#?[\w_]+$/);
|
|
11
|
+
const slashName = (0, combi_1.seq)("/", (0, combi_1.regex)(/^[\w]+$/), "/", (0, combi_1.stopBefore1)(...KEYWORDS), (0, combi_1.regex)(/^[\w_]+$/));
|
|
12
|
+
return (0, combi_1.altPrio)((0, combi_1.regex)(/^"(?:[^"]|"")*"$/), (0, combi_1.seq)((0, combi_1.optPrio)(":"), slashName), (0, combi_1.seq)((0, combi_1.optPrio)(":"), word));
|
|
9
13
|
}
|
|
10
14
|
}
|
|
11
15
|
exports.CDSName = CDSName;
|
|
@@ -6,7 +6,8 @@ const combi_1 = require("../../abap/2_statements/combi");
|
|
|
6
6
|
class CDSParametersSelect extends combi_1.Expression {
|
|
7
7
|
getRunnable() {
|
|
8
8
|
const name = (0, combi_1.seq)(_1.CDSName, (0, combi_1.opt)((0, combi_1.seq)(".", _1.CDSName)));
|
|
9
|
-
const
|
|
9
|
+
const typedLiteral = (0, combi_1.seq)(_1.CDSType, _1.CDSString);
|
|
10
|
+
const value = (0, combi_1.altPrio)(typedLiteral, _1.CDSInteger, name, _1.CDSString);
|
|
10
11
|
const colonPair = (0, combi_1.seq)(name, ":", value, (0, combi_1.optPrio)("DEFAULT"));
|
|
11
12
|
const arrowPair = (0, combi_1.seq)(name, "=", ">", value);
|
|
12
13
|
const nameValue = (0, combi_1.altPrio)(colonPair, arrowPair);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CDSParenSelect = void 0;
|
|
4
|
+
const _1 = require(".");
|
|
5
|
+
const combi_1 = require("../../abap/2_statements/combi");
|
|
6
|
+
class CDSParenSelect extends combi_1.Expression {
|
|
7
|
+
getRunnable() {
|
|
8
|
+
const unionBranch = (0, combi_1.altPrio)(CDSParenSelect, _1.CDSSelect);
|
|
9
|
+
const unionOps = (0, combi_1.star)((0, combi_1.altPrio)((0, combi_1.seq)("UNION", (0, combi_1.opt)("ALL"), unionBranch), (0, combi_1.seq)("EXCEPT", unionBranch), (0, combi_1.seq)("INTERSECT", unionBranch)));
|
|
10
|
+
return (0, combi_1.seq)("(", (0, combi_1.altPrio)((0, combi_1.seq)(CDSParenSelect, unionOps), (0, combi_1.seq)(_1.CDSSelect, unionOps)), ")");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.CDSParenSelect = CDSParenSelect;
|
|
14
|
+
//# sourceMappingURL=cds_paren_select.js.map
|
|
@@ -3,10 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CDSPrefixedName = void 0;
|
|
4
4
|
const combi_1 = require("../../abap/2_statements/combi");
|
|
5
5
|
const cds_name_1 = require("./cds_name");
|
|
6
|
+
const cds_integer_1 = require("./cds_integer");
|
|
6
7
|
const cds_parameters_1 = require("./cds_parameters");
|
|
7
8
|
const cds_parameters_select_1 = require("./cds_parameters_select");
|
|
8
9
|
const cds_condition_1 = require("./cds_condition");
|
|
9
|
-
const cds_integer_1 = require("./cds_integer");
|
|
10
10
|
const cds_string_1 = require("./cds_string");
|
|
11
11
|
class CDSPrefixedName extends combi_1.Expression {
|
|
12
12
|
getRunnable() {
|
|
@@ -16,13 +16,17 @@ class CDSPrefixedName extends combi_1.Expression {
|
|
|
16
16
|
const cardinalityJoin = (0, combi_1.seq)("[", cardSpec, ":", joinType, "]");
|
|
17
17
|
const cardinalityJoinWhere = (0, combi_1.seq)("[", cardSpec, ":", joinType, "WHERE", cds_condition_1.CDSCondition, "]");
|
|
18
18
|
const joinWhere = (0, combi_1.seq)("[", joinType, "WHERE", cds_condition_1.CDSCondition, "]");
|
|
19
|
-
const textCard = (0, combi_1.altPrio)("MANY TO EXACT ONE", "MANY TO ONE", "ONE TO MANY", "ONE TO ONE", "TO EXACT ONE", "TO ONE", "TO MANY");
|
|
19
|
+
const textCard = (0, combi_1.altPrio)("EXACT ONE TO EXACT ONE", "EXACT ONE TO MANY", "EXACT ONE TO ONE", "MANY TO EXACT ONE", "MANY TO MANY", "MANY TO ONE", "ONE TO EXACT ONE", "ONE TO MANY", "ONE TO ONE", "TO EXACT ONE", "TO ONE", "TO MANY");
|
|
20
20
|
const textCardFilter = (0, combi_1.seq)("[", textCard, (0, combi_1.optPrio)((0, combi_1.seq)(":", (0, combi_1.altPrio)((0, combi_1.seq)(joinType, "WHERE", cds_condition_1.CDSCondition), joinType, cds_condition_1.CDSCondition))), "]");
|
|
21
21
|
const cardNum = (0, combi_1.altPrio)(cds_integer_1.CDSInteger, "*");
|
|
22
22
|
const rangeCard = (0, combi_1.seq)(cds_integer_1.CDSInteger, ".", ".", cardNum);
|
|
23
23
|
const rangeCardFilter = (0, combi_1.seq)("[", rangeCard, ":", cds_condition_1.CDSCondition, "]");
|
|
24
|
-
const
|
|
25
|
-
const
|
|
24
|
+
const rangeOnly = (0, combi_1.seq)("[", rangeCard, "]");
|
|
25
|
+
const numToText = (0, combi_1.seq)(cds_integer_1.CDSInteger, (0, combi_1.altPrio)("TO EXACT ONE", "TO ONE", "TO MANY"));
|
|
26
|
+
const numTextCardFilter = (0, combi_1.seq)("[", numToText, (0, combi_1.optPrio)((0, combi_1.seq)(":", cds_condition_1.CDSCondition)), "]");
|
|
27
|
+
const numToNum = (0, combi_1.seq)("[", cds_integer_1.CDSInteger, "TO", cds_integer_1.CDSInteger, (0, combi_1.optPrio)((0, combi_1.seq)(":", cds_condition_1.CDSCondition)), "]");
|
|
28
|
+
const pathFilter = (0, combi_1.altPrio)(cardinalityJoinWhere, joinWhere, cardinalityJoin, joinRedirect, numToNum, numTextCardFilter, textCardFilter, rangeCardFilter, rangeOnly, (0, combi_1.seq)("[", cardSpec, ":", cds_condition_1.CDSCondition, "]"), (0, combi_1.seq)("[", cardSpec, "]"), (0, combi_1.seq)("[", cds_condition_1.CDSCondition, "]"));
|
|
29
|
+
const segment = (0, combi_1.seq)(".", (0, combi_1.altPrio)(cds_string_1.CDSString, cds_integer_1.CDSInteger, cds_name_1.CDSName, "*"), (0, combi_1.optPrio)((0, combi_1.altPrio)(cds_parameters_select_1.CDSParametersSelect, cds_parameters_1.CDSParameters)), (0, combi_1.optPrio)(pathFilter));
|
|
26
30
|
return (0, combi_1.seq)(cds_name_1.CDSName, (0, combi_1.optPrio)((0, combi_1.altPrio)(cds_parameters_1.CDSParameters, cds_parameters_select_1.CDSParametersSelect)), (0, combi_1.optPrio)(pathFilter), (0, combi_1.star)(segment));
|
|
27
31
|
}
|
|
28
32
|
}
|
|
@@ -3,10 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CDSRelation = void 0;
|
|
4
4
|
const _1 = require(".");
|
|
5
5
|
const combi_1 = require("../../abap/2_statements/combi");
|
|
6
|
+
const KEYWORDS = ["AS", "ON", "WHERE", "WITH", "UNION", "GROUP", "HAVING",
|
|
7
|
+
"AND", "OR", "BETWEEN", "LIKE", "IN", "EXISTS",
|
|
8
|
+
"WHEN", "THEN", "ELSE", "END", "CASE", "CAST"];
|
|
6
9
|
class CDSRelation extends combi_1.Expression {
|
|
7
10
|
getRunnable() {
|
|
8
|
-
const
|
|
9
|
-
|
|
11
|
+
const word = (0, combi_1.regex)(/^[\w_]+$/);
|
|
12
|
+
const slashName = (0, combi_1.seq)("/", (0, combi_1.regex)(/^[\w]+$/), "/", (0, combi_1.stopBefore1)(...KEYWORDS), (0, combi_1.regex)(/^[\w_]+$/));
|
|
13
|
+
const name = (0, combi_1.altPrio)(slashName, word);
|
|
14
|
+
return (0, combi_1.seq)(name, (0, combi_1.opt)(_1.CDSParametersSelect), (0, combi_1.opt)(_1.CDSAs));
|
|
10
15
|
}
|
|
11
16
|
}
|
|
12
17
|
exports.CDSRelation = CDSRelation;
|
|
@@ -7,11 +7,12 @@ const cds_association_1 = require("./cds_association");
|
|
|
7
7
|
const cds_join_1 = require("./cds_join");
|
|
8
8
|
class CDSSelect extends combi_1.Expression {
|
|
9
9
|
getRunnable() {
|
|
10
|
-
const fields = (0, combi_1.seq)((0, combi_1.star)((0, combi_1.seq)(_1.CDSElement, ",")), _1.CDSElement);
|
|
10
|
+
const fields = (0, combi_1.seq)((0, combi_1.stopBefore1)("FROM"), (0, combi_1.star)((0, combi_1.seq)(_1.CDSElement, ",")), _1.CDSElement);
|
|
11
11
|
const distinct = (0, combi_1.str)("DISTINCT");
|
|
12
12
|
const elementList = (0, combi_1.seq)(_1.CDSElement, (0, combi_1.star)((0, combi_1.seq)(",", _1.CDSElement)), (0, combi_1.opt)(","));
|
|
13
13
|
const elements = (0, combi_1.seq)((0, combi_1.str)("{"), (0, combi_1.altPrio)("*", elementList), (0, combi_1.str)("}"));
|
|
14
|
-
const
|
|
14
|
+
const typedLiteralVal = (0, combi_1.seq)(_1.CDSType, _1.CDSString);
|
|
15
|
+
const aspectValue = (0, combi_1.altPrio)(typedLiteralVal, _1.CDSString, _1.CDSPrefixedName);
|
|
15
16
|
const aspectBinding = (0, combi_1.seq)(_1.CDSPrefixedName, "=", ">", aspectValue);
|
|
16
17
|
const bindAspect = (0, combi_1.seq)("BIND", "ASPECT", _1.CDSName, "(", aspectBinding, (0, combi_1.starPrio)((0, combi_1.seq)(",", aspectBinding)), ")", (0, combi_1.optPrio)((0, combi_1.seq)("AS", _1.CDSName)));
|
|
17
18
|
const parenSelect = (0, combi_1.seq)("(", CDSSelect, ")");
|
|
@@ -3,16 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CDSTableField = void 0;
|
|
4
4
|
const _1 = require(".");
|
|
5
5
|
const combi_1 = require("../../abap/2_statements/combi");
|
|
6
|
-
// A single field or association/composition inside a `define table entity { ... }`
|
|
7
|
-
// inline body. Wraps annotations + name + type together so tooling can iterate
|
|
8
|
-
// per-field with associated field-level annotations (matches the CDSElement
|
|
9
|
-
// shape used for select-list elements).
|
|
10
6
|
class CDSTableField extends combi_1.Expression {
|
|
11
7
|
getRunnable() {
|
|
12
8
|
const nullability = (0, combi_1.optPrio)((0, combi_1.alt)("NOT NULL", "NULL"));
|
|
9
|
+
const excludingNames = (0, combi_1.seq)(_1.CDSName, (0, combi_1.star)((0, combi_1.seq)(",", _1.CDSName)));
|
|
10
|
+
const excluding = (0, combi_1.seq)("EXCLUDING", "{", excludingNames, "}");
|
|
11
|
+
const includeField = (0, combi_1.seq)("INCLUDE", _1.CDSPrefixedName, (0, combi_1.optPrio)((0, combi_1.altPrio)((0, combi_1.seq)((0, combi_1.str)("SIGNATURE ONLY"), (0, combi_1.optPrio)(excluding)), (0, combi_1.seq)(excluding, (0, combi_1.optPrio)((0, combi_1.str)("SIGNATURE ONLY"))))));
|
|
13
12
|
const field = (0, combi_1.seq)((0, combi_1.optPrio)((0, combi_1.str)("KEY")), _1.CDSName, ":", _1.CDSType, nullability);
|
|
14
13
|
const assocOrComp = (0, combi_1.seq)(_1.CDSName, ":", (0, combi_1.alt)(_1.CDSComposition, _1.CDSAssociation));
|
|
15
|
-
return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.
|
|
14
|
+
return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.altPrio)(includeField, assocOrComp, field), ";");
|
|
16
15
|
}
|
|
17
16
|
}
|
|
18
17
|
exports.CDSTableField = CDSTableField;
|
|
@@ -5,7 +5,9 @@ const _1 = require(".");
|
|
|
5
5
|
const combi_1 = require("../../abap/2_statements/combi");
|
|
6
6
|
class CDSWithParameters extends combi_1.Expression {
|
|
7
7
|
getRunnable() {
|
|
8
|
-
const
|
|
8
|
+
const extNameValue = (0, combi_1.altPrio)(_1.CDSName, (0, combi_1.regex)(/^"(?:[^"]|"")*"$/));
|
|
9
|
+
const externalName = (0, combi_1.seq)("EXTERNAL", "NAME", extNameValue);
|
|
10
|
+
const param = (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), _1.CDSName, ":", _1.CDSType, (0, combi_1.opt)(externalName), (0, combi_1.star)(_1.CDSAnnotation));
|
|
9
11
|
return (0, combi_1.seq)("WITH PARAMETERS", param, (0, combi_1.star)((0, combi_1.seq)(",", param)));
|
|
10
12
|
}
|
|
11
13
|
}
|
|
@@ -36,6 +36,7 @@ __exportStar(require("./cds_define_hierarchy"), exports);
|
|
|
36
36
|
__exportStar(require("./cds_define_projection"), exports);
|
|
37
37
|
__exportStar(require("./cds_define_table_entity"), exports);
|
|
38
38
|
__exportStar(require("./cds_define_table_function"), exports);
|
|
39
|
+
__exportStar(require("./cds_paren_select"), exports);
|
|
39
40
|
__exportStar(require("./cds_define_view"), exports);
|
|
40
41
|
__exportStar(require("./cds_element"), exports);
|
|
41
42
|
__exportStar(require("./cds_extend_view"), exports);
|
package/build/src/registry.js
CHANGED
|
@@ -59,35 +59,38 @@ class UnusedVariablesConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
|
59
59
|
exports.UnusedVariablesConf = UnusedVariablesConf;
|
|
60
60
|
class WorkArea {
|
|
61
61
|
constructor() {
|
|
62
|
-
this
|
|
62
|
+
// keyed by filename + start position, this equals Identifier.equals()
|
|
63
|
+
this.workarea = new Map();
|
|
63
64
|
}
|
|
64
65
|
push(id, count = 1) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
66
|
+
const key = this.buildKey(id);
|
|
67
|
+
if (this.workarea.has(key)) {
|
|
68
|
+
return;
|
|
69
69
|
}
|
|
70
|
-
this.workarea.
|
|
70
|
+
this.workarea.set(key, { id, count });
|
|
71
71
|
}
|
|
72
72
|
removeIfExists(id) {
|
|
73
73
|
if (id === undefined) {
|
|
74
74
|
return;
|
|
75
75
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
return;
|
|
76
|
+
const key = this.buildKey(id);
|
|
77
|
+
const found = this.workarea.get(key);
|
|
78
|
+
if (found !== undefined) {
|
|
79
|
+
found.count--;
|
|
80
|
+
if (found.count === 0) {
|
|
81
|
+
this.workarea.delete(key);
|
|
83
82
|
}
|
|
84
83
|
}
|
|
85
84
|
}
|
|
86
85
|
get() {
|
|
87
|
-
return this.workarea;
|
|
86
|
+
return [...this.workarea.values()];
|
|
88
87
|
}
|
|
89
88
|
count() {
|
|
90
|
-
return this.workarea.
|
|
89
|
+
return this.workarea.size;
|
|
90
|
+
}
|
|
91
|
+
buildKey(id) {
|
|
92
|
+
const start = id.getStart();
|
|
93
|
+
return id.getFilename() + "," + start.getRow() + "," + start.getCol();
|
|
91
94
|
}
|
|
92
95
|
}
|
|
93
96
|
class UnusedVariables {
|
|
@@ -221,6 +224,9 @@ Errors found in INCLUDES are reported for the main program.`,
|
|
|
221
224
|
}
|
|
222
225
|
buildIssues(obj) {
|
|
223
226
|
const ret = [];
|
|
227
|
+
const metadata = this.getMetadata();
|
|
228
|
+
const pragma = metadata.pragma + "";
|
|
229
|
+
const files = new Map();
|
|
224
230
|
for (const w of this.workarea.get()) {
|
|
225
231
|
const filename = w.id.getFilename();
|
|
226
232
|
if (this.reg.isFileDependency(filename) === true) {
|
|
@@ -229,41 +235,51 @@ Errors found in INCLUDES are reported for the main program.`,
|
|
|
229
235
|
else if (obj instanceof objects_1.Program === false && obj.containsFile(filename) === false) {
|
|
230
236
|
continue;
|
|
231
237
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
continue;
|
|
238
|
+
if (files.has(filename) === false) {
|
|
239
|
+
files.set(filename, this.findFile(filename));
|
|
235
240
|
}
|
|
236
|
-
|
|
237
|
-
|
|
241
|
+
const file = files.get(filename);
|
|
242
|
+
let statement = undefined;
|
|
243
|
+
let statementIndex = -1;
|
|
244
|
+
if (file !== undefined) {
|
|
245
|
+
const statements = file.getStatements();
|
|
246
|
+
const token = w.id.getToken();
|
|
247
|
+
for (let i = 0; i < statements.length; i++) {
|
|
248
|
+
if (statements[i].includesToken(token)) {
|
|
249
|
+
statement = statements[i];
|
|
250
|
+
statementIndex = i;
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (statement !== undefined && file !== undefined) {
|
|
256
|
+
if (statement.getPragmas().some(t => t.getStr() === pragma)) {
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
else if (this.suppressedbyPseudo(file, statementIndex, w.id, obj)) {
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
238
262
|
}
|
|
239
263
|
const name = w.id.getName();
|
|
240
264
|
const message = "Variable \"" + name.toLowerCase() + "\" not used";
|
|
241
|
-
const fix = this.buildFix(w.id, obj);
|
|
242
|
-
ret.push(issue_1.Issue.atIdentifier(w.id, message,
|
|
265
|
+
const fix = this.buildFix(w.id, obj, statement);
|
|
266
|
+
ret.push(issue_1.Issue.atIdentifier(w.id, message, metadata.key, this.conf.severity, fix));
|
|
243
267
|
}
|
|
244
268
|
return ret;
|
|
245
269
|
}
|
|
246
|
-
suppressedbyPseudo(
|
|
247
|
-
|
|
270
|
+
suppressedbyPseudo(file, statementIndex, v, obj) {
|
|
271
|
+
// pseudo comments are only found in files belonging to the object itself, not in eg. includes
|
|
272
|
+
if (obj.getABAPFileByName(v.getFilename()) === undefined) {
|
|
248
273
|
return false;
|
|
249
274
|
}
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
let next = false;
|
|
255
|
-
for (const s of file.getStatements()) {
|
|
256
|
-
if (next === true && s.get() instanceof _statement_1.Comment) {
|
|
257
|
-
return s.concatTokens().includes(this.getMetadata().pseudoComment + "");
|
|
258
|
-
}
|
|
259
|
-
if (s === statement) {
|
|
260
|
-
next = true;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
275
|
+
const statements = file.getStatements();
|
|
276
|
+
const next = statements[statementIndex + 1];
|
|
277
|
+
return (next === null || next === void 0 ? void 0 : next.get()) instanceof _statement_1.Comment
|
|
278
|
+
&& next.concatTokens().includes(this.getMetadata().pseudoComment + "");
|
|
263
279
|
return false;
|
|
264
280
|
}
|
|
265
|
-
|
|
266
|
-
const file = this.reg.getFileByName(
|
|
281
|
+
findFile(filename) {
|
|
282
|
+
const file = this.reg.getFileByName(filename);
|
|
267
283
|
if (file === undefined) {
|
|
268
284
|
return undefined;
|
|
269
285
|
}
|
|
@@ -271,26 +287,17 @@ Errors found in INCLUDES are reported for the main program.`,
|
|
|
271
287
|
if (!(object instanceof _abap_object_1.ABAPObject)) {
|
|
272
288
|
return undefined;
|
|
273
289
|
}
|
|
274
|
-
|
|
275
|
-
|
|
290
|
+
return object.getABAPFileByName(filename);
|
|
291
|
+
}
|
|
292
|
+
buildFix(v, obj, statement) {
|
|
293
|
+
if (statement === undefined || !(statement.get() instanceof Statements.Data)) {
|
|
276
294
|
return undefined;
|
|
277
295
|
}
|
|
278
|
-
const statement = edit_helper_1.EditHelper.findStatement(v.getToken(), abapfile);
|
|
279
|
-
return statement;
|
|
280
|
-
}
|
|
281
|
-
buildFix(v, obj) {
|
|
282
296
|
const file = obj.getABAPFileByName(v.getFilename());
|
|
283
297
|
if (file === undefined) {
|
|
284
298
|
return undefined;
|
|
285
299
|
}
|
|
286
|
-
|
|
287
|
-
if (statement === undefined) {
|
|
288
|
-
return undefined;
|
|
289
|
-
}
|
|
290
|
-
else if (statement.get() instanceof Statements.Data) {
|
|
291
|
-
return edit_helper_1.EditHelper.deleteStatement(file, statement);
|
|
292
|
-
}
|
|
293
|
-
return undefined;
|
|
300
|
+
return edit_helper_1.EditHelper.deleteStatement(file, statement);
|
|
294
301
|
}
|
|
295
302
|
}
|
|
296
303
|
exports.UnusedVariables = UnusedVariables;
|