@itwin/grouping-mapping-widget 0.3.0 → 0.3.3
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/lib/cjs/formula/FormulaFunctionProvider.d.ts +18 -0
- package/lib/cjs/formula/FormulaFunctionProvider.js +136 -0
- package/lib/cjs/formula/FormulaFunctionProvider.js.map +1 -0
- package/lib/cjs/formula/FormulaOperatorsProvider.d.ts +34 -0
- package/lib/cjs/formula/FormulaOperatorsProvider.js +185 -0
- package/lib/cjs/formula/FormulaOperatorsProvider.js.map +1 -0
- package/lib/cjs/formula/FormulaSplitter.d.ts +2 -0
- package/lib/cjs/formula/FormulaSplitter.js +140 -0
- package/lib/cjs/formula/FormulaSplitter.js.map +1 -0
- package/lib/cjs/formula/FormulaTokensValidator.d.ts +5 -0
- package/lib/cjs/formula/FormulaTokensValidator.js +135 -0
- package/lib/cjs/formula/FormulaTokensValidator.js.map +1 -0
- package/lib/cjs/formula/FormulaValidator.d.ts +3 -0
- package/lib/cjs/formula/FormulaValidator.js +35 -0
- package/lib/cjs/formula/FormulaValidator.js.map +1 -0
- package/lib/cjs/formula/IResult.d.ts +5 -0
- package/lib/cjs/formula/IResult.js +3 -0
- package/lib/cjs/formula/IResult.js.map +1 -0
- package/lib/cjs/formula/InfixToPostfixConverter.d.ts +18 -0
- package/lib/cjs/formula/InfixToPostfixConverter.js +299 -0
- package/lib/cjs/formula/InfixToPostfixConverter.js.map +1 -0
- package/lib/cjs/formula/InputStream.d.ts +12 -0
- package/lib/cjs/formula/InputStream.js +36 -0
- package/lib/cjs/formula/InputStream.js.map +1 -0
- package/lib/cjs/formula/ParenthesisValidator.d.ts +7 -0
- package/lib/cjs/formula/ParenthesisValidator.js +34 -0
- package/lib/cjs/formula/ParenthesisValidator.js.map +1 -0
- package/lib/cjs/formula/Queue.d.ts +11 -0
- package/lib/cjs/formula/Queue.js +42 -0
- package/lib/cjs/formula/Queue.js.map +1 -0
- package/lib/cjs/formula/Stack.d.ts +14 -0
- package/lib/cjs/formula/Stack.js +71 -0
- package/lib/cjs/formula/Stack.js.map +1 -0
- package/lib/cjs/formula/StringBuilder.d.ts +9 -0
- package/lib/cjs/formula/StringBuilder.js +26 -0
- package/lib/cjs/formula/StringBuilder.js.map +1 -0
- package/lib/cjs/formula/Types.d.ts +8 -0
- package/lib/cjs/formula/Types.js +3 -0
- package/lib/cjs/formula/Types.js.map +1 -0
- package/lib/cjs/formula/Utils.d.ts +7 -0
- package/lib/cjs/formula/Utils.js +39 -0
- package/lib/cjs/formula/Utils.js.map +1 -0
- package/lib/cjs/widget/GroupingMappingWidget.d.ts +4 -0
- package/lib/cjs/widget/GroupingMappingWidget.js +6 -23
- package/lib/cjs/widget/GroupingMappingWidget.js.map +1 -1
- package/lib/cjs/widget/components/CalculatedPropertyAction.d.ts +3 -3
- package/lib/cjs/widget/components/CalculatedPropertyAction.js +15 -10
- package/lib/cjs/widget/components/CalculatedPropertyAction.js.map +1 -1
- package/lib/cjs/widget/components/CalculatedPropertyTable.d.ts +9 -6
- package/lib/cjs/widget/components/CalculatedPropertyTable.js +8 -33
- package/lib/cjs/widget/components/CalculatedPropertyTable.js.map +1 -1
- package/lib/cjs/widget/components/ConfirmMappingsImport.d.ts +3 -3
- package/lib/cjs/widget/components/ConfirmMappingsImport.js +6 -3
- package/lib/cjs/widget/components/ConfirmMappingsImport.js.map +1 -1
- package/lib/cjs/widget/components/ConfirmMappingsImport.scss +4 -2
- package/lib/cjs/widget/components/CustomCalculationAction.d.ts +6 -4
- package/lib/cjs/widget/components/CustomCalculationAction.js +23 -12
- package/lib/cjs/widget/components/CustomCalculationAction.js.map +1 -1
- package/lib/cjs/widget/components/CustomCalculationTable.d.ts +9 -6
- package/lib/cjs/widget/components/CustomCalculationTable.js +8 -33
- package/lib/cjs/widget/components/CustomCalculationTable.js.map +1 -1
- package/lib/cjs/widget/components/GroupAction.d.ts +2 -2
- package/lib/cjs/widget/components/GroupAction.js +25 -51
- package/lib/cjs/widget/components/GroupAction.js.map +1 -1
- package/lib/cjs/widget/components/GroupPropertyAction.d.ts +1 -1
- package/lib/cjs/widget/components/GroupPropertyAction.js +12 -8
- package/lib/cjs/widget/components/GroupPropertyAction.js.map +1 -1
- package/lib/cjs/widget/components/GroupPropertyTable.d.ts +9 -6
- package/lib/cjs/widget/components/GroupPropertyTable.js +8 -33
- package/lib/cjs/widget/components/GroupPropertyTable.js.map +1 -1
- package/lib/cjs/widget/components/Grouping.d.ts +3 -3
- package/lib/cjs/widget/components/Grouping.js +22 -22
- package/lib/cjs/widget/components/Grouping.js.map +1 -1
- package/lib/cjs/widget/components/GroupingMapping.d.ts +12 -2
- package/lib/cjs/widget/components/GroupingMapping.js +18 -4
- package/lib/cjs/widget/components/GroupingMapping.js.map +1 -1
- package/lib/cjs/widget/components/Mapping.d.ts +2 -2
- package/lib/cjs/widget/components/Mapping.js +14 -14
- package/lib/cjs/widget/components/Mapping.js.map +1 -1
- package/lib/cjs/widget/components/MappingAction.d.ts +2 -2
- package/lib/cjs/widget/components/MappingAction.js +8 -13
- package/lib/cjs/widget/components/MappingAction.js.map +1 -1
- package/lib/cjs/widget/components/MappingImportWizardModal.js +2 -2
- package/lib/cjs/widget/components/MappingImportWizardModal.js.map +1 -1
- package/lib/cjs/widget/components/MappingImportWizardModal.scss +6 -2
- package/lib/cjs/widget/components/PropertyMenu.d.ts +2 -2
- package/lib/cjs/widget/components/PropertyMenu.js +68 -21
- package/lib/cjs/widget/components/PropertyMenu.js.map +1 -1
- package/lib/cjs/widget/components/SelectIModel.js +4 -8
- package/lib/cjs/widget/components/SelectIModel.js.map +1 -1
- package/lib/cjs/widget/components/SelectIModel.scss +2 -1
- package/lib/cjs/widget/components/SelectMapping.scss +2 -1
- package/lib/cjs/widget/components/SelectMappings.d.ts +2 -2
- package/lib/cjs/widget/components/SelectMappings.js +10 -11
- package/lib/cjs/widget/components/SelectMappings.js.map +1 -1
- package/lib/cjs/widget/components/SelectProject.js +12 -16
- package/lib/cjs/widget/components/SelectProject.js.map +1 -1
- package/lib/cjs/widget/components/SelectProject.scss +3 -8
- package/lib/cjs/widget/hooks/useFetchData.d.ts +9 -0
- package/lib/cjs/widget/hooks/useFetchData.js +41 -0
- package/lib/cjs/widget/hooks/useFetchData.js.map +1 -0
- package/lib/cjs/widget/hooks/useFormulaValidation.d.ts +6 -0
- package/lib/cjs/widget/hooks/useFormulaValidation.js +29 -0
- package/lib/cjs/widget/hooks/useFormulaValidation.js.map +1 -0
- package/lib/cjs/widget/utils.d.ts +1 -0
- package/lib/cjs/widget/utils.js +9 -0
- package/lib/cjs/widget/utils.js.map +1 -1
- package/lib/esm/formula/FormulaFunctionProvider.d.ts +18 -0
- package/lib/esm/formula/FormulaFunctionProvider.js +130 -0
- package/lib/esm/formula/FormulaFunctionProvider.js.map +1 -0
- package/lib/esm/formula/FormulaOperatorsProvider.d.ts +34 -0
- package/lib/esm/formula/FormulaOperatorsProvider.js +174 -0
- package/lib/esm/formula/FormulaOperatorsProvider.js.map +1 -0
- package/lib/esm/formula/FormulaSplitter.d.ts +2 -0
- package/lib/esm/formula/FormulaSplitter.js +136 -0
- package/lib/esm/formula/FormulaSplitter.js.map +1 -0
- package/lib/esm/formula/FormulaTokensValidator.d.ts +5 -0
- package/lib/esm/formula/FormulaTokensValidator.js +131 -0
- package/lib/esm/formula/FormulaTokensValidator.js.map +1 -0
- package/lib/esm/formula/FormulaValidator.d.ts +3 -0
- package/lib/esm/formula/FormulaValidator.js +31 -0
- package/lib/esm/formula/FormulaValidator.js.map +1 -0
- package/lib/esm/formula/IResult.d.ts +5 -0
- package/lib/esm/formula/IResult.js +2 -0
- package/lib/esm/formula/IResult.js.map +1 -0
- package/lib/esm/formula/InfixToPostfixConverter.d.ts +18 -0
- package/lib/esm/formula/InfixToPostfixConverter.js +295 -0
- package/lib/esm/formula/InfixToPostfixConverter.js.map +1 -0
- package/lib/esm/formula/InputStream.d.ts +12 -0
- package/lib/esm/formula/InputStream.js +32 -0
- package/lib/esm/formula/InputStream.js.map +1 -0
- package/lib/esm/formula/ParenthesisValidator.d.ts +7 -0
- package/lib/esm/formula/ParenthesisValidator.js +30 -0
- package/lib/esm/formula/ParenthesisValidator.js.map +1 -0
- package/lib/esm/formula/Queue.d.ts +11 -0
- package/lib/esm/formula/Queue.js +38 -0
- package/lib/esm/formula/Queue.js.map +1 -0
- package/lib/esm/formula/Stack.d.ts +14 -0
- package/lib/esm/formula/Stack.js +67 -0
- package/lib/esm/formula/Stack.js.map +1 -0
- package/lib/esm/formula/StringBuilder.d.ts +9 -0
- package/lib/esm/formula/StringBuilder.js +22 -0
- package/lib/esm/formula/StringBuilder.js.map +1 -0
- package/lib/esm/formula/Types.d.ts +8 -0
- package/lib/esm/formula/Types.js +2 -0
- package/lib/esm/formula/Types.js.map +1 -0
- package/lib/esm/formula/Utils.d.ts +7 -0
- package/lib/esm/formula/Utils.js +30 -0
- package/lib/esm/formula/Utils.js.map +1 -0
- package/lib/esm/widget/GroupingMappingWidget.d.ts +4 -0
- package/lib/esm/widget/GroupingMappingWidget.js +6 -4
- package/lib/esm/widget/GroupingMappingWidget.js.map +1 -1
- package/lib/esm/widget/components/CalculatedPropertyAction.d.ts +3 -3
- package/lib/esm/widget/components/CalculatedPropertyAction.js +16 -11
- package/lib/esm/widget/components/CalculatedPropertyAction.js.map +1 -1
- package/lib/esm/widget/components/CalculatedPropertyTable.d.ts +9 -6
- package/lib/esm/widget/components/CalculatedPropertyTable.js +9 -34
- package/lib/esm/widget/components/CalculatedPropertyTable.js.map +1 -1
- package/lib/esm/widget/components/ConfirmMappingsImport.d.ts +3 -3
- package/lib/esm/widget/components/ConfirmMappingsImport.js +7 -4
- package/lib/esm/widget/components/ConfirmMappingsImport.js.map +1 -1
- package/lib/esm/widget/components/ConfirmMappingsImport.scss +4 -2
- package/lib/esm/widget/components/CustomCalculationAction.d.ts +6 -4
- package/lib/esm/widget/components/CustomCalculationAction.js +24 -13
- package/lib/esm/widget/components/CustomCalculationAction.js.map +1 -1
- package/lib/esm/widget/components/CustomCalculationTable.d.ts +9 -6
- package/lib/esm/widget/components/CustomCalculationTable.js +9 -34
- package/lib/esm/widget/components/CustomCalculationTable.js.map +1 -1
- package/lib/esm/widget/components/GroupAction.d.ts +2 -2
- package/lib/esm/widget/components/GroupAction.js +26 -52
- package/lib/esm/widget/components/GroupAction.js.map +1 -1
- package/lib/esm/widget/components/GroupPropertyAction.d.ts +1 -1
- package/lib/esm/widget/components/GroupPropertyAction.js +13 -9
- package/lib/esm/widget/components/GroupPropertyAction.js.map +1 -1
- package/lib/esm/widget/components/GroupPropertyTable.d.ts +9 -6
- package/lib/esm/widget/components/GroupPropertyTable.js +9 -34
- package/lib/esm/widget/components/GroupPropertyTable.js.map +1 -1
- package/lib/esm/widget/components/Grouping.d.ts +3 -3
- package/lib/esm/widget/components/Grouping.js +23 -23
- package/lib/esm/widget/components/Grouping.js.map +1 -1
- package/lib/esm/widget/components/GroupingMapping.d.ts +12 -2
- package/lib/esm/widget/components/GroupingMapping.js +17 -4
- package/lib/esm/widget/components/GroupingMapping.js.map +1 -1
- package/lib/esm/widget/components/Mapping.d.ts +2 -2
- package/lib/esm/widget/components/Mapping.js +15 -15
- package/lib/esm/widget/components/Mapping.js.map +1 -1
- package/lib/esm/widget/components/MappingAction.d.ts +2 -2
- package/lib/esm/widget/components/MappingAction.js +9 -14
- package/lib/esm/widget/components/MappingAction.js.map +1 -1
- package/lib/esm/widget/components/MappingImportWizardModal.js +2 -2
- package/lib/esm/widget/components/MappingImportWizardModal.js.map +1 -1
- package/lib/esm/widget/components/MappingImportWizardModal.scss +6 -2
- package/lib/esm/widget/components/PropertyMenu.d.ts +2 -2
- package/lib/esm/widget/components/PropertyMenu.js +69 -22
- package/lib/esm/widget/components/PropertyMenu.js.map +1 -1
- package/lib/esm/widget/components/SelectIModel.js +5 -6
- package/lib/esm/widget/components/SelectIModel.js.map +1 -1
- package/lib/esm/widget/components/SelectIModel.scss +2 -1
- package/lib/esm/widget/components/SelectMapping.scss +2 -1
- package/lib/esm/widget/components/SelectMappings.d.ts +2 -2
- package/lib/esm/widget/components/SelectMappings.js +11 -12
- package/lib/esm/widget/components/SelectMappings.js.map +1 -1
- package/lib/esm/widget/components/SelectProject.js +13 -14
- package/lib/esm/widget/components/SelectProject.js.map +1 -1
- package/lib/esm/widget/components/SelectProject.scss +3 -8
- package/lib/esm/widget/hooks/useFetchData.d.ts +9 -0
- package/lib/esm/widget/hooks/useFetchData.js +35 -0
- package/lib/esm/widget/hooks/useFetchData.js.map +1 -0
- package/lib/esm/widget/hooks/useFormulaValidation.d.ts +6 -0
- package/lib/esm/widget/hooks/useFormulaValidation.js +25 -0
- package/lib/esm/widget/hooks/useFormulaValidation.js.map +1 -0
- package/lib/esm/widget/utils.d.ts +1 -0
- package/lib/esm/widget/utils.js +7 -1
- package/lib/esm/widget/utils.js.map +1 -1
- package/package.json +3 -2
- package/lib/cjs/api/generated/api.d.ts +0 -3222
- package/lib/cjs/api/generated/api.js +0 -5291
- package/lib/cjs/api/generated/api.js.map +0 -1
- package/lib/cjs/api/generated/configuration.d.ts +0 -56
- package/lib/cjs/api/generated/configuration.js +0 -30
- package/lib/cjs/api/generated/configuration.js.map +0 -1
- package/lib/cjs/api/generated/index.d.ts +0 -14
- package/lib/cjs/api/generated/index.js +0 -31
- package/lib/cjs/api/generated/index.js.map +0 -1
- package/lib/cjs/api/reportingClient.d.ts +0 -34
- package/lib/cjs/api/reportingClient.js +0 -177
- package/lib/cjs/api/reportingClient.js.map +0 -1
- package/lib/cjs/widget/hooks/useFetchAccessToken.d.ts +0 -3
- package/lib/cjs/widget/hooks/useFetchAccessToken.js +0 -22
- package/lib/cjs/widget/hooks/useFetchAccessToken.js.map +0 -1
- package/lib/esm/api/generated/api.d.ts +0 -3222
- package/lib/esm/api/generated/api.js +0 -5248
- package/lib/esm/api/generated/api.js.map +0 -1
- package/lib/esm/api/generated/configuration.d.ts +0 -56
- package/lib/esm/api/generated/configuration.js +0 -26
- package/lib/esm/api/generated/configuration.js.map +0 -1
- package/lib/esm/api/generated/index.d.ts +0 -14
- package/lib/esm/api/generated/index.js +0 -19
- package/lib/esm/api/generated/index.js.map +0 -1
- package/lib/esm/api/reportingClient.d.ts +0 -34
- package/lib/esm/api/reportingClient.js +0 -173
- package/lib/esm/api/reportingClient.js.map +0 -1
- package/lib/esm/widget/hooks/useFetchAccessToken.d.ts +0 -3
- package/lib/esm/widget/hooks/useFetchAccessToken.js +0 -20
- package/lib/esm/widget/hooks/useFetchAccessToken.js.map +0 -1
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
const allOperators = ["+", "-", "*", "%", "**", "/", "`", "~", "!", "@", "#", "$", "^", "&", "=", "[", "]", "{", "}", "\\", "|", ";", ":", "'", "\"", "<", ">", "?", "+=", "-=", "*=", "/=", "%=", "&=", "^=", "|=", "?=", "==", "!=", ">=", "<=", "++", "--", "<<", ">>", "&&", "||", "??", "?.", "**=", "<<=", ">>=", "&&=", "||=", "??=", "===", "!==", ">>>", ">>>="];
|
|
2
|
+
export var OperatorType;
|
|
3
|
+
(function (OperatorType) {
|
|
4
|
+
OperatorType[OperatorType["UnaryPlus"] = 0] = "UnaryPlus";
|
|
5
|
+
OperatorType[OperatorType["UnaryNegation"] = 1] = "UnaryNegation";
|
|
6
|
+
OperatorType[OperatorType["Exponentiation"] = 2] = "Exponentiation";
|
|
7
|
+
OperatorType[OperatorType["Multiplication"] = 3] = "Multiplication";
|
|
8
|
+
OperatorType[OperatorType["Division"] = 4] = "Division";
|
|
9
|
+
OperatorType[OperatorType["Remainder"] = 5] = "Remainder";
|
|
10
|
+
OperatorType[OperatorType["Addition"] = 6] = "Addition";
|
|
11
|
+
OperatorType[OperatorType["Subtraction"] = 7] = "Subtraction";
|
|
12
|
+
OperatorType[OperatorType["LogicalNot"] = 8] = "LogicalNot";
|
|
13
|
+
OperatorType[OperatorType["LessThan"] = 9] = "LessThan";
|
|
14
|
+
OperatorType[OperatorType["LessThanOrEqual"] = 10] = "LessThanOrEqual";
|
|
15
|
+
OperatorType[OperatorType["GreaterThan"] = 11] = "GreaterThan";
|
|
16
|
+
OperatorType[OperatorType["GreaterThanOrEqual"] = 12] = "GreaterThanOrEqual";
|
|
17
|
+
OperatorType[OperatorType["Equality"] = 13] = "Equality";
|
|
18
|
+
OperatorType[OperatorType["Inequality"] = 14] = "Inequality";
|
|
19
|
+
OperatorType[OperatorType["LogicalAnd"] = 15] = "LogicalAnd";
|
|
20
|
+
OperatorType[OperatorType["LogicalOr"] = 16] = "LogicalOr";
|
|
21
|
+
})(OperatorType || (OperatorType = {}));
|
|
22
|
+
export var OperatorAssociativity;
|
|
23
|
+
(function (OperatorAssociativity) {
|
|
24
|
+
OperatorAssociativity[OperatorAssociativity["Left"] = 0] = "Left";
|
|
25
|
+
OperatorAssociativity[OperatorAssociativity["Right"] = 1] = "Right";
|
|
26
|
+
})(OperatorAssociativity || (OperatorAssociativity = {}));
|
|
27
|
+
export function isOperator(token) {
|
|
28
|
+
return allOperators.includes(token);
|
|
29
|
+
}
|
|
30
|
+
export function getBinaryOperator(token) {
|
|
31
|
+
switch (token) {
|
|
32
|
+
case "**": return OperatorType.Exponentiation;
|
|
33
|
+
case "*": return OperatorType.Multiplication;
|
|
34
|
+
case "/": return OperatorType.Division;
|
|
35
|
+
case "%": return OperatorType.Remainder;
|
|
36
|
+
case "+": return OperatorType.Addition;
|
|
37
|
+
case "-": return OperatorType.Subtraction;
|
|
38
|
+
case "<": return OperatorType.LessThan;
|
|
39
|
+
case "<=": return OperatorType.LessThanOrEqual;
|
|
40
|
+
case ">": return OperatorType.GreaterThan;
|
|
41
|
+
case ">=": return OperatorType.GreaterThanOrEqual;
|
|
42
|
+
case "==": return OperatorType.Equality;
|
|
43
|
+
case "!=": return OperatorType.Inequality;
|
|
44
|
+
case "&&": return OperatorType.LogicalAnd;
|
|
45
|
+
case "||": return OperatorType.LogicalOr;
|
|
46
|
+
default: return undefined;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function getUnaryOperator(token) {
|
|
50
|
+
switch (token) {
|
|
51
|
+
case "+": return OperatorType.UnaryPlus;
|
|
52
|
+
case "-": return OperatorType.UnaryNegation;
|
|
53
|
+
case "!": return OperatorType.LogicalNot;
|
|
54
|
+
default: return undefined;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
|
|
58
|
+
export function getOperatorPrecedence(op) {
|
|
59
|
+
switch (op) {
|
|
60
|
+
case OperatorType.UnaryPlus:
|
|
61
|
+
case OperatorType.UnaryNegation:
|
|
62
|
+
case OperatorType.LogicalNot:
|
|
63
|
+
return 15;
|
|
64
|
+
case OperatorType.Exponentiation:
|
|
65
|
+
return 14;
|
|
66
|
+
case OperatorType.Multiplication:
|
|
67
|
+
case OperatorType.Division:
|
|
68
|
+
case OperatorType.Remainder:
|
|
69
|
+
return 13;
|
|
70
|
+
case OperatorType.Subtraction:
|
|
71
|
+
case OperatorType.Addition:
|
|
72
|
+
return 12;
|
|
73
|
+
case OperatorType.LessThan:
|
|
74
|
+
case OperatorType.LessThanOrEqual:
|
|
75
|
+
case OperatorType.GreaterThan:
|
|
76
|
+
case OperatorType.GreaterThanOrEqual:
|
|
77
|
+
return 10;
|
|
78
|
+
case OperatorType.Equality:
|
|
79
|
+
case OperatorType.Inequality:
|
|
80
|
+
return 9;
|
|
81
|
+
case OperatorType.LogicalAnd:
|
|
82
|
+
return 5;
|
|
83
|
+
case OperatorType.LogicalOr:
|
|
84
|
+
return 4;
|
|
85
|
+
default: return 1;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export function getOperatorAssociativity(op) {
|
|
89
|
+
switch (op) {
|
|
90
|
+
case OperatorType.UnaryPlus:
|
|
91
|
+
case OperatorType.UnaryNegation:
|
|
92
|
+
case OperatorType.Exponentiation:
|
|
93
|
+
case OperatorType.LogicalNot:
|
|
94
|
+
return OperatorAssociativity.Right;
|
|
95
|
+
case OperatorType.Multiplication:
|
|
96
|
+
case OperatorType.Division:
|
|
97
|
+
case OperatorType.Remainder:
|
|
98
|
+
case OperatorType.Addition:
|
|
99
|
+
case OperatorType.Subtraction:
|
|
100
|
+
case OperatorType.LessThan:
|
|
101
|
+
case OperatorType.LessThanOrEqual:
|
|
102
|
+
case OperatorType.GreaterThan:
|
|
103
|
+
case OperatorType.GreaterThanOrEqual:
|
|
104
|
+
case OperatorType.Equality:
|
|
105
|
+
case OperatorType.Inequality:
|
|
106
|
+
case OperatorType.LogicalAnd:
|
|
107
|
+
case OperatorType.LogicalOr:
|
|
108
|
+
return OperatorAssociativity.Left;
|
|
109
|
+
default:
|
|
110
|
+
return OperatorAssociativity.Left;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
export function isSupportedOperator(token) {
|
|
114
|
+
return undefined !== getUnaryOperator(token) || undefined !== getBinaryOperator(token);
|
|
115
|
+
}
|
|
116
|
+
export function getOperatorArgumentCountBounds(token) {
|
|
117
|
+
switch (token) {
|
|
118
|
+
case "**": return [2, 2];
|
|
119
|
+
case "*": return [2, 2];
|
|
120
|
+
case "/": return [2, 2];
|
|
121
|
+
case "%": return [2, 2];
|
|
122
|
+
case "+": return [1, 2];
|
|
123
|
+
case "-": return [1, 2];
|
|
124
|
+
case "!": return [1, 1];
|
|
125
|
+
case "<": return [2, 2];
|
|
126
|
+
case "<=": return [2, 2];
|
|
127
|
+
case ">": return [2, 2];
|
|
128
|
+
case ">=": return [2, 2];
|
|
129
|
+
case "==": return [2, 2];
|
|
130
|
+
case "!=": return [2, 2];
|
|
131
|
+
case "&&": return [2, 2];
|
|
132
|
+
case "||": return [2, 2];
|
|
133
|
+
default: return undefined;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
export function getOperatorReturnType(token, arg1, arg2) {
|
|
137
|
+
if (!arg2 && !getUnaryOperator(token))
|
|
138
|
+
return { errorMessage: `Unary operator "${token}" is not supported.` };
|
|
139
|
+
if (arg2 && !getBinaryOperator(token))
|
|
140
|
+
return { errorMessage: `Binary operator "${token}" is not supported.` };
|
|
141
|
+
if ((arg1 === "undefined" || arg2 === "undefined") && (token !== "==" && token !== "!="))
|
|
142
|
+
return { errorMessage: `${!arg2 ? "Unary" : "Binary"} operator "${token}" does not support null operands.` };
|
|
143
|
+
switch (token) {
|
|
144
|
+
case "**":
|
|
145
|
+
case "*":
|
|
146
|
+
case "/":
|
|
147
|
+
case "%":
|
|
148
|
+
return arg1 === "string" || arg2 === "string" ?
|
|
149
|
+
{ errorMessage: `Binary operator "${token}" does not support string operands.` } :
|
|
150
|
+
{ value: "number" };
|
|
151
|
+
case "-":
|
|
152
|
+
return arg1 === "string" || arg2 === "string" ?
|
|
153
|
+
{ errorMessage: `${!arg2 ? "Unary" : "Binary"} operator "${token}" does not support string operands.` } :
|
|
154
|
+
{ value: "number" };
|
|
155
|
+
case "+":
|
|
156
|
+
if (!arg2)
|
|
157
|
+
return { value: arg1 };
|
|
158
|
+
else
|
|
159
|
+
return arg1 === "string" || arg2 === "string" ? { value: "string" } : { value: "number" };
|
|
160
|
+
case "!":
|
|
161
|
+
case "<":
|
|
162
|
+
case "<=":
|
|
163
|
+
case ">":
|
|
164
|
+
case ">=":
|
|
165
|
+
case "==":
|
|
166
|
+
case "!=":
|
|
167
|
+
case "&&":
|
|
168
|
+
case "||":
|
|
169
|
+
return { value: "boolean" };
|
|
170
|
+
default:
|
|
171
|
+
return { errorMessage: `Operator "${token}" is not supported.` };
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=FormulaOperatorsProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormulaOperatorsProvider.js","sourceRoot":"","sources":["../../../src/formula/FormulaOperatorsProvider.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport type { IResult } from \"./IResult\";\nimport type { DataType, PossibleDataType } from \"./Types\";\n\nconst allOperators = [\"+\", \"-\", \"*\", \"%\", \"**\", \"/\", \"`\", \"~\", \"!\", \"@\", \"#\", \"$\", \"^\", \"&\", \"=\", \"[\", \"]\", \"{\", \"}\", \"\\\\\", \"|\", \";\", \":\", \"'\", \"\\\"\", \"<\", \">\", \"?\", \"+=\", \"-=\", \"*=\", \"/=\", \"%=\", \"&=\", \"^=\", \"|=\", \"?=\", \"==\", \"!=\", \">=\", \"<=\", \"++\", \"--\", \"<<\", \">>\", \"&&\", \"||\", \"??\", \"?.\", \"**=\", \"<<=\", \">>=\", \"&&=\", \"||=\", \"??=\", \"===\", \"!==\", \">>>\", \">>>=\"];\n\nexport enum OperatorType {\n UnaryPlus,\n UnaryNegation,\n Exponentiation,\n Multiplication,\n Division,\n Remainder,\n Addition,\n Subtraction,\n LogicalNot,\n LessThan,\n LessThanOrEqual,\n GreaterThan,\n GreaterThanOrEqual,\n Equality,\n Inequality,\n LogicalAnd,\n LogicalOr,\n}\n\nexport enum OperatorAssociativity {\n Left,\n Right,\n}\n\nexport function isOperator(token: string): boolean {\n return allOperators.includes(token);\n}\n\nexport function getBinaryOperator(token: string): OperatorType | undefined {\n switch (token) {\n case \"**\": return OperatorType.Exponentiation;\n case \"*\": return OperatorType.Multiplication;\n case \"/\": return OperatorType.Division;\n case \"%\": return OperatorType.Remainder;\n case \"+\": return OperatorType.Addition;\n case \"-\": return OperatorType.Subtraction;\n case \"<\": return OperatorType.LessThan;\n case \"<=\": return OperatorType.LessThanOrEqual;\n case \">\": return OperatorType.GreaterThan;\n case \">=\": return OperatorType.GreaterThanOrEqual;\n case \"==\": return OperatorType.Equality;\n case \"!=\": return OperatorType.Inequality;\n case \"&&\": return OperatorType.LogicalAnd;\n case \"||\": return OperatorType.LogicalOr;\n default: return undefined;\n }\n}\n\nexport function getUnaryOperator(token: string): OperatorType | undefined {\n switch (token) {\n case \"+\": return OperatorType.UnaryPlus;\n case \"-\": return OperatorType.UnaryNegation;\n case \"!\": return OperatorType.LogicalNot;\n default: return undefined;\n }\n}\n\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence\nexport function getOperatorPrecedence(op: OperatorType | undefined): number {\n switch (op) {\n case OperatorType.UnaryPlus:\n case OperatorType.UnaryNegation:\n case OperatorType.LogicalNot:\n return 15;\n case OperatorType.Exponentiation:\n return 14;\n case OperatorType.Multiplication:\n case OperatorType.Division:\n case OperatorType.Remainder:\n return 13;\n case OperatorType.Subtraction:\n case OperatorType.Addition:\n return 12;\n case OperatorType.LessThan:\n case OperatorType.LessThanOrEqual:\n case OperatorType.GreaterThan:\n case OperatorType.GreaterThanOrEqual:\n return 10;\n case OperatorType.Equality:\n case OperatorType.Inequality:\n return 9;\n case OperatorType.LogicalAnd:\n return 5;\n case OperatorType.LogicalOr:\n return 4;\n default: return 1;\n }\n}\n\nexport function getOperatorAssociativity(op: OperatorType | undefined): number {\n switch (op) {\n case OperatorType.UnaryPlus:\n case OperatorType.UnaryNegation:\n case OperatorType.Exponentiation:\n case OperatorType.LogicalNot:\n return OperatorAssociativity.Right;\n case OperatorType.Multiplication:\n case OperatorType.Division:\n case OperatorType.Remainder:\n case OperatorType.Addition:\n case OperatorType.Subtraction:\n case OperatorType.LessThan:\n case OperatorType.LessThanOrEqual:\n case OperatorType.GreaterThan:\n case OperatorType.GreaterThanOrEqual:\n case OperatorType.Equality:\n case OperatorType.Inequality:\n case OperatorType.LogicalAnd:\n case OperatorType.LogicalOr:\n return OperatorAssociativity.Left;\n default:\n return OperatorAssociativity.Left;\n }\n}\n\nexport function isSupportedOperator(token: string): boolean {\n return undefined !== getUnaryOperator(token) || undefined !== getBinaryOperator(token);\n}\n\nexport function getOperatorArgumentCountBounds(token: string): [number, number] | undefined {\n switch (token) {\n case \"**\": return [2, 2];\n case \"*\": return [2, 2];\n case \"/\": return [2, 2];\n case \"%\": return [2, 2];\n case \"+\": return [1, 2];\n case \"-\": return [1, 2];\n case \"!\": return [1, 1];\n case \"<\": return [2, 2];\n case \"<=\": return [2, 2];\n case \">\": return [2, 2];\n case \">=\": return [2, 2];\n case \"==\": return [2, 2];\n case \"!=\": return [2, 2];\n case \"&&\": return [2, 2];\n case \"||\": return [2, 2];\n default: return undefined;\n }\n}\n\nexport function getOperatorReturnType(token: string, arg1: PossibleDataType, arg2?: PossibleDataType): IResult<DataType> {\n if (!arg2 && !getUnaryOperator(token))\n return { errorMessage: `Unary operator \"${token}\" is not supported.` };\n\n if (arg2 && !getBinaryOperator(token))\n return { errorMessage: `Binary operator \"${token}\" is not supported.` };\n\n if ((arg1 === \"undefined\" || arg2 === \"undefined\") && (token !== \"==\" && token !== \"!=\"))\n return { errorMessage: `${!arg2 ? \"Unary\" : \"Binary\"} operator \"${token}\" does not support null operands.` };\n\n switch (token) {\n case \"**\":\n case \"*\":\n case \"/\":\n case \"%\":\n return arg1 === \"string\" || arg2 === \"string\" ?\n { errorMessage: `Binary operator \"${token}\" does not support string operands.` } :\n { value: \"number\" };\n case \"-\":\n return arg1 === \"string\" || arg2 === \"string\" ?\n { errorMessage: `${!arg2 ? \"Unary\" : \"Binary\"} operator \"${token}\" does not support string operands.` } :\n { value: \"number\" };\n case \"+\":\n if (!arg2)\n return { value: arg1 as DataType };\n else\n return arg1 === \"string\" || arg2 === \"string\" ? { value: \"string\" } : { value: \"number\" };\n case \"!\":\n case \"<\":\n case \"<=\":\n case \">\":\n case \">=\":\n case \"==\":\n case \"!=\":\n case \"&&\":\n case \"||\":\n return { value: \"boolean\" };\n default:\n return { errorMessage: `Operator \"${token}\" is not supported.` };\n }\n}\n"]}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { InputStream } from "./InputStream";
|
|
6
|
+
import { StringBuilder } from "./StringBuilder";
|
|
7
|
+
import { isDecimalSeparator, isDigit, isLetterOrUnderscore, isStringDelimiter, isWhitespace } from "./Utils";
|
|
8
|
+
const fourSymbolCombinations = [">>>="];
|
|
9
|
+
const threeSymbolCombinations = ["**=", "<<=", ">>=", "&&=", "||=", "??=", "===", "!==", ">>>"];
|
|
10
|
+
const twoSymbolCombinations = ["+=", "-=", "*=", "/=", "%=", "&=", "^=", "|=", "?=", "==", "!=", ">=", "<=", "++", "--", "**", "<<", ">>", "&&", "||", "??", "?."];
|
|
11
|
+
const oneSymbolCombinations = ["~", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "=", "+", "[", "]", "{", "}", "\\", "|", ";", ":", ",", ".", "<", ">", "/", "?"];
|
|
12
|
+
const symbolCombinations = [
|
|
13
|
+
fourSymbolCombinations,
|
|
14
|
+
threeSymbolCombinations,
|
|
15
|
+
twoSymbolCombinations,
|
|
16
|
+
oneSymbolCombinations,
|
|
17
|
+
];
|
|
18
|
+
function parseScientificNotation(stream) {
|
|
19
|
+
const notationBuilder = new StringBuilder();
|
|
20
|
+
const nextChar = stream.next;
|
|
21
|
+
const afterEChar = stream.peek;
|
|
22
|
+
if (isDigit(afterEChar) || afterEChar === "+" || afterEChar === "-") {
|
|
23
|
+
notationBuilder.push(nextChar);
|
|
24
|
+
notationBuilder.push(stream.next);
|
|
25
|
+
while (isDigit(stream.peek)) {
|
|
26
|
+
notationBuilder.push(stream.next);
|
|
27
|
+
}
|
|
28
|
+
if (isDecimalSeparator(stream.peek)) {
|
|
29
|
+
throw new Error("The exponent in scientific notation must be an integer.");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
stream.undo;
|
|
34
|
+
}
|
|
35
|
+
return notationBuilder.value;
|
|
36
|
+
}
|
|
37
|
+
function parseNumber(stream) {
|
|
38
|
+
const numberBuilder = new StringBuilder(stream.current);
|
|
39
|
+
let hasSeparator = isDecimalSeparator(stream.current);
|
|
40
|
+
while (true) {
|
|
41
|
+
const peekedChar = stream.peek;
|
|
42
|
+
if (peekedChar.toLowerCase() === "e") {
|
|
43
|
+
numberBuilder.push(parseScientificNotation(stream));
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
if (isDecimalSeparator(peekedChar)) {
|
|
47
|
+
if (hasSeparator) {
|
|
48
|
+
throw new Error("A number cannot have multiple decimal separators.");
|
|
49
|
+
}
|
|
50
|
+
hasSeparator = true;
|
|
51
|
+
numberBuilder.push(stream.next);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (isDigit(peekedChar)) {
|
|
55
|
+
numberBuilder.push(stream.next);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return numberBuilder.value;
|
|
62
|
+
}
|
|
63
|
+
function unescape(char) {
|
|
64
|
+
switch (char) {
|
|
65
|
+
case "n": return "\n";
|
|
66
|
+
case "t": return "\t";
|
|
67
|
+
default: return char;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function parseStringLiteral(stream) {
|
|
71
|
+
const stringBuilder = new StringBuilder(stream.current);
|
|
72
|
+
const delimiter = stream.current;
|
|
73
|
+
while (stream.next !== delimiter) {
|
|
74
|
+
if (stream.isEOF) {
|
|
75
|
+
throw new Error(`Missing closing string delimiter (${delimiter}).`);
|
|
76
|
+
}
|
|
77
|
+
stringBuilder.push(stream.current === "\\" ? unescape(stream.next) : stream.current);
|
|
78
|
+
}
|
|
79
|
+
stringBuilder.push(stream.current);
|
|
80
|
+
return stringBuilder.value;
|
|
81
|
+
}
|
|
82
|
+
function parseVariable(stream) {
|
|
83
|
+
const variableBuilder = new StringBuilder(stream.current);
|
|
84
|
+
while (isLetterOrUnderscore(stream.peek) || isDigit(stream.peek)) {
|
|
85
|
+
variableBuilder.push(stream.next);
|
|
86
|
+
}
|
|
87
|
+
if (isDecimalSeparator(stream.peek)) {
|
|
88
|
+
throw new Error("Decimal separator in variable.");
|
|
89
|
+
}
|
|
90
|
+
return variableBuilder.value;
|
|
91
|
+
}
|
|
92
|
+
function parseSymbolCombination(stream) {
|
|
93
|
+
const symbolComboBuilder = new StringBuilder(stream.current);
|
|
94
|
+
while (symbolComboBuilder.length < symbolCombinations.length && oneSymbolCombinations.includes(stream.peek)) {
|
|
95
|
+
symbolComboBuilder.push(stream.next);
|
|
96
|
+
}
|
|
97
|
+
for (let i = symbolCombinations.length - symbolComboBuilder.length; i < symbolCombinations.length - 1; i++) {
|
|
98
|
+
const symbolCombo = symbolComboBuilder.value;
|
|
99
|
+
if (symbolCombinations[i].includes(symbolCombo)) {
|
|
100
|
+
return symbolCombo;
|
|
101
|
+
}
|
|
102
|
+
symbolComboBuilder.pop();
|
|
103
|
+
stream.undo;
|
|
104
|
+
}
|
|
105
|
+
return symbolComboBuilder.value;
|
|
106
|
+
}
|
|
107
|
+
function parseFormula(formula) {
|
|
108
|
+
const tokens = [];
|
|
109
|
+
const stream = new InputStream(formula);
|
|
110
|
+
while (!stream.isEOF) {
|
|
111
|
+
const char = stream.next;
|
|
112
|
+
if (isWhitespace(char)) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (isDigit(char) || isDecimalSeparator(char)) {
|
|
116
|
+
tokens.push(parseNumber(stream));
|
|
117
|
+
}
|
|
118
|
+
else if (isLetterOrUnderscore(char)) {
|
|
119
|
+
tokens.push(parseVariable(stream));
|
|
120
|
+
}
|
|
121
|
+
else if (isStringDelimiter(char)) {
|
|
122
|
+
tokens.push(parseStringLiteral(stream));
|
|
123
|
+
}
|
|
124
|
+
else if (oneSymbolCombinations.includes(char)) {
|
|
125
|
+
tokens.push(parseSymbolCombination(stream));
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
throw new Error(`Unknown symbol received "${char}".`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return tokens;
|
|
132
|
+
}
|
|
133
|
+
export function splitFormula(formula) {
|
|
134
|
+
return parseFormula(formula);
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=FormulaSplitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormulaSplitter.js","sourceRoot":"","sources":["../../../src/formula/FormulaSplitter.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport { InputStream } from \"./InputStream\";\nimport { StringBuilder } from \"./StringBuilder\";\nimport { isDecimalSeparator, isDigit, isLetterOrUnderscore, isStringDelimiter, isWhitespace } from \"./Utils\";\n\nconst fourSymbolCombinations = [\">>>=\"];\nconst threeSymbolCombinations = [\"**=\", \"<<=\", \">>=\", \"&&=\", \"||=\", \"??=\", \"===\", \"!==\", \">>>\"];\nconst twoSymbolCombinations = [\"+=\", \"-=\", \"*=\", \"/=\", \"%=\", \"&=\", \"^=\", \"|=\", \"?=\", \"==\", \"!=\", \">=\", \"<=\", \"++\", \"--\", \"**\", \"<<\", \">>\", \"&&\", \"||\", \"??\", \"?.\"];\nconst oneSymbolCombinations = [\"~\", \"!\", \"@\", \"#\", \"$\", \"%\", \"^\", \"&\", \"*\", \"(\", \")\", \"-\", \"=\", \"+\", \"[\", \"]\", \"{\", \"}\", \"\\\\\", \"|\", \";\", \":\", \",\", \".\", \"<\", \">\", \"/\", \"?\"];\n\nconst symbolCombinations: string[][] = [\n fourSymbolCombinations,\n threeSymbolCombinations,\n twoSymbolCombinations,\n oneSymbolCombinations,\n];\n\nfunction parseScientificNotation(stream: InputStream) {\n const notationBuilder = new StringBuilder();\n\n const nextChar = stream.next;\n const afterEChar = stream.peek;\n if (isDigit(afterEChar) || afterEChar === \"+\" || afterEChar === \"-\") {\n notationBuilder.push(nextChar);\n notationBuilder.push(stream.next);\n while (isDigit(stream.peek)) {\n notationBuilder.push(stream.next);\n }\n if (isDecimalSeparator(stream.peek)) {\n throw new Error(\"The exponent in scientific notation must be an integer.\");\n }\n } else {\n stream.undo;\n }\n\n return notationBuilder.value;\n}\n\nfunction parseNumber(stream: InputStream): string {\n const numberBuilder = new StringBuilder(stream.current);\n let hasSeparator = isDecimalSeparator(stream.current);\n\n while (true) {\n const peekedChar = stream.peek;\n if (peekedChar.toLowerCase() === \"e\") {\n numberBuilder.push(parseScientificNotation(stream));\n break;\n }\n\n if (isDecimalSeparator(peekedChar)) {\n if (hasSeparator) {\n throw new Error(\"A number cannot have multiple decimal separators.\");\n }\n hasSeparator = true;\n numberBuilder.push(stream.next);\n continue;\n }\n\n if (isDigit(peekedChar)) {\n numberBuilder.push(stream.next);\n } else {\n break;\n }\n }\n\n return numberBuilder.value;\n}\n\nfunction unescape(char: string): string {\n switch (char) {\n case \"n\": return \"\\n\";\n case \"t\": return \"\\t\";\n default: return char;\n }\n}\n\nfunction parseStringLiteral(stream: InputStream): string {\n const stringBuilder = new StringBuilder(stream.current);\n const delimiter = stream.current;\n\n while (stream.next !== delimiter) {\n if (stream.isEOF) {\n throw new Error(`Missing closing string delimiter (${delimiter}).`);\n }\n\n stringBuilder.push(stream.current === \"\\\\\" ? unescape(stream.next) : stream.current);\n }\n\n stringBuilder.push(stream.current);\n return stringBuilder.value;\n}\n\nfunction parseVariable(stream: InputStream): string {\n const variableBuilder = new StringBuilder(stream.current);\n\n while (isLetterOrUnderscore(stream.peek) || isDigit(stream.peek)) {\n variableBuilder.push(stream.next);\n }\n\n if (isDecimalSeparator(stream.peek)) {\n throw new Error(\"Decimal separator in variable.\");\n }\n\n return variableBuilder.value;\n}\n\nfunction parseSymbolCombination(stream: InputStream): string {\n const symbolComboBuilder = new StringBuilder(stream.current);\n while (symbolComboBuilder.length < symbolCombinations.length && oneSymbolCombinations.includes(stream.peek)) {\n symbolComboBuilder.push(stream.next);\n }\n\n for (let i = symbolCombinations.length - symbolComboBuilder.length; i < symbolCombinations.length - 1; i++) {\n const symbolCombo = symbolComboBuilder.value;\n if (symbolCombinations[i].includes(symbolCombo)) {\n return symbolCombo;\n }\n symbolComboBuilder.pop();\n stream.undo;\n }\n\n return symbolComboBuilder.value;\n}\n\nfunction parseFormula(formula: string): string[] {\n const tokens: string[] = [];\n const stream = new InputStream(formula);\n while (!stream.isEOF) {\n const char = stream.next;\n if (isWhitespace(char)) {\n continue;\n }\n\n if (isDigit(char) || isDecimalSeparator(char)) {\n tokens.push(parseNumber(stream));\n } else if (isLetterOrUnderscore(char)) {\n tokens.push(parseVariable(stream));\n } else if (isStringDelimiter(char)) {\n tokens.push(parseStringLiteral(stream));\n } else if (oneSymbolCombinations.includes(char)) {\n tokens.push(parseSymbolCombination(stream));\n } else {\n throw new Error(`Unknown symbol received \"${char}\".`);\n }\n }\n\n return tokens;\n}\n\nexport function splitFormula(formula: string): string[] {\n return parseFormula(formula);\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Token } from "./InfixToPostfixConverter";
|
|
2
|
+
import type { Queue } from "./Queue";
|
|
3
|
+
import type { PropertyMap } from "./Types";
|
|
4
|
+
export declare function validateTokens(tokens: Queue<Token>, properties: PropertyMap): string;
|
|
5
|
+
//# sourceMappingURL=FormulaTokensValidator.d.ts.map
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { getFormulaFunctionReturnType, getFunction } from "./FormulaFunctionProvider";
|
|
6
|
+
import { getOperatorArgumentCountBounds, getOperatorReturnType, isOperator } from "./FormulaOperatorsProvider";
|
|
7
|
+
import { TokenType } from "./InfixToPostfixConverter";
|
|
8
|
+
import { Stack } from "./Stack";
|
|
9
|
+
function isNumericalConstant(name) {
|
|
10
|
+
return [
|
|
11
|
+
"e",
|
|
12
|
+
"ln2",
|
|
13
|
+
"ln10",
|
|
14
|
+
"log2e",
|
|
15
|
+
"log10e",
|
|
16
|
+
"pi",
|
|
17
|
+
"sqrt1_2",
|
|
18
|
+
"sqrt2",
|
|
19
|
+
].includes(name.toLowerCase());
|
|
20
|
+
}
|
|
21
|
+
export function validateTokens(tokens, properties) {
|
|
22
|
+
if (tokens.length === 0)
|
|
23
|
+
return "Formula cannot be empty.";
|
|
24
|
+
const argStack = new Stack();
|
|
25
|
+
while (tokens.length > 0) {
|
|
26
|
+
const token = tokens.dequeue();
|
|
27
|
+
switch (token.type) {
|
|
28
|
+
case TokenType.Number:
|
|
29
|
+
argStack.push("number");
|
|
30
|
+
break;
|
|
31
|
+
case TokenType.String:
|
|
32
|
+
argStack.push("string");
|
|
33
|
+
break;
|
|
34
|
+
case TokenType.Boolean:
|
|
35
|
+
argStack.push("boolean");
|
|
36
|
+
break;
|
|
37
|
+
case TokenType.Null:
|
|
38
|
+
argStack.push("undefined");
|
|
39
|
+
break;
|
|
40
|
+
case TokenType.Variable:
|
|
41
|
+
const isConstant = isNumericalConstant(token.value);
|
|
42
|
+
if (isConstant) {
|
|
43
|
+
argStack.push("number");
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
const prop = properties[token.value];
|
|
47
|
+
if (!prop)
|
|
48
|
+
return `Variable "${token.value}" is not available.`;
|
|
49
|
+
argStack.push(prop);
|
|
50
|
+
}
|
|
51
|
+
break;
|
|
52
|
+
case TokenType.Operator:
|
|
53
|
+
if (!isOperator(token.value))
|
|
54
|
+
return `Operator "${token.value}" is not supported.`;
|
|
55
|
+
const operatorBounds = getOperatorArgumentCountBounds(token.value);
|
|
56
|
+
if (!operatorBounds)
|
|
57
|
+
return `Operator "${token.value}" is not supported.`;
|
|
58
|
+
if (operatorBounds[0] === 2 && token.argCount === 1)
|
|
59
|
+
return `Unary operator "${token.value}" is not supported.`;
|
|
60
|
+
if (argStack.length < token.argCount) {
|
|
61
|
+
return `Too few arguments given for ${token.argCount === 1 ? "unary" : "binary"} operator "${token.value}".`;
|
|
62
|
+
}
|
|
63
|
+
const opArgs = argStack.popN(token.argCount).reverse();
|
|
64
|
+
let operationResult;
|
|
65
|
+
if (opArgs.length === 1)
|
|
66
|
+
operationResult = getOperatorReturnType(token.value, opArgs[0]);
|
|
67
|
+
else if (opArgs.length === 2)
|
|
68
|
+
operationResult = getOperatorReturnType(token.value, opArgs[0], opArgs[1]);
|
|
69
|
+
else
|
|
70
|
+
return `Operator "${token.value}" does not support ${token.argCount} operands.`;
|
|
71
|
+
if (operationResult.errorMessage)
|
|
72
|
+
return operationResult.errorMessage;
|
|
73
|
+
else
|
|
74
|
+
argStack.push(operationResult.value);
|
|
75
|
+
break;
|
|
76
|
+
case TokenType.Function:
|
|
77
|
+
const fnArg = getFunction(token.value);
|
|
78
|
+
if (!fnArg)
|
|
79
|
+
return `Function "${token.value}" is not supported.`;
|
|
80
|
+
const fnArgBounds = fnArg.argumentCountBounds;
|
|
81
|
+
if (fnArgBounds[0] === 0 && fnArgBounds[1] === 0 && token.argCount > 0) {
|
|
82
|
+
return `Function "${token.value}" does not accept any arguments.`;
|
|
83
|
+
}
|
|
84
|
+
else if (fnArgBounds[1] === -1 && token.argCount < fnArgBounds[0]) {
|
|
85
|
+
if (fnArgBounds[0] === 1) {
|
|
86
|
+
return `Function "${token.value}" requires at least 1 argument.`;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
if (token.argCount === 1) {
|
|
90
|
+
return `Function "${token.value}" requires at least ${fnArgBounds[0]} arguments, but only 1 argument was given.`;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
return `Function "${token.value}" requires at least ${fnArgBounds[0]} arguments, but only ${token.argCount} arguments were given.`;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else if (fnArgBounds[0] === fnArgBounds[1] && token.argCount !== fnArgBounds[0]) {
|
|
98
|
+
if (fnArgBounds[0] === 1) {
|
|
99
|
+
return `Function "${token.value}" requires exactly 1 argument, but ${token.argCount} arguments were given.`;
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
if (token.argCount === 1) {
|
|
103
|
+
return `Function "${token.value}" requires exactly ${fnArgBounds[0]} arguments, but 1 argument was given.`;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
return `Function "${token.value}" requires exactly ${fnArgBounds[0]} arguments, but ${token.argCount} arguments were given.`;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const fArgs = argStack.popN(token.argCount).reverse();
|
|
111
|
+
if (fArgs.length < token.argCount) {
|
|
112
|
+
return `Too few arguments given for function "${token.value}".`;
|
|
113
|
+
}
|
|
114
|
+
const functionResult = getFormulaFunctionReturnType(fnArg, fArgs);
|
|
115
|
+
if (functionResult.errorMessage)
|
|
116
|
+
return `Function "${token.value}" is invalid. ${functionResult.errorMessage}`;
|
|
117
|
+
else
|
|
118
|
+
argStack.push(functionResult.value);
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (argStack.length !== 1) {
|
|
123
|
+
return "Formula is invalid.";
|
|
124
|
+
}
|
|
125
|
+
const resultType = argStack.pop();
|
|
126
|
+
if (!resultType || resultType === "undefined") {
|
|
127
|
+
return "Formula cannot always return null.";
|
|
128
|
+
}
|
|
129
|
+
return "";
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=FormulaTokensValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormulaTokensValidator.js","sourceRoot":"","sources":["../../../src/formula/FormulaTokensValidator.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport { getFormulaFunctionReturnType, getFunction } from \"./FormulaFunctionProvider\";\nimport { getOperatorArgumentCountBounds, getOperatorReturnType, isOperator } from \"./FormulaOperatorsProvider\";\nimport type { Token } from \"./InfixToPostfixConverter\";\nimport { TokenType } from \"./InfixToPostfixConverter\";\nimport type { Queue } from \"./Queue\";\nimport { Stack } from \"./Stack\";\nimport type { PossibleDataType, PropertyMap } from \"./Types\";\n\nfunction isNumericalConstant(name: string): boolean {\n return [\n \"e\",\n \"ln2\",\n \"ln10\",\n \"log2e\",\n \"log10e\",\n \"pi\",\n \"sqrt1_2\",\n \"sqrt2\",\n ].includes(name.toLowerCase());\n}\n\nexport function validateTokens(tokens: Queue<Token>, properties: PropertyMap): string {\n if (tokens.length === 0)\n return \"Formula cannot be empty.\";\n\n const argStack = new Stack<PossibleDataType>();\n\n while (tokens.length > 0) {\n const token = tokens.dequeue()!;\n\n switch (token.type) {\n case TokenType.Number:\n argStack.push(\"number\");\n break;\n case TokenType.String:\n argStack.push(\"string\");\n break;\n case TokenType.Boolean:\n argStack.push(\"boolean\");\n break;\n case TokenType.Null:\n argStack.push(\"undefined\");\n break;\n case TokenType.Variable:\n const isConstant = isNumericalConstant(token.value);\n if (isConstant) {\n argStack.push(\"number\");\n } else {\n const prop = properties[token.value];\n if (!prop)\n return `Variable \"${token.value}\" is not available.`;\n argStack.push(prop);\n }\n break;\n case TokenType.Operator:\n if (!isOperator(token.value))\n return `Operator \"${token.value}\" is not supported.`;\n\n const operatorBounds = getOperatorArgumentCountBounds(token.value);\n if (!operatorBounds)\n return `Operator \"${token.value}\" is not supported.`;\n\n if (operatorBounds[0] === 2 && token.argCount === 1)\n return `Unary operator \"${token.value}\" is not supported.`;\n\n if (argStack.length < token.argCount) {\n return `Too few arguments given for ${token.argCount === 1 ? \"unary\" : \"binary\"} operator \"${token.value}\".`;\n }\n const opArgs = argStack.popN(token.argCount).reverse();\n let operationResult;\n if (opArgs.length === 1)\n operationResult = getOperatorReturnType(token.value, opArgs[0]);\n else if (opArgs.length === 2)\n operationResult = getOperatorReturnType(token.value, opArgs[0], opArgs[1]);\n else\n return `Operator \"${token.value}\" does not support ${token.argCount} operands.`;\n\n if (operationResult.errorMessage)\n return operationResult.errorMessage;\n else\n argStack.push(operationResult.value!);\n\n break;\n case TokenType.Function:\n const fnArg = getFunction(token.value);\n if (!fnArg)\n return `Function \"${token.value}\" is not supported.`;\n\n const fnArgBounds = fnArg.argumentCountBounds;\n if (fnArgBounds[0] === 0 && fnArgBounds[1] === 0 && token.argCount > 0) {\n return `Function \"${token.value}\" does not accept any arguments.`;\n } else if (fnArgBounds[1] === -1 && token.argCount < fnArgBounds[0]) {\n if (fnArgBounds[0] === 1) {\n return `Function \"${token.value}\" requires at least 1 argument.`;\n } else {\n if (token.argCount === 1) {\n return `Function \"${token.value}\" requires at least ${fnArgBounds[0]} arguments, but only 1 argument was given.`;\n } else {\n return `Function \"${token.value}\" requires at least ${fnArgBounds[0]} arguments, but only ${token.argCount} arguments were given.`;\n }\n }\n } else if (fnArgBounds[0] === fnArgBounds[1] && token.argCount !== fnArgBounds[0]) {\n if (fnArgBounds[0] === 1) {\n return `Function \"${token.value}\" requires exactly 1 argument, but ${token.argCount} arguments were given.`;\n } else {\n if (token.argCount === 1) {\n return `Function \"${token.value}\" requires exactly ${fnArgBounds[0]} arguments, but 1 argument was given.`;\n } else {\n return `Function \"${token.value}\" requires exactly ${fnArgBounds[0]} arguments, but ${token.argCount} arguments were given.`;\n }\n }\n }\n\n const fArgs = argStack.popN(token.argCount).reverse();\n if (fArgs.length < token.argCount) {\n return `Too few arguments given for function \"${token.value}\".`;\n }\n\n const functionResult = getFormulaFunctionReturnType(fnArg, fArgs);\n if (functionResult.errorMessage)\n return `Function \"${token.value}\" is invalid. ${functionResult.errorMessage}`;\n else\n argStack.push(functionResult.value!);\n\n break;\n }\n }\n\n if (argStack.length !== 1) {\n return \"Formula is invalid.\";\n }\n\n const resultType = argStack.pop();\n if (!resultType || resultType === \"undefined\") {\n return \"Formula cannot always return null.\";\n }\n\n return \"\";\n}\n\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { splitFormula } from "./FormulaSplitter";
|
|
6
|
+
import { validateTokens } from "./FormulaTokensValidator";
|
|
7
|
+
import { convertInfixToPostfix } from "./InfixToPostfixConverter";
|
|
8
|
+
import { ParenthesisState, validateParenthesis } from "./ParenthesisValidator";
|
|
9
|
+
export function validateFormula(formula, properties) {
|
|
10
|
+
var _a;
|
|
11
|
+
const parenthesisState = validateParenthesis(formula);
|
|
12
|
+
if (ParenthesisState.NotClosed === parenthesisState) {
|
|
13
|
+
return "Opened but not closed parenthesis found.";
|
|
14
|
+
}
|
|
15
|
+
else if (ParenthesisState.NotOpened === parenthesisState) {
|
|
16
|
+
return "Closed but not opened parenthesis found.";
|
|
17
|
+
}
|
|
18
|
+
let infixFormulaTokens;
|
|
19
|
+
try {
|
|
20
|
+
infixFormulaTokens = splitFormula(formula);
|
|
21
|
+
}
|
|
22
|
+
catch (ex) {
|
|
23
|
+
return ex.message;
|
|
24
|
+
}
|
|
25
|
+
const postfixFormulaTokens = convertInfixToPostfix(infixFormulaTokens);
|
|
26
|
+
if (undefined === postfixFormulaTokens.value) {
|
|
27
|
+
return (_a = postfixFormulaTokens.errorMessage) !== null && _a !== void 0 ? _a : "Unknown error";
|
|
28
|
+
}
|
|
29
|
+
return validateTokens(postfixFormulaTokens.value, properties);
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=FormulaValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormulaValidator.js","sourceRoot":"","sources":["../../../src/formula/FormulaValidator.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAG/E,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,UAAuB;;IACtE,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACtD,IAAI,gBAAgB,CAAC,SAAS,KAAK,gBAAgB,EAAE;QACnD,OAAO,0CAA0C,CAAC;KACnD;SAAM,IAAI,gBAAgB,CAAC,SAAS,KAAK,gBAAgB,EAAE;QAC1D,OAAO,0CAA0C,CAAC;KACnD;IAED,IAAI,kBAAkB,CAAC;IACvB,IAAI;QACF,kBAAkB,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;KAC5C;IAAC,OAAO,EAAE,EAAE;QACX,OAAQ,EAAY,CAAC,OAAO,CAAC;KAC9B;IAED,MAAM,oBAAoB,GAAG,qBAAqB,CAAC,kBAAkB,CAAC,CAAC;IAEvE,IAAI,SAAS,KAAK,oBAAoB,CAAC,KAAK,EAAE;QAC5C,OAAO,MAAA,oBAAoB,CAAC,YAAY,mCAAI,eAAe,CAAC;KAC7D;IAED,OAAO,cAAc,CAAC,oBAAoB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;AAChE,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport { splitFormula } from \"./FormulaSplitter\";\nimport { validateTokens } from \"./FormulaTokensValidator\";\nimport { convertInfixToPostfix } from \"./InfixToPostfixConverter\";\nimport { ParenthesisState, validateParenthesis } from \"./ParenthesisValidator\";\nimport type { PropertyMap } from \"./Types\";\n\nexport function validateFormula(formula: string, properties: PropertyMap): string {\n const parenthesisState = validateParenthesis(formula);\n if (ParenthesisState.NotClosed === parenthesisState) {\n return \"Opened but not closed parenthesis found.\";\n } else if (ParenthesisState.NotOpened === parenthesisState) {\n return \"Closed but not opened parenthesis found.\";\n }\n\n let infixFormulaTokens;\n try {\n infixFormulaTokens = splitFormula(formula);\n } catch (ex) {\n return (ex as Error).message;\n }\n\n const postfixFormulaTokens = convertInfixToPostfix(infixFormulaTokens);\n\n if (undefined === postfixFormulaTokens.value) {\n return postfixFormulaTokens.errorMessage ?? \"Unknown error\";\n }\n\n return validateTokens(postfixFormulaTokens.value, properties);\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IResult.js","sourceRoot":"","sources":["../../../src/formula/IResult.ts"],"names":[],"mappings":"","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nexport interface IResult<T> {\n value?: T;\n errorMessage?: string;\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IResult } from "./IResult";
|
|
2
|
+
import { Queue } from "./Queue";
|
|
3
|
+
export declare enum TokenType {
|
|
4
|
+
Number = 0,
|
|
5
|
+
Function = 1,
|
|
6
|
+
Operator = 2,
|
|
7
|
+
Variable = 3,
|
|
8
|
+
String = 4,
|
|
9
|
+
Boolean = 5,
|
|
10
|
+
Null = 6
|
|
11
|
+
}
|
|
12
|
+
export interface Token {
|
|
13
|
+
value: string;
|
|
14
|
+
type: TokenType;
|
|
15
|
+
argCount: number;
|
|
16
|
+
}
|
|
17
|
+
export declare function convertInfixToPostfix(infix: string[]): IResult<Queue<Token>>;
|
|
18
|
+
//# sourceMappingURL=InfixToPostfixConverter.d.ts.map
|