@sapui5/sap.fe.base 1.142.0 → 1.142.2
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/package.json +1 -1
- package/src/sap/fe/base/.library +1 -1
- package/src/sap/fe/base/AnnotationEnum.js +5 -3
- package/src/sap/fe/base/AnnotationEnum.ts +5 -2
- package/src/sap/fe/base/BindingToolkit.js +318 -34
- package/src/sap/fe/base/BindingToolkit.ts +639 -53
- package/src/sap/fe/base/library.js +1 -1
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
ActionParameter,
|
|
3
|
+
AddAnnotationExpression,
|
|
4
|
+
AddConditionalExpression,
|
|
3
5
|
AndAnnotationExpression,
|
|
4
6
|
AndConditionalExpression,
|
|
5
7
|
ApplyAnnotationExpression,
|
|
6
8
|
Boolean,
|
|
7
9
|
ConditionalCheckOrValue,
|
|
10
|
+
ConvertedMetadata,
|
|
11
|
+
DivAnnotationExpression,
|
|
12
|
+
DivByAnnotationExpression,
|
|
13
|
+
DivByConditionalExpression,
|
|
14
|
+
DivConditionalExpression,
|
|
8
15
|
EntitySet,
|
|
9
16
|
EntityType,
|
|
10
17
|
EqAnnotationExpression,
|
|
@@ -13,14 +20,24 @@ import type {
|
|
|
13
20
|
GeConditionalExpression,
|
|
14
21
|
GtAnnotationExpression,
|
|
15
22
|
GtConditionalExpression,
|
|
23
|
+
HasAnnotationExpression,
|
|
24
|
+
HasConditionalExpression,
|
|
16
25
|
IfAnnotationExpression,
|
|
17
26
|
IfAnnotationExpressionValue,
|
|
27
|
+
InAnnotationExpression,
|
|
28
|
+
InConditionalExpression,
|
|
18
29
|
LeAnnotationExpression,
|
|
19
30
|
LeConditionalExpression,
|
|
20
31
|
LtAnnotationExpression,
|
|
21
32
|
LtConditionalExpression,
|
|
33
|
+
ModAnnotationExpression,
|
|
34
|
+
ModConditionalExpression,
|
|
35
|
+
MulAnnotationExpression,
|
|
36
|
+
MulConditionalExpression,
|
|
22
37
|
NeAnnotationExpression,
|
|
23
38
|
NeConditionalExpression,
|
|
39
|
+
NegAnnotationExpression,
|
|
40
|
+
NegConditionalExpression,
|
|
24
41
|
NotAnnotationExpression,
|
|
25
42
|
NotConditionalExpression,
|
|
26
43
|
OrAnnotationExpression,
|
|
@@ -29,6 +46,8 @@ import type {
|
|
|
29
46
|
PathConditionExpression,
|
|
30
47
|
Property,
|
|
31
48
|
PropertyAnnotationValue,
|
|
49
|
+
SubAnnotationExpression,
|
|
50
|
+
SubConditionalExpression,
|
|
32
51
|
ConstantExpression as VocabConstantExpression
|
|
33
52
|
} from "@sap-ux/vocabularies-types";
|
|
34
53
|
import { CommonAnnotationTerms } from "@sap-ux/vocabularies-types/vocabularies/Common";
|
|
@@ -157,7 +176,7 @@ export type EmbeddedUI5ExpressionBindingExpression<T> = BaseExpression<T> & {
|
|
|
157
176
|
value: string;
|
|
158
177
|
};
|
|
159
178
|
|
|
160
|
-
export type ComparisonOperator = "===" | "!==" | ">=" | ">" | "<=" | "<";
|
|
179
|
+
export type ComparisonOperator = "===" | "!==" | ">=" | ">" | "<=" | "<" | "Has" | "In";
|
|
161
180
|
export type ComparisonExpression = BaseExpression<boolean> & {
|
|
162
181
|
_type: "Comparison";
|
|
163
182
|
operator: ComparisonOperator;
|
|
@@ -165,6 +184,13 @@ export type ComparisonExpression = BaseExpression<boolean> & {
|
|
|
165
184
|
operand2: BindingToolkitExpression<unknown>;
|
|
166
185
|
};
|
|
167
186
|
|
|
187
|
+
export type ArithmeticOperator = "+" | "-" | "*" | "/" | "%" | "Neg" | "Floor";
|
|
188
|
+
export type ArithmeticExpression = BaseExpression<number> & {
|
|
189
|
+
_type: "Arithmetic";
|
|
190
|
+
operator: ArithmeticOperator;
|
|
191
|
+
operand1: BindingToolkitExpression<unknown>;
|
|
192
|
+
operand2: BindingToolkitExpression<unknown>;
|
|
193
|
+
};
|
|
168
194
|
export type IfElseExpression<T> = BaseExpression<T> & {
|
|
169
195
|
_type: "IfElse";
|
|
170
196
|
condition: BindingToolkitExpression<boolean>;
|
|
@@ -174,6 +200,9 @@ export type IfElseExpression<T> = BaseExpression<T> & {
|
|
|
174
200
|
export function isProperty(serviceObject: unknown): serviceObject is Property {
|
|
175
201
|
return (serviceObject as Property)?._type === "Property";
|
|
176
202
|
}
|
|
203
|
+
function isActionParameter(serviceObject: unknown): serviceObject is ActionParameter {
|
|
204
|
+
return (serviceObject as ActionParameter)?._type === "ActionParameter";
|
|
205
|
+
}
|
|
177
206
|
|
|
178
207
|
/**
|
|
179
208
|
* An expression that evaluates to type T.
|
|
@@ -195,7 +224,8 @@ export type BindingToolkitExpression<T> =
|
|
|
195
224
|
| FormatterExpression<T>
|
|
196
225
|
| ComplexTypeExpression<T>
|
|
197
226
|
| ReferenceExpression
|
|
198
|
-
| FunctionExpression<T
|
|
227
|
+
| FunctionExpression<T>
|
|
228
|
+
| ArithmeticExpression;
|
|
199
229
|
|
|
200
230
|
type TypeMappingDefinition = {
|
|
201
231
|
type: string;
|
|
@@ -293,7 +323,12 @@ export function _checkExpressionsAreEqual<T>(a: BindingToolkitExpression<T>, b:
|
|
|
293
323
|
case "EmbeddedBinding":
|
|
294
324
|
case "EmbeddedExpressionBinding":
|
|
295
325
|
return a.value === (b as ConstantExpression<T>).value;
|
|
296
|
-
|
|
326
|
+
case "Arithmetic":
|
|
327
|
+
return (
|
|
328
|
+
a.operator === (b as ArithmeticExpression).operator &&
|
|
329
|
+
_checkExpressionsAreEqual(a.operand1, (b as ArithmeticExpression).operand1) &&
|
|
330
|
+
_checkExpressionsAreEqual(a.operand2, (b as ArithmeticExpression).operand2)
|
|
331
|
+
);
|
|
297
332
|
case "Not":
|
|
298
333
|
return _checkExpressionsAreEqual(a.operand, (b as NotExpression).operand);
|
|
299
334
|
case "Truthy":
|
|
@@ -499,6 +534,138 @@ export function or(...operands: ExpressionOrPrimitive<boolean>[]): BindingToolki
|
|
|
499
534
|
}
|
|
500
535
|
}
|
|
501
536
|
|
|
537
|
+
export function add<T extends PrimitiveType>(
|
|
538
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
539
|
+
rightOperand: ExpressionOrPrimitive<T>
|
|
540
|
+
): BindingToolkitExpression<number> {
|
|
541
|
+
return arithmetic("+", leftOperand, rightOperand);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
export function subtract<T extends PrimitiveType>(
|
|
545
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
546
|
+
rightOperand: ExpressionOrPrimitive<T>
|
|
547
|
+
): BindingToolkitExpression<number> {
|
|
548
|
+
return arithmetic("-", leftOperand, rightOperand);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
export function multiply<T extends PrimitiveType>(
|
|
552
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
553
|
+
rightOperand: ExpressionOrPrimitive<T>
|
|
554
|
+
): BindingToolkitExpression<number> {
|
|
555
|
+
return arithmetic("*", leftOperand, rightOperand);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
export function divide<T extends PrimitiveType>(
|
|
559
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
560
|
+
rightOperand: ExpressionOrPrimitive<T>
|
|
561
|
+
): BindingToolkitExpression<number> {
|
|
562
|
+
return arithmetic("/", leftOperand, rightOperand);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
export function modulo<T extends PrimitiveType>(
|
|
566
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
567
|
+
rightOperand: ExpressionOrPrimitive<T>
|
|
568
|
+
): BindingToolkitExpression<number> {
|
|
569
|
+
return arithmetic("%", leftOperand, rightOperand);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
export function negate<T extends PrimitiveType>(operand: ExpressionOrPrimitive<T>): BindingToolkitExpression<number> {
|
|
573
|
+
return arithmetic("Neg", operand, null);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
export function floor<T extends PrimitiveType>(operand: ExpressionOrPrimitive<T>): BindingToolkitExpression<number> {
|
|
577
|
+
return arithmetic("Floor", operand, null);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Arithmetic expression.
|
|
582
|
+
* @param operator
|
|
583
|
+
* @param leftOperand
|
|
584
|
+
* @param rightOperand
|
|
585
|
+
* @returns Expression evaluating to number
|
|
586
|
+
*/
|
|
587
|
+
export function arithmetic<T extends PrimitiveType>(
|
|
588
|
+
operator: ArithmeticOperator,
|
|
589
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
590
|
+
rightOperand: ExpressionOrPrimitive<T>
|
|
591
|
+
): BindingToolkitExpression<number> {
|
|
592
|
+
const leftExpression = wrapPrimitive(leftOperand);
|
|
593
|
+
const rightExpression = wrapPrimitive(rightOperand);
|
|
594
|
+
if (hasUnresolvableExpression(leftExpression, rightExpression)) {
|
|
595
|
+
return unresolvableExpression;
|
|
596
|
+
}
|
|
597
|
+
if (isConstant(leftExpression) && isConstant(rightExpression)) {
|
|
598
|
+
switch (operator) {
|
|
599
|
+
case "+":
|
|
600
|
+
if (leftExpression.value === null || leftExpression.value === undefined) {
|
|
601
|
+
return constant(rightExpression.value as number);
|
|
602
|
+
} else if (rightExpression.value === null || rightExpression.value === undefined) {
|
|
603
|
+
return constant(leftExpression.value as number);
|
|
604
|
+
}
|
|
605
|
+
const sum = (leftExpression.value as number) + (rightExpression.value as number);
|
|
606
|
+
return constant(sum);
|
|
607
|
+
case "-":
|
|
608
|
+
if (leftExpression.value === null || leftExpression.value === undefined) {
|
|
609
|
+
return constant(rightExpression.value as number);
|
|
610
|
+
} else if (rightExpression.value === null || rightExpression.value === undefined) {
|
|
611
|
+
return constant(leftExpression.value as number);
|
|
612
|
+
}
|
|
613
|
+
const diff = (leftExpression.value as number) - (rightExpression.value as number);
|
|
614
|
+
return constant(diff);
|
|
615
|
+
case "/":
|
|
616
|
+
if (
|
|
617
|
+
leftExpression.value === null ||
|
|
618
|
+
leftExpression.value === undefined ||
|
|
619
|
+
rightExpression.value === null ||
|
|
620
|
+
rightExpression.value === undefined
|
|
621
|
+
) {
|
|
622
|
+
return constant(0);
|
|
623
|
+
}
|
|
624
|
+
const div = (leftExpression.value as number) / (rightExpression.value as number);
|
|
625
|
+
return constant(div);
|
|
626
|
+
case "Neg":
|
|
627
|
+
if (leftExpression.value === null || leftExpression.value === undefined) {
|
|
628
|
+
return constant(0);
|
|
629
|
+
}
|
|
630
|
+
return constant(-leftExpression.value);
|
|
631
|
+
case "%":
|
|
632
|
+
if (
|
|
633
|
+
leftExpression.value === null ||
|
|
634
|
+
leftExpression.value === undefined ||
|
|
635
|
+
rightExpression.value === null ||
|
|
636
|
+
rightExpression.value === undefined
|
|
637
|
+
) {
|
|
638
|
+
return constant(0);
|
|
639
|
+
}
|
|
640
|
+
const mod = (leftExpression.value as number) % (rightExpression.value as number);
|
|
641
|
+
return constant(mod);
|
|
642
|
+
case "Floor":
|
|
643
|
+
if (leftExpression.value === null || leftExpression.value === undefined) {
|
|
644
|
+
return constant(0);
|
|
645
|
+
}
|
|
646
|
+
return constant(Math.floor(leftExpression.value as number));
|
|
647
|
+
case "*":
|
|
648
|
+
if (
|
|
649
|
+
leftExpression.value === null ||
|
|
650
|
+
leftExpression.value === undefined ||
|
|
651
|
+
rightExpression.value === null ||
|
|
652
|
+
rightExpression.value === undefined
|
|
653
|
+
) {
|
|
654
|
+
return constant(0);
|
|
655
|
+
}
|
|
656
|
+
const mult = (leftExpression.value as number) * (rightExpression.value as number);
|
|
657
|
+
return constant(mult);
|
|
658
|
+
}
|
|
659
|
+
} else {
|
|
660
|
+
return {
|
|
661
|
+
_type: "Arithmetic",
|
|
662
|
+
operator: operator,
|
|
663
|
+
operand1: leftExpression,
|
|
664
|
+
operand2: rightExpression
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
|
|
502
669
|
/**
|
|
503
670
|
* Logical `not` operator.
|
|
504
671
|
* @param operand The expression to reverse
|
|
@@ -539,6 +706,11 @@ export function not(operand: ExpressionOrPrimitive<boolean>): BindingToolkitExpr
|
|
|
539
706
|
return { ...operand, operator: "<=" };
|
|
540
707
|
case ">=":
|
|
541
708
|
return { ...operand, operator: "<" };
|
|
709
|
+
default:
|
|
710
|
+
return {
|
|
711
|
+
_type: "Not",
|
|
712
|
+
operand: operand
|
|
713
|
+
};
|
|
542
714
|
}
|
|
543
715
|
} else if (operand._type === "Not") {
|
|
544
716
|
return operand.operand;
|
|
@@ -849,6 +1021,15 @@ type ComplexAnnotationExpression<P> =
|
|
|
849
1021
|
| GeAnnotationExpression<P>
|
|
850
1022
|
| LeAnnotationExpression<P>
|
|
851
1023
|
| LtAnnotationExpression<P>
|
|
1024
|
+
| HasAnnotationExpression<P>
|
|
1025
|
+
| InAnnotationExpression<P>
|
|
1026
|
+
| AddAnnotationExpression<P>
|
|
1027
|
+
| SubAnnotationExpression<P>
|
|
1028
|
+
| MulAnnotationExpression<P>
|
|
1029
|
+
| DivAnnotationExpression<P>
|
|
1030
|
+
| ModAnnotationExpression<P>
|
|
1031
|
+
| DivByAnnotationExpression<P>
|
|
1032
|
+
| NegAnnotationExpression<P>
|
|
852
1033
|
| VocabConstantExpression<P>;
|
|
853
1034
|
|
|
854
1035
|
function isPrimitiveObject(objectType: object): boolean {
|
|
@@ -871,6 +1052,11 @@ function isComplexAnnotationExpression<T>(annotationValue: PropertyAnnotationVal
|
|
|
871
1052
|
return typeof annotationValue === "object" && !isPrimitiveObject(annotationValue as object);
|
|
872
1053
|
}
|
|
873
1054
|
|
|
1055
|
+
let CONVERTER_ROOT_SYMBOL: symbol | undefined;
|
|
1056
|
+
export function setConverterRootSymbol(converterRootSymbol: symbol): void {
|
|
1057
|
+
CONVERTER_ROOT_SYMBOL = converterRootSymbol;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
874
1060
|
/**
|
|
875
1061
|
* Generate the corresponding annotationValue for a given annotation annotationValue.
|
|
876
1062
|
* @template T The target type
|
|
@@ -886,6 +1072,11 @@ export function getExpressionFromAnnotation<T extends PrimitiveType>(
|
|
|
886
1072
|
defaultValue?: ExpressionOrPrimitive<T>,
|
|
887
1073
|
pathVisitor?: Function
|
|
888
1074
|
): BindingToolkitExpression<PrimitiveTypeCast<T>> {
|
|
1075
|
+
let converterRoot: ConvertedMetadata | undefined;
|
|
1076
|
+
if (CONVERTER_ROOT_SYMBOL) {
|
|
1077
|
+
converterRoot = (annotationValue?.[CONVERTER_ROOT_SYMBOL as never] as unknown as Function)?.() as ConvertedMetadata | undefined;
|
|
1078
|
+
}
|
|
1079
|
+
|
|
889
1080
|
if (annotationValue === undefined) {
|
|
890
1081
|
return wrapPrimitive(defaultValue as PrimitiveTypeCast<T>);
|
|
891
1082
|
}
|
|
@@ -898,55 +1089,106 @@ export function getExpressionFromAnnotation<T extends PrimitiveType>(
|
|
|
898
1089
|
case "Path":
|
|
899
1090
|
return pathInModel(annotationValue.path, undefined, visitedNavigationPaths, pathVisitor);
|
|
900
1091
|
case "If":
|
|
901
|
-
return annotationIfExpression(
|
|
902
|
-
|
|
903
|
-
|
|
1092
|
+
return annotationIfExpression(
|
|
1093
|
+
annotationValue.$If,
|
|
1094
|
+
visitedNavigationPaths,
|
|
1095
|
+
pathVisitor,
|
|
1096
|
+
converterRoot
|
|
1097
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
904
1098
|
case "Not":
|
|
905
|
-
return not(
|
|
906
|
-
|
|
907
|
-
|
|
1099
|
+
return not(
|
|
1100
|
+
parseAnnotationCondition(annotationValue.$Not, visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1101
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
908
1102
|
case "Eq":
|
|
909
1103
|
return equal(
|
|
910
|
-
parseAnnotationCondition(annotationValue.$Eq[0], visitedNavigationPaths, pathVisitor),
|
|
911
|
-
parseAnnotationCondition(annotationValue.$Eq[1], visitedNavigationPaths, pathVisitor)
|
|
1104
|
+
parseAnnotationCondition(annotationValue.$Eq[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1105
|
+
parseAnnotationCondition(annotationValue.$Eq[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
912
1106
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
913
1107
|
case "Ne":
|
|
914
1108
|
return notEqual(
|
|
915
|
-
parseAnnotationCondition(annotationValue.$Ne[0], visitedNavigationPaths, pathVisitor),
|
|
916
|
-
parseAnnotationCondition(annotationValue.$Ne[1], visitedNavigationPaths, pathVisitor)
|
|
1109
|
+
parseAnnotationCondition(annotationValue.$Ne[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1110
|
+
parseAnnotationCondition(annotationValue.$Ne[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
917
1111
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
918
1112
|
case "Gt":
|
|
919
1113
|
return greaterThan(
|
|
920
|
-
parseAnnotationCondition(annotationValue.$Gt[0], visitedNavigationPaths, pathVisitor),
|
|
921
|
-
parseAnnotationCondition(annotationValue.$Gt[1], visitedNavigationPaths, pathVisitor)
|
|
1114
|
+
parseAnnotationCondition(annotationValue.$Gt[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1115
|
+
parseAnnotationCondition(annotationValue.$Gt[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
922
1116
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
923
1117
|
case "Ge":
|
|
924
1118
|
return greaterOrEqual(
|
|
925
|
-
parseAnnotationCondition(annotationValue.$Ge[0], visitedNavigationPaths, pathVisitor),
|
|
926
|
-
parseAnnotationCondition(annotationValue.$Ge[1], visitedNavigationPaths, pathVisitor)
|
|
1119
|
+
parseAnnotationCondition(annotationValue.$Ge[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1120
|
+
parseAnnotationCondition(annotationValue.$Ge[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
927
1121
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
928
1122
|
case "Lt":
|
|
929
1123
|
return lessThan(
|
|
930
|
-
parseAnnotationCondition(annotationValue.$Lt[0], visitedNavigationPaths, pathVisitor),
|
|
931
|
-
parseAnnotationCondition(annotationValue.$Lt[1], visitedNavigationPaths, pathVisitor)
|
|
1124
|
+
parseAnnotationCondition(annotationValue.$Lt[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1125
|
+
parseAnnotationCondition(annotationValue.$Lt[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
932
1126
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
933
1127
|
case "Le":
|
|
934
1128
|
return lessOrEqual(
|
|
935
|
-
parseAnnotationCondition(annotationValue.$Le[0], visitedNavigationPaths, pathVisitor),
|
|
936
|
-
parseAnnotationCondition(annotationValue.$Le[1], visitedNavigationPaths, pathVisitor)
|
|
1129
|
+
parseAnnotationCondition(annotationValue.$Le[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1130
|
+
parseAnnotationCondition(annotationValue.$Le[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
937
1131
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
938
1132
|
case "Or":
|
|
939
1133
|
return or(
|
|
940
1134
|
...annotationValue.$Or.map(function (orCondition) {
|
|
941
|
-
return parseAnnotationCondition<boolean>(orCondition, visitedNavigationPaths, pathVisitor);
|
|
1135
|
+
return parseAnnotationCondition<boolean>(orCondition, visitedNavigationPaths, pathVisitor, converterRoot);
|
|
942
1136
|
})
|
|
943
1137
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
944
1138
|
case "And":
|
|
945
1139
|
return and(
|
|
946
1140
|
...annotationValue.$And.map(function (andCondition) {
|
|
947
|
-
return parseAnnotationCondition<boolean>(andCondition, visitedNavigationPaths, pathVisitor);
|
|
1141
|
+
return parseAnnotationCondition<boolean>(andCondition, visitedNavigationPaths, pathVisitor, converterRoot);
|
|
948
1142
|
})
|
|
949
1143
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1144
|
+
case "In":
|
|
1145
|
+
return comparison(
|
|
1146
|
+
"In",
|
|
1147
|
+
parseAnnotationCondition(annotationValue.$In[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1148
|
+
parseAnnotationCondition(annotationValue.$In[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1149
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1150
|
+
case "Has":
|
|
1151
|
+
return comparison(
|
|
1152
|
+
"Has",
|
|
1153
|
+
parseAnnotationCondition(annotationValue.$Has[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1154
|
+
parseAnnotationCondition(annotationValue.$Has[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1155
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1156
|
+
case "Add":
|
|
1157
|
+
return add(
|
|
1158
|
+
parseAnnotationCondition(annotationValue.$Add[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1159
|
+
parseAnnotationCondition(annotationValue.$Add[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1160
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1161
|
+
case "Sub":
|
|
1162
|
+
return subtract(
|
|
1163
|
+
parseAnnotationCondition(annotationValue.$Sub[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1164
|
+
parseAnnotationCondition(annotationValue.$Sub[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1165
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1166
|
+
case "Mul":
|
|
1167
|
+
return multiply(
|
|
1168
|
+
parseAnnotationCondition(annotationValue.$Mul[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1169
|
+
parseAnnotationCondition(annotationValue.$Mul[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1170
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1171
|
+
case "Div":
|
|
1172
|
+
return floor(
|
|
1173
|
+
divide(
|
|
1174
|
+
parseAnnotationCondition(annotationValue.$Div[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1175
|
+
parseAnnotationCondition(annotationValue.$Div[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1176
|
+
)
|
|
1177
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1178
|
+
case "DivBy":
|
|
1179
|
+
return divide(
|
|
1180
|
+
parseAnnotationCondition(annotationValue.$DivBy[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1181
|
+
parseAnnotationCondition(annotationValue.$DivBy[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1182
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1183
|
+
case "Mod":
|
|
1184
|
+
return modulo(
|
|
1185
|
+
parseAnnotationCondition(annotationValue.$Mod[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1186
|
+
parseAnnotationCondition(annotationValue.$Mod[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1187
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1188
|
+
case "Neg":
|
|
1189
|
+
return negate(
|
|
1190
|
+
parseAnnotationCondition(annotationValue.$Neg[0], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1191
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
950
1192
|
case "Apply":
|
|
951
1193
|
return annotationApplyExpression(
|
|
952
1194
|
annotationValue as ApplyAnnotationExpression<string>,
|
|
@@ -966,60 +1208,122 @@ export function getExpressionFromAnnotation<T extends PrimitiveType>(
|
|
|
966
1208
|
* @param annotationValue The condition or value from the annotation
|
|
967
1209
|
* @param visitedNavigationPaths The path from the root entity set
|
|
968
1210
|
* @param pathVisitor A function to modify the resulting path
|
|
1211
|
+
* @param converterRoot The root converted metadata
|
|
969
1212
|
* @returns An equivalent expression
|
|
970
1213
|
*/
|
|
971
1214
|
function parseAnnotationCondition<T extends PrimitiveType>(
|
|
972
1215
|
annotationValue: ConditionalCheckOrValue,
|
|
973
1216
|
visitedNavigationPaths: string[] = [],
|
|
974
|
-
pathVisitor?: Function
|
|
1217
|
+
pathVisitor?: Function,
|
|
1218
|
+
converterRoot?: ConvertedMetadata
|
|
975
1219
|
): BindingToolkitExpression<T> {
|
|
976
1220
|
if (annotationValue === null || typeof annotationValue !== "object") {
|
|
977
1221
|
return constant(annotationValue as T);
|
|
978
1222
|
} else if (annotationValue.hasOwnProperty("$Or")) {
|
|
979
1223
|
return or(
|
|
980
1224
|
...((annotationValue as OrConditionalExpression).$Or.map(function (orCondition) {
|
|
981
|
-
return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor);
|
|
1225
|
+
return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor, converterRoot);
|
|
982
1226
|
}) as unknown as BindingToolkitExpression<boolean>[])
|
|
983
1227
|
) as BindingToolkitExpression<T>;
|
|
984
1228
|
} else if (annotationValue.hasOwnProperty("$And")) {
|
|
985
1229
|
return and(
|
|
986
1230
|
...((annotationValue as AndConditionalExpression).$And.map(function (andCondition) {
|
|
987
|
-
return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor);
|
|
1231
|
+
return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor, converterRoot);
|
|
988
1232
|
}) as unknown as BindingToolkitExpression<boolean>[])
|
|
989
1233
|
) as BindingToolkitExpression<T>;
|
|
990
1234
|
} else if (annotationValue.hasOwnProperty("$Not")) {
|
|
991
1235
|
return not(
|
|
992
|
-
parseAnnotationCondition((annotationValue as NotConditionalExpression).$Not, visitedNavigationPaths, pathVisitor)
|
|
1236
|
+
parseAnnotationCondition((annotationValue as NotConditionalExpression).$Not, visitedNavigationPaths, pathVisitor, converterRoot)
|
|
993
1237
|
) as BindingToolkitExpression<T>;
|
|
994
1238
|
} else if (annotationValue.hasOwnProperty("$Eq")) {
|
|
995
1239
|
return equal(
|
|
996
|
-
parseAnnotationCondition(
|
|
997
|
-
|
|
1240
|
+
parseAnnotationCondition(
|
|
1241
|
+
(annotationValue as EqConditionalExpression).$Eq[0],
|
|
1242
|
+
visitedNavigationPaths,
|
|
1243
|
+
pathVisitor,
|
|
1244
|
+
converterRoot
|
|
1245
|
+
),
|
|
1246
|
+
parseAnnotationCondition(
|
|
1247
|
+
(annotationValue as EqConditionalExpression).$Eq[1],
|
|
1248
|
+
visitedNavigationPaths,
|
|
1249
|
+
pathVisitor,
|
|
1250
|
+
converterRoot
|
|
1251
|
+
)
|
|
998
1252
|
) as BindingToolkitExpression<T>;
|
|
999
1253
|
} else if (annotationValue.hasOwnProperty("$Ne")) {
|
|
1000
1254
|
return notEqual(
|
|
1001
|
-
parseAnnotationCondition(
|
|
1002
|
-
|
|
1255
|
+
parseAnnotationCondition(
|
|
1256
|
+
(annotationValue as NeConditionalExpression).$Ne[0],
|
|
1257
|
+
visitedNavigationPaths,
|
|
1258
|
+
pathVisitor,
|
|
1259
|
+
converterRoot
|
|
1260
|
+
),
|
|
1261
|
+
parseAnnotationCondition(
|
|
1262
|
+
(annotationValue as NeConditionalExpression).$Ne[1],
|
|
1263
|
+
visitedNavigationPaths,
|
|
1264
|
+
pathVisitor,
|
|
1265
|
+
converterRoot
|
|
1266
|
+
)
|
|
1003
1267
|
) as BindingToolkitExpression<T>;
|
|
1004
1268
|
} else if (annotationValue.hasOwnProperty("$Gt")) {
|
|
1005
1269
|
return greaterThan(
|
|
1006
|
-
parseAnnotationCondition(
|
|
1007
|
-
|
|
1270
|
+
parseAnnotationCondition(
|
|
1271
|
+
(annotationValue as GtConditionalExpression).$Gt[0],
|
|
1272
|
+
visitedNavigationPaths,
|
|
1273
|
+
pathVisitor,
|
|
1274
|
+
converterRoot
|
|
1275
|
+
),
|
|
1276
|
+
parseAnnotationCondition(
|
|
1277
|
+
(annotationValue as GtConditionalExpression).$Gt[1],
|
|
1278
|
+
visitedNavigationPaths,
|
|
1279
|
+
pathVisitor,
|
|
1280
|
+
converterRoot
|
|
1281
|
+
)
|
|
1008
1282
|
) as BindingToolkitExpression<T>;
|
|
1009
1283
|
} else if (annotationValue.hasOwnProperty("$Ge")) {
|
|
1010
1284
|
return greaterOrEqual(
|
|
1011
|
-
parseAnnotationCondition(
|
|
1012
|
-
|
|
1285
|
+
parseAnnotationCondition(
|
|
1286
|
+
(annotationValue as GeConditionalExpression).$Ge[0],
|
|
1287
|
+
visitedNavigationPaths,
|
|
1288
|
+
pathVisitor,
|
|
1289
|
+
converterRoot
|
|
1290
|
+
),
|
|
1291
|
+
parseAnnotationCondition(
|
|
1292
|
+
(annotationValue as GeConditionalExpression).$Ge[1],
|
|
1293
|
+
visitedNavigationPaths,
|
|
1294
|
+
pathVisitor,
|
|
1295
|
+
converterRoot
|
|
1296
|
+
)
|
|
1013
1297
|
) as BindingToolkitExpression<T>;
|
|
1014
1298
|
} else if (annotationValue.hasOwnProperty("$Lt")) {
|
|
1015
1299
|
return lessThan(
|
|
1016
|
-
parseAnnotationCondition(
|
|
1017
|
-
|
|
1300
|
+
parseAnnotationCondition(
|
|
1301
|
+
(annotationValue as LtConditionalExpression).$Lt[0],
|
|
1302
|
+
visitedNavigationPaths,
|
|
1303
|
+
pathVisitor,
|
|
1304
|
+
converterRoot
|
|
1305
|
+
),
|
|
1306
|
+
parseAnnotationCondition(
|
|
1307
|
+
(annotationValue as LtConditionalExpression).$Lt[1],
|
|
1308
|
+
visitedNavigationPaths,
|
|
1309
|
+
pathVisitor,
|
|
1310
|
+
converterRoot
|
|
1311
|
+
)
|
|
1018
1312
|
) as BindingToolkitExpression<T>;
|
|
1019
1313
|
} else if (annotationValue.hasOwnProperty("$Le")) {
|
|
1020
1314
|
return lessOrEqual(
|
|
1021
|
-
parseAnnotationCondition(
|
|
1022
|
-
|
|
1315
|
+
parseAnnotationCondition(
|
|
1316
|
+
(annotationValue as LeConditionalExpression).$Le[0],
|
|
1317
|
+
visitedNavigationPaths,
|
|
1318
|
+
pathVisitor,
|
|
1319
|
+
converterRoot
|
|
1320
|
+
),
|
|
1321
|
+
parseAnnotationCondition(
|
|
1322
|
+
(annotationValue as LeConditionalExpression).$Le[1],
|
|
1323
|
+
visitedNavigationPaths,
|
|
1324
|
+
pathVisitor,
|
|
1325
|
+
converterRoot
|
|
1326
|
+
)
|
|
1023
1327
|
) as BindingToolkitExpression<T>;
|
|
1024
1328
|
} else if (annotationValue.hasOwnProperty("$Path")) {
|
|
1025
1329
|
return pathInModel((annotationValue as PathConditionExpression<T>).$Path, undefined, visitedNavigationPaths, pathVisitor);
|
|
@@ -1045,9 +1349,137 @@ function parseAnnotationCondition<T extends PrimitiveType>(
|
|
|
1045
1349
|
pathVisitor
|
|
1046
1350
|
) as BindingToolkitExpression<T>;
|
|
1047
1351
|
} else if (annotationValue.hasOwnProperty("$EnumMember")) {
|
|
1048
|
-
return constant(resolveEnumValue((annotationValue as { $EnumMember?: string }).$EnumMember) as T);
|
|
1352
|
+
return constant(resolveEnumValue((annotationValue as { $EnumMember?: string }).$EnumMember, converterRoot) as T);
|
|
1353
|
+
} else if (annotationValue.hasOwnProperty("$In")) {
|
|
1354
|
+
return comparison(
|
|
1355
|
+
"In",
|
|
1356
|
+
parseAnnotationCondition(
|
|
1357
|
+
(annotationValue as InConditionalExpression).$In[0],
|
|
1358
|
+
visitedNavigationPaths,
|
|
1359
|
+
pathVisitor,
|
|
1360
|
+
converterRoot
|
|
1361
|
+
),
|
|
1362
|
+
parseAnnotationCondition(
|
|
1363
|
+
(annotationValue as InConditionalExpression).$In[1],
|
|
1364
|
+
visitedNavigationPaths,
|
|
1365
|
+
pathVisitor,
|
|
1366
|
+
converterRoot
|
|
1367
|
+
)
|
|
1368
|
+
) as BindingToolkitExpression<T>;
|
|
1369
|
+
} else if (annotationValue.hasOwnProperty("$Has")) {
|
|
1370
|
+
return comparison(
|
|
1371
|
+
"Has",
|
|
1372
|
+
parseAnnotationCondition(
|
|
1373
|
+
(annotationValue as HasConditionalExpression).$Has[0],
|
|
1374
|
+
visitedNavigationPaths,
|
|
1375
|
+
pathVisitor,
|
|
1376
|
+
converterRoot
|
|
1377
|
+
),
|
|
1378
|
+
parseAnnotationCondition(
|
|
1379
|
+
(annotationValue as HasConditionalExpression).$Has[1],
|
|
1380
|
+
visitedNavigationPaths,
|
|
1381
|
+
pathVisitor,
|
|
1382
|
+
converterRoot
|
|
1383
|
+
)
|
|
1384
|
+
) as BindingToolkitExpression<T>;
|
|
1385
|
+
} else if (annotationValue.hasOwnProperty("$Add")) {
|
|
1386
|
+
return add(
|
|
1387
|
+
parseAnnotationCondition(
|
|
1388
|
+
(annotationValue as AddConditionalExpression).$Add[0],
|
|
1389
|
+
visitedNavigationPaths,
|
|
1390
|
+
pathVisitor,
|
|
1391
|
+
converterRoot
|
|
1392
|
+
),
|
|
1393
|
+
parseAnnotationCondition(
|
|
1394
|
+
(annotationValue as AddConditionalExpression).$Add[1],
|
|
1395
|
+
visitedNavigationPaths,
|
|
1396
|
+
pathVisitor,
|
|
1397
|
+
converterRoot
|
|
1398
|
+
)
|
|
1399
|
+
) as BindingToolkitExpression<T>;
|
|
1400
|
+
} else if (annotationValue.hasOwnProperty("$Sub")) {
|
|
1401
|
+
return subtract(
|
|
1402
|
+
parseAnnotationCondition(
|
|
1403
|
+
(annotationValue as SubConditionalExpression).$Sub[0],
|
|
1404
|
+
visitedNavigationPaths,
|
|
1405
|
+
pathVisitor,
|
|
1406
|
+
converterRoot
|
|
1407
|
+
),
|
|
1408
|
+
parseAnnotationCondition(
|
|
1409
|
+
(annotationValue as SubConditionalExpression).$Sub[1],
|
|
1410
|
+
visitedNavigationPaths,
|
|
1411
|
+
pathVisitor,
|
|
1412
|
+
converterRoot
|
|
1413
|
+
)
|
|
1414
|
+
) as BindingToolkitExpression<T>;
|
|
1415
|
+
} else if (annotationValue.hasOwnProperty("$Mul")) {
|
|
1416
|
+
return multiply(
|
|
1417
|
+
parseAnnotationCondition(
|
|
1418
|
+
(annotationValue as MulConditionalExpression).$Mul[0],
|
|
1419
|
+
visitedNavigationPaths,
|
|
1420
|
+
pathVisitor,
|
|
1421
|
+
converterRoot
|
|
1422
|
+
),
|
|
1423
|
+
parseAnnotationCondition(
|
|
1424
|
+
(annotationValue as MulConditionalExpression).$Mul[1],
|
|
1425
|
+
visitedNavigationPaths,
|
|
1426
|
+
pathVisitor,
|
|
1427
|
+
converterRoot
|
|
1428
|
+
)
|
|
1429
|
+
) as BindingToolkitExpression<T>;
|
|
1430
|
+
} else if (annotationValue.hasOwnProperty("$Div")) {
|
|
1431
|
+
return floor(
|
|
1432
|
+
divide(
|
|
1433
|
+
parseAnnotationCondition(
|
|
1434
|
+
(annotationValue as DivConditionalExpression).$Div[0],
|
|
1435
|
+
visitedNavigationPaths,
|
|
1436
|
+
pathVisitor,
|
|
1437
|
+
converterRoot
|
|
1438
|
+
),
|
|
1439
|
+
parseAnnotationCondition(
|
|
1440
|
+
(annotationValue as DivConditionalExpression).$Div[1],
|
|
1441
|
+
visitedNavigationPaths,
|
|
1442
|
+
pathVisitor,
|
|
1443
|
+
converterRoot
|
|
1444
|
+
)
|
|
1445
|
+
)
|
|
1446
|
+
) as BindingToolkitExpression<T>;
|
|
1447
|
+
} else if (annotationValue.hasOwnProperty("$DivBy")) {
|
|
1448
|
+
return divide(
|
|
1449
|
+
parseAnnotationCondition(
|
|
1450
|
+
(annotationValue as DivByConditionalExpression).$DivBy[0],
|
|
1451
|
+
visitedNavigationPaths,
|
|
1452
|
+
pathVisitor,
|
|
1453
|
+
converterRoot
|
|
1454
|
+
),
|
|
1455
|
+
parseAnnotationCondition(
|
|
1456
|
+
(annotationValue as DivByConditionalExpression).$DivBy[1],
|
|
1457
|
+
visitedNavigationPaths,
|
|
1458
|
+
pathVisitor,
|
|
1459
|
+
converterRoot
|
|
1460
|
+
)
|
|
1461
|
+
) as BindingToolkitExpression<T>;
|
|
1462
|
+
} else if (annotationValue.hasOwnProperty("$Mod")) {
|
|
1463
|
+
return modulo(
|
|
1464
|
+
parseAnnotationCondition(
|
|
1465
|
+
(annotationValue as ModConditionalExpression).$Mod[0],
|
|
1466
|
+
visitedNavigationPaths,
|
|
1467
|
+
pathVisitor,
|
|
1468
|
+
converterRoot
|
|
1469
|
+
),
|
|
1470
|
+
parseAnnotationCondition(
|
|
1471
|
+
(annotationValue as ModConditionalExpression).$Mod[1],
|
|
1472
|
+
visitedNavigationPaths,
|
|
1473
|
+
pathVisitor,
|
|
1474
|
+
converterRoot
|
|
1475
|
+
)
|
|
1476
|
+
) as BindingToolkitExpression<T>;
|
|
1477
|
+
} else if (annotationValue.hasOwnProperty("$Neg")) {
|
|
1478
|
+
return negate(
|
|
1479
|
+
parseAnnotationCondition((annotationValue as NegConditionalExpression).$Neg, visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1480
|
+
) as BindingToolkitExpression<T>;
|
|
1049
1481
|
}
|
|
1050
|
-
return constant(
|
|
1482
|
+
return constant(annotationValue as T);
|
|
1051
1483
|
}
|
|
1052
1484
|
|
|
1053
1485
|
/**
|
|
@@ -1056,17 +1488,19 @@ function parseAnnotationCondition<T extends PrimitiveType>(
|
|
|
1056
1488
|
* @param annotationValue An If expression returning the type T
|
|
1057
1489
|
* @param visitedNavigationPaths The path from the root entity set
|
|
1058
1490
|
* @param pathVisitor A function to modify the resulting path
|
|
1491
|
+
* @param converterRoot The root converted metadata
|
|
1059
1492
|
* @returns The equivalent ifElse expression
|
|
1060
1493
|
*/
|
|
1061
1494
|
export function annotationIfExpression<T extends PrimitiveType>(
|
|
1062
1495
|
annotationValue: IfAnnotationExpressionValue<T>,
|
|
1063
1496
|
visitedNavigationPaths: string[] = [],
|
|
1064
|
-
pathVisitor?: Function
|
|
1497
|
+
pathVisitor?: Function,
|
|
1498
|
+
converterRoot?: ConvertedMetadata
|
|
1065
1499
|
): BindingToolkitExpression<T> {
|
|
1066
1500
|
return ifElse(
|
|
1067
|
-
parseAnnotationCondition(annotationValue[0], visitedNavigationPaths, pathVisitor),
|
|
1068
|
-
parseAnnotationCondition(annotationValue[1] as ConditionalCheckOrValue, visitedNavigationPaths, pathVisitor),
|
|
1069
|
-
parseAnnotationCondition(annotationValue[2] as ConditionalCheckOrValue, visitedNavigationPaths, pathVisitor)
|
|
1501
|
+
parseAnnotationCondition(annotationValue[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1502
|
+
parseAnnotationCondition(annotationValue[1] as ConditionalCheckOrValue, visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1503
|
+
parseAnnotationCondition(annotationValue[2] as ConditionalCheckOrValue, visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1070
1504
|
);
|
|
1071
1505
|
}
|
|
1072
1506
|
// This type is not recursively transformed from the metamodel content, as such we have some ugly things there
|
|
@@ -1205,6 +1639,43 @@ function comparison<T extends PrimitiveType>(
|
|
|
1205
1639
|
return constant(false);
|
|
1206
1640
|
}
|
|
1207
1641
|
return constant(leftExpression.value >= rightExpression.value);
|
|
1642
|
+
|
|
1643
|
+
case "Has": {
|
|
1644
|
+
if (
|
|
1645
|
+
leftExpression.value === null ||
|
|
1646
|
+
leftExpression.value === undefined ||
|
|
1647
|
+
rightExpression.value === null ||
|
|
1648
|
+
rightExpression.value === undefined
|
|
1649
|
+
) {
|
|
1650
|
+
return constant(false);
|
|
1651
|
+
}
|
|
1652
|
+
const leftValueInt = leftExpression.value as number;
|
|
1653
|
+
const rightValueInt = rightExpression.value as number;
|
|
1654
|
+
return constant(!!(leftValueInt & rightValueInt));
|
|
1655
|
+
}
|
|
1656
|
+
case "In": {
|
|
1657
|
+
if (
|
|
1658
|
+
leftExpression.value === null ||
|
|
1659
|
+
leftExpression.value === undefined ||
|
|
1660
|
+
rightExpression.value === null ||
|
|
1661
|
+
rightExpression.value === undefined
|
|
1662
|
+
) {
|
|
1663
|
+
return constant(false);
|
|
1664
|
+
}
|
|
1665
|
+
// Check all the children of the right expression are constants
|
|
1666
|
+
const allChildrenConstants = (rightExpression.value as T[]).every((item) => isConstant(item));
|
|
1667
|
+
if (allChildrenConstants) {
|
|
1668
|
+
const rightValues = (rightExpression.value as ConstantExpression<T>[]).map((item) => item.value);
|
|
1669
|
+
return constant(rightValues.includes(leftExpression.value));
|
|
1670
|
+
} else {
|
|
1671
|
+
return {
|
|
1672
|
+
_type: "Comparison",
|
|
1673
|
+
operator: operator,
|
|
1674
|
+
operand1: leftExpression,
|
|
1675
|
+
operand2: rightExpression
|
|
1676
|
+
};
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1208
1679
|
}
|
|
1209
1680
|
} else {
|
|
1210
1681
|
return {
|
|
@@ -1359,6 +1830,20 @@ export function lessThan<T extends DefinedPrimitiveType>(
|
|
|
1359
1830
|
return comparison("<", leftOperand, rightOperand);
|
|
1360
1831
|
}
|
|
1361
1832
|
|
|
1833
|
+
/**
|
|
1834
|
+
* Comparison: "Include" (In).
|
|
1835
|
+
* @template T The target type
|
|
1836
|
+
* @param leftOperand The operand on the left side
|
|
1837
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
1838
|
+
* @returns An expression representing the comparison
|
|
1839
|
+
*/
|
|
1840
|
+
export function includes<T extends DefinedPrimitiveType>(
|
|
1841
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
1842
|
+
rightOperand: ExpressionOrPrimitive<T[]>
|
|
1843
|
+
): BindingToolkitExpression<boolean> {
|
|
1844
|
+
return comparison("In", leftOperand, rightOperand as ExpressionOrPrimitive<T>);
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1362
1847
|
/**
|
|
1363
1848
|
* If-then-else expression.
|
|
1364
1849
|
*
|
|
@@ -1584,7 +2069,7 @@ export function formatResult<T, U extends Fn<T>>(
|
|
|
1584
2069
|
}
|
|
1585
2070
|
|
|
1586
2071
|
type BindingConstraints = {
|
|
1587
|
-
scale?: number;
|
|
2072
|
+
scale?: number | string;
|
|
1588
2073
|
precision?: number;
|
|
1589
2074
|
maxLength?: number;
|
|
1590
2075
|
nullable?: boolean;
|
|
@@ -1664,16 +2149,18 @@ export function formatWithTypeInformation<T>(
|
|
|
1664
2149
|
parseAsString: false
|
|
1665
2150
|
});
|
|
1666
2151
|
}
|
|
1667
|
-
if (outExpression.type === "sap.ui.model.odata.type.String" && isProperty(property)) {
|
|
2152
|
+
if (outExpression.type === "sap.ui.model.odata.type.String" && (isProperty(property) || isActionParameter(property))) {
|
|
1668
2153
|
if (outExpression.constraints?.isDigitSequence || (outExpression.constraints?.nullable !== false && property.nullable === true)) {
|
|
1669
2154
|
outExpression.formatOptions.parseKeepsEmptyString = false;
|
|
1670
2155
|
} else {
|
|
1671
2156
|
outExpression.formatOptions.parseKeepsEmptyString = true;
|
|
1672
2157
|
}
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
2158
|
+
if (isProperty(property)) {
|
|
2159
|
+
const fiscalType = getFiscalType(property);
|
|
2160
|
+
if (fiscalType) {
|
|
2161
|
+
outExpression.formatOptions.fiscalType = fiscalType;
|
|
2162
|
+
outExpression.type = "sap.fe.core.type.FiscalDate";
|
|
2163
|
+
}
|
|
1677
2164
|
}
|
|
1678
2165
|
}
|
|
1679
2166
|
const typesSupportingParseEmptyValueToZero = [
|
|
@@ -1899,6 +2386,51 @@ export function isEmpty(expression: BindingToolkitExpression<string>): BindingTo
|
|
|
1899
2386
|
});
|
|
1900
2387
|
return and(...aBindings);
|
|
1901
2388
|
}
|
|
2389
|
+
/**
|
|
2390
|
+
* Shortcut function to determine if a binding can be statically resolvable.
|
|
2391
|
+
* @param exp The expression to evaluate
|
|
2392
|
+
* @returns A Boolean evaluating if there is no relative path dependent on the current context
|
|
2393
|
+
*/
|
|
2394
|
+
export function isExpressionStaticallyResolvable<T extends PrimitiveType>(exp: BindingToolkitExpression<T>): boolean {
|
|
2395
|
+
const referencedPaths: string[] = [];
|
|
2396
|
+
transformRecursively(
|
|
2397
|
+
exp,
|
|
2398
|
+
"PathInModel",
|
|
2399
|
+
(pathExp) => {
|
|
2400
|
+
if (pathExp.modelName === undefined && typeof pathExp.path === "string") {
|
|
2401
|
+
referencedPaths.push(pathExp.path);
|
|
2402
|
+
}
|
|
2403
|
+
return pathExp;
|
|
2404
|
+
},
|
|
2405
|
+
true
|
|
2406
|
+
);
|
|
2407
|
+
if (referencedPaths.length === 0) {
|
|
2408
|
+
return true;
|
|
2409
|
+
}
|
|
2410
|
+
return referencedPaths.every((p) => p.startsWith("/"));
|
|
2411
|
+
}
|
|
2412
|
+
|
|
2413
|
+
export function getStaticallyResolvableExpression<T extends PrimitiveType>(
|
|
2414
|
+
exp: BindingToolkitExpression<T>,
|
|
2415
|
+
defaultValue: BindingToolkitExpression<T>
|
|
2416
|
+
): BindingToolkitExpression<T> {
|
|
2417
|
+
if (exp._type === "Set") {
|
|
2418
|
+
const newOperands = exp.operands.map((operand: BindingToolkitExpression<boolean>) => {
|
|
2419
|
+
if (isExpressionStaticallyResolvable(operand) || isConstant(operand)) {
|
|
2420
|
+
return operand;
|
|
2421
|
+
} else {
|
|
2422
|
+
return defaultValue;
|
|
2423
|
+
}
|
|
2424
|
+
});
|
|
2425
|
+
|
|
2426
|
+
if (exp.operator === "||") {
|
|
2427
|
+
return or(...(newOperands as unknown as BindingToolkitExpression<boolean>[])) as unknown as BindingToolkitExpression<T>;
|
|
2428
|
+
} else {
|
|
2429
|
+
return and(...(newOperands as unknown as BindingToolkitExpression<boolean>[])) as unknown as BindingToolkitExpression<T>;
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
return isExpressionStaticallyResolvable(exp) ? exp : defaultValue;
|
|
2433
|
+
}
|
|
1902
2434
|
|
|
1903
2435
|
export function concat(...inExpressions: ExpressionOrPrimitive<string>[]): BindingToolkitExpression<string> {
|
|
1904
2436
|
const expressions = inExpressions.map(wrapPrimitive);
|
|
@@ -2048,6 +2580,21 @@ export function transformRecursively<T extends PrimitiveType | unknown, ET exten
|
|
|
2048
2580
|
expression = comparison(expression.operator, operand1, operand2) as BindingToolkitExpression<T>;
|
|
2049
2581
|
}
|
|
2050
2582
|
break;
|
|
2583
|
+
case "Arithmetic":
|
|
2584
|
+
const operand1 = transformRecursively(
|
|
2585
|
+
expression.operand1 as BindingToolkitExpression<T>,
|
|
2586
|
+
expressionType,
|
|
2587
|
+
transformFunction,
|
|
2588
|
+
includeAllExpression
|
|
2589
|
+
);
|
|
2590
|
+
const operand2 = transformRecursively(
|
|
2591
|
+
expression.operand2 as BindingToolkitExpression<T>,
|
|
2592
|
+
expressionType,
|
|
2593
|
+
transformFunction,
|
|
2594
|
+
includeAllExpression
|
|
2595
|
+
);
|
|
2596
|
+
expression = arithmetic(expression.operator, operand1, operand2) as BindingToolkitExpression<T>;
|
|
2597
|
+
break;
|
|
2051
2598
|
case "Constant":
|
|
2052
2599
|
const constantValue: Record<string, BindingToolkitExpression<unknown>> = expression.value as Record<
|
|
2053
2600
|
string,
|
|
@@ -2364,6 +2911,9 @@ export function compileExpression<T extends PrimitiveType>(
|
|
|
2364
2911
|
case "Not":
|
|
2365
2912
|
const notExpression = `!${compileExpression(expr.operand, true)}`;
|
|
2366
2913
|
return wrapBindingExpression(notExpression, embeddedInBinding);
|
|
2914
|
+
case "Arithmetic":
|
|
2915
|
+
const arithmeticExpression = compileArithmeticExpression(expr);
|
|
2916
|
+
return wrapBindingExpression(arithmeticExpression, embeddedInBinding);
|
|
2367
2917
|
|
|
2368
2918
|
case "Truthy":
|
|
2369
2919
|
const truthyExpression = `!!${compileExpression(expr.operand, true)}`;
|
|
@@ -2382,6 +2932,25 @@ export function compileExpression<T extends PrimitiveType>(
|
|
|
2382
2932
|
}
|
|
2383
2933
|
}
|
|
2384
2934
|
|
|
2935
|
+
function compileArithmeticExpression(expression: ArithmeticExpression): string {
|
|
2936
|
+
function compileOperand(operand: BindingToolkitExpression<unknown>): CompiledBindingToolkitExpression {
|
|
2937
|
+
const compiledOperand = compileExpression(operand, true) ?? "undefined";
|
|
2938
|
+
return wrapBindingExpression(compiledOperand, true, needParenthesis(operand));
|
|
2939
|
+
}
|
|
2940
|
+
switch (expression.operator) {
|
|
2941
|
+
case "Neg":
|
|
2942
|
+
return `-(${compileOperand(expression.operand1)})`;
|
|
2943
|
+
case "Floor":
|
|
2944
|
+
return `Math.floor(${compileOperand(expression.operand1)})`;
|
|
2945
|
+
case "%":
|
|
2946
|
+
case "/":
|
|
2947
|
+
case "*":
|
|
2948
|
+
case "+":
|
|
2949
|
+
case "-":
|
|
2950
|
+
return `${compileOperand(expression.operand1)} ${expression.operator} ${compileOperand(expression.operand2)}`;
|
|
2951
|
+
}
|
|
2952
|
+
}
|
|
2953
|
+
|
|
2385
2954
|
/**
|
|
2386
2955
|
* Compile a comparison expression.
|
|
2387
2956
|
* @param expression The comparison expression.
|
|
@@ -2392,8 +2961,25 @@ function compileComparisonExpression(expression: ComparisonExpression): string {
|
|
|
2392
2961
|
const compiledOperand = compileExpression(operand, true) ?? "undefined";
|
|
2393
2962
|
return wrapBindingExpression(compiledOperand, true, needParenthesis(operand));
|
|
2394
2963
|
}
|
|
2395
|
-
|
|
2396
|
-
|
|
2964
|
+
switch (expression.operator) {
|
|
2965
|
+
case "In": {
|
|
2966
|
+
const path = compileOperand(expression.operand1);
|
|
2967
|
+
const collection = compileOperand(expression.operand2) ?? [];
|
|
2968
|
+
return `${collection}.includes(${path})`;
|
|
2969
|
+
}
|
|
2970
|
+
case "Has": {
|
|
2971
|
+
const path = compileOperand(expression.operand1);
|
|
2972
|
+
const flags = compileOperand(expression.operand2) ?? [];
|
|
2973
|
+
return `(${path} & ${flags}) > 0`;
|
|
2974
|
+
}
|
|
2975
|
+
case "===":
|
|
2976
|
+
case "!==":
|
|
2977
|
+
case ">=":
|
|
2978
|
+
case ">":
|
|
2979
|
+
case "<=":
|
|
2980
|
+
case "<":
|
|
2981
|
+
return `${compileOperand(expression.operand1)} ${expression.operator} ${compileOperand(expression.operand2)}`;
|
|
2982
|
+
}
|
|
2397
2983
|
}
|
|
2398
2984
|
|
|
2399
2985
|
/**
|