@steedos/odata-v4-parser 2.2.53-beta.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.
@@ -0,0 +1,825 @@
1
+ import Utils from "./utils";
2
+ import Lexer from "./lexer";
3
+ import PrimitiveLiteral from "./primitiveLiteral";
4
+ import NameOrIdentifier from "./nameOrIdentifier";
5
+ import ArrayOrObject from "./json";
6
+
7
+ export namespace Expressions {
8
+ export function commonExpr(value: Utils.SourceArray, index: number): Lexer.Token {
9
+ let token = PrimitiveLiteral.primitiveLiteral(value, index) ||
10
+ parameterAlias(value, index) ||
11
+ ArrayOrObject.arrayOrObject(value, index) ||
12
+ rootExpr(value, index) ||
13
+ methodCallExpr(value, index) ||
14
+ firstMemberExpr(value, index) ||
15
+ functionExpr(value, index) ||
16
+ negateExpr(value, index) ||
17
+ parenExpr(value, index) ||
18
+ castExpr(value, index);
19
+ if (!token) return;
20
+
21
+ let expr = addExpr(value, token.next) ||
22
+ subExpr(value, token.next) ||
23
+ mulExpr(value, token.next) ||
24
+ divExpr(value, token.next) ||
25
+ modExpr(value, token.next);
26
+
27
+ if (expr) {
28
+ token.value = {
29
+ left: Lexer.clone(token),
30
+ right: expr.value
31
+ };
32
+ token.next = expr.value.next;
33
+ token.type = expr.type;
34
+ token.raw = Utils.stringify(value, token.position, token.next);
35
+ }
36
+
37
+ if (token) return Lexer.tokenize(value, token.position, token.next, token, Lexer.TokenType.CommonExpression);
38
+ }
39
+
40
+ export function boolCommonExpr(value: Utils.SourceArray, index: number): Lexer.Token {
41
+ let token = isofExpr(value, index) ||
42
+ boolMethodCallExpr(value, index) ||
43
+ notExpr(value, index) ||
44
+ commonExpr(value, index) ||
45
+ boolParenExpr(value, index);
46
+
47
+ if (!token) return;
48
+ let commonMoreExpr = undefined;
49
+ if (token.type === Lexer.TokenType.CommonExpression) {
50
+ commonMoreExpr = eqExpr(value, token.next) ||
51
+ neExpr(value, token.next) ||
52
+ ltExpr(value, token.next) ||
53
+ leExpr(value, token.next) ||
54
+ gtExpr(value, token.next) ||
55
+ geExpr(value, token.next) ||
56
+ hasExpr(value, token.next) ||
57
+ inExpr(value, token.next)
58
+ ;
59
+
60
+ if (commonMoreExpr) {
61
+ token.value = {
62
+ left: token.value,
63
+ right: commonMoreExpr.value
64
+ };
65
+ token.next = commonMoreExpr.value.next;
66
+ token.type = commonMoreExpr.type;
67
+ token.raw = Utils.stringify(value, token.position, token.next);
68
+ }
69
+ }
70
+
71
+ let expr = andExpr(value, token.next) ||
72
+ orExpr(value, token.next);
73
+
74
+ if (expr) {
75
+ let left = Lexer.clone(token);
76
+ token.next = expr.value.next;
77
+ token.value = {
78
+ left: left,
79
+ right: expr.value
80
+ };
81
+ token.type = expr.type;
82
+ token.raw = Utils.stringify(value, token.position, token.next);
83
+
84
+ if (token.type === Lexer.TokenType.AndExpression && token.value.right.type === Lexer.TokenType.OrExpression) {
85
+ token.value.left = Lexer.tokenize(value, token.value.left.position, token.value.right.value.left.next, {
86
+ left: token.value.left,
87
+ right: token.value.right.value.left
88
+ }, token.type);
89
+ token.type = token.value.right.type;
90
+ token.value.right = token.value.right.value.right;
91
+ }
92
+ }
93
+
94
+ return token;
95
+ }
96
+
97
+ export function andExpr(value: Utils.SourceArray, index: number): Lexer.Token {
98
+ let rws = Lexer.RWS(value, index);
99
+ if (rws === index || !Utils.equals(value, rws, "and")) return;
100
+ let start = index;
101
+ index = rws + 3;
102
+ rws = Lexer.RWS(value, index);
103
+ if (rws === index) return;
104
+ index = rws;
105
+ let token = boolCommonExpr(value, index);
106
+ if (!token) return;
107
+
108
+ return Lexer.tokenize(value, start, index, token, Lexer.TokenType.AndExpression);
109
+ }
110
+
111
+ export function orExpr(value: Utils.SourceArray, index: number): Lexer.Token {
112
+ let rws = Lexer.RWS(value, index);
113
+ if (rws === index || !Utils.equals(value, rws, "or")) return;
114
+ let start = index;
115
+ index = rws + 2;
116
+ rws = Lexer.RWS(value, index);
117
+ if (rws === index) return;
118
+ index = rws;
119
+ let token = boolCommonExpr(value, index);
120
+ if (!token) return;
121
+
122
+ return Lexer.tokenize(value, start, index, token, Lexer.TokenType.OrExpression);
123
+ }
124
+
125
+ export function leftRightExpr(value: Utils.SourceArray, index: number, expr: string, tokenType: Lexer.TokenType): Lexer.Token {
126
+ let rws = Lexer.RWS(value, index);
127
+ if (rws === index) return;
128
+ let start = index;
129
+ index = rws;
130
+ if (!Utils.equals(value, index, expr)) return;
131
+ index += expr.length;
132
+ rws = Lexer.RWS(value, index);
133
+ if (rws === index) return;
134
+ index = rws;
135
+ let token = commonExpr(value, index);
136
+ if (!token) return;
137
+ return Lexer.tokenize(value, start, index, token.value, tokenType);
138
+ }
139
+ export function eqExpr(value: Utils.SourceArray, index: number): Lexer.Token { return leftRightExpr(value, index, "eq", Lexer.TokenType.EqualsExpression); }
140
+ export function neExpr(value: Utils.SourceArray, index: number): Lexer.Token { return leftRightExpr(value, index, "ne", Lexer.TokenType.NotEqualsExpression); }
141
+ export function ltExpr(value: Utils.SourceArray, index: number): Lexer.Token { return leftRightExpr(value, index, "lt", Lexer.TokenType.LesserThanExpression); }
142
+ export function leExpr(value: Utils.SourceArray, index: number): Lexer.Token { return leftRightExpr(value, index, "le", Lexer.TokenType.LesserOrEqualsExpression); }
143
+ export function gtExpr(value: Utils.SourceArray, index: number): Lexer.Token { return leftRightExpr(value, index, "gt", Lexer.TokenType.GreaterThanExpression); }
144
+ export function geExpr(value: Utils.SourceArray, index: number): Lexer.Token { return leftRightExpr(value, index, "ge", Lexer.TokenType.GreaterOrEqualsExpression); }
145
+ export function hasExpr(value: Utils.SourceArray, index: number): Lexer.Token { return leftRightExpr(value, index, "has", Lexer.TokenType.HasExpression); }
146
+
147
+ export function addExpr(value: Utils.SourceArray, index: number): Lexer.Token { return leftRightExpr(value, index, "add", Lexer.TokenType.AddExpression); }
148
+ export function subExpr(value: Utils.SourceArray, index: number): Lexer.Token { return leftRightExpr(value, index, "sub", Lexer.TokenType.SubExpression); }
149
+ export function mulExpr(value: Utils.SourceArray, index: number): Lexer.Token { return leftRightExpr(value, index, "mul", Lexer.TokenType.MulExpression); }
150
+ export function divExpr(value: Utils.SourceArray, index: number): Lexer.Token { return leftRightExpr(value, index, "div", Lexer.TokenType.DivExpression); }
151
+ export function modExpr(value: Utils.SourceArray, index: number): Lexer.Token { return leftRightExpr(value, index, "mod", Lexer.TokenType.ModExpression); }
152
+
153
+ export function inExpr(value: Utils.SourceArray, index: number): Lexer.Token {
154
+ // return leftRightExpr(value, index, "in", Lexer.TokenType.InExpression);
155
+ const expr: string = 'in';
156
+ const tokenType: Lexer.TokenType = Lexer.TokenType.InExpression;
157
+ let rws = Lexer.RWS(value, index);
158
+ if (rws === index) return;
159
+ let start = index;
160
+ index = rws;
161
+ if (!Utils.equals(value, index, expr)) return;
162
+ index += expr.length;
163
+ rws = Lexer.RWS(value, index);
164
+ if (rws === index) return;
165
+ index = rws;
166
+ let token = boolCommonExpr(value, index);
167
+ if (!token) return;
168
+
169
+ return Lexer.tokenize(value, start, index, token.value, tokenType);
170
+ }
171
+
172
+ export function notExpr(value: Utils.SourceArray, index: number): Lexer.Token {
173
+ if (!Utils.equals(value, index, "not")) return;
174
+ let start = index;
175
+ index += 3;
176
+ let rws = Lexer.RWS(value, index);
177
+ if (rws === index) return;
178
+ index = rws;
179
+ let token = boolCommonExpr(value, index);
180
+ if (!token) return;
181
+
182
+ return Lexer.tokenize(value, start, token.next, token, Lexer.TokenType.NotExpression);
183
+ }
184
+
185
+ export function boolParenExpr(value: Utils.SourceArray, index: number): Lexer.Token {
186
+ let open = Lexer.OPEN(value, index);
187
+ if (!open) return;
188
+ let start = index;
189
+ index = open;
190
+ index = Lexer.BWS(value, index);
191
+ let token = boolCommonExpr(value, index);
192
+ if (!token) return;
193
+ index = Lexer.BWS(value, token.next);
194
+ let close = Lexer.CLOSE(value, index);
195
+ if (!close) return;
196
+ index = close;
197
+
198
+ return Lexer.tokenize(value, start, index, token, Lexer.TokenType.BoolParenExpression);
199
+ }
200
+ export function parenExpr(value: Utils.SourceArray, index: number): Lexer.Token {
201
+ let open = Lexer.OPEN(value, index);
202
+ if (!open) return;
203
+ let start = index;
204
+ index = open;
205
+ index = Lexer.BWS(value, index);
206
+ let token = commonExpr(value, index);
207
+ if (!token) return;
208
+ index = Lexer.BWS(value, token.next);
209
+ let close = Lexer.CLOSE(value, index);
210
+ if (!close) return;
211
+ index = close;
212
+
213
+ return Lexer.tokenize(value, start, index, token.value, Lexer.TokenType.ParenExpression);
214
+ }
215
+
216
+ export function boolMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token {
217
+ return endsWithMethodCallExpr(value, index) ||
218
+ startsWithMethodCallExpr(value, index) ||
219
+ containsMethodCallExpr(value, index) ||
220
+ intersectsMethodCallExpr(value, index);
221
+ }
222
+ export function methodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token {
223
+ return indexOfMethodCallExpr(value, index) ||
224
+ toLowerMethodCallExpr(value, index) ||
225
+ toUpperMethodCallExpr(value, index) ||
226
+ trimMethodCallExpr(value, index) ||
227
+ substringMethodCallExpr(value, index) ||
228
+ substringOfMethodCallExpr(value, index) ||
229
+ concatMethodCallExpr(value, index) ||
230
+ lengthMethodCallExpr(value, index) ||
231
+ yearMethodCallExpr(value, index) ||
232
+ monthMethodCallExpr(value, index) ||
233
+ dayMethodCallExpr(value, index) ||
234
+ hourMethodCallExpr(value, index) ||
235
+ minuteMethodCallExpr(value, index) ||
236
+ secondMethodCallExpr(value, index) ||
237
+ fractionalsecondsMethodCallExpr(value, index) ||
238
+ totalsecondsMethodCallExpr(value, index) ||
239
+ dateMethodCallExpr(value, index) ||
240
+ timeMethodCallExpr(value, index) ||
241
+ roundMethodCallExpr(value, index) ||
242
+ floorMethodCallExpr(value, index) ||
243
+ ceilingMethodCallExpr(value, index) ||
244
+ distanceMethodCallExpr(value, index) ||
245
+ geoLengthMethodCallExpr(value, index) ||
246
+ totalOffsetMinutesMethodCallExpr(value, index) ||
247
+ minDateTimeMethodCallExpr(value, index) ||
248
+ maxDateTimeMethodCallExpr(value, index) ||
249
+ nowMethodCallExpr(value, index);
250
+ }
251
+ export function methodCallExprFactory(value: Utils.SourceArray, index: number, method: string, min?: number, max?: number): Lexer.Token {
252
+ if (typeof min === "undefined") min = 0;
253
+ if (typeof max === "undefined") max = min;
254
+
255
+ if (!Utils.equals(value, index, method)) return;
256
+ let start = index;
257
+ index += method.length;
258
+ let open = Lexer.OPEN(value, index);
259
+ if (!open) return;
260
+ index = open;
261
+ index = Lexer.BWS(value, index);
262
+ let parameters;
263
+ if (min > 0) {
264
+ parameters = [];
265
+ while (parameters.length < max) {
266
+ let expr = commonExpr(value, index);
267
+ if (parameters.length < min && !expr) return;
268
+ else if (expr) {
269
+ parameters.push(expr.value);
270
+ index = expr.next;
271
+ index = Lexer.BWS(value, index);
272
+ let comma = Lexer.COMMA(value, index);
273
+ if (parameters.length < min && !comma) return;
274
+ if (comma) index = comma;
275
+ else break;
276
+ index = Lexer.BWS(value, index);
277
+ } else break;
278
+ }
279
+ }
280
+ index = Lexer.BWS(value, index);
281
+ let close = Lexer.CLOSE(value, index);
282
+ if (!close) return;
283
+ index = close;
284
+
285
+ return Lexer.tokenize(value, start, index, {
286
+ method: method,
287
+ parameters: parameters
288
+ }, Lexer.TokenType.MethodCallExpression);
289
+ }
290
+ export function containsMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "contains", 2); }
291
+ export function startsWithMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "startswith", 2); }
292
+ export function endsWithMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "endswith", 2); }
293
+ export function lengthMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "length", 1); }
294
+ export function indexOfMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "indexof", 2); }
295
+ export function substringMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "substring", 2, 3); }
296
+ export function substringOfMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "substringof", 2); }
297
+ export function toLowerMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "tolower", 1); }
298
+ export function toUpperMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "toupper", 1); }
299
+ export function trimMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "trim", 1); }
300
+ export function concatMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "concat", 2); }
301
+
302
+ export function yearMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "year", 1); }
303
+ export function monthMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "month", 1); }
304
+ export function dayMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "day", 1); }
305
+ export function hourMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "hour", 1); }
306
+ export function minuteMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "minute", 1); }
307
+ export function secondMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "second", 1); }
308
+ export function fractionalsecondsMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "fractionalseconds", 1); }
309
+ export function totalsecondsMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "totalseconds", 1); }
310
+ export function dateMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "date", 1); }
311
+ export function timeMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "time", 1); }
312
+ export function totalOffsetMinutesMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "totaloffsetminutes", 1); }
313
+
314
+ export function minDateTimeMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "mindatetime", 0); }
315
+ export function maxDateTimeMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "maxdatetime", 0); }
316
+ export function nowMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "now", 0); }
317
+
318
+ export function roundMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "round", 1); }
319
+ export function floorMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "floor", 1); }
320
+ export function ceilingMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "ceiling", 1); }
321
+
322
+ export function distanceMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "geo.distance", 2); }
323
+ export function geoLengthMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "geo.length", 1); }
324
+ export function intersectsMethodCallExpr(value: Utils.SourceArray, index: number): Lexer.Token { return methodCallExprFactory(value, index, "geo.intersects", 2); }
325
+
326
+ export function isofExpr(value: Utils.SourceArray, index: number): Lexer.Token {
327
+ if (!Utils.equals(value, index, "isof")) return;
328
+ let start = index;
329
+ index += 4;
330
+ let open = Lexer.OPEN(value, index);
331
+ if (!open) return;
332
+ index = open;
333
+ index = Lexer.BWS(value, index);
334
+ let expr = commonExpr(value, index);
335
+ if (expr) {
336
+ index = expr.next;
337
+ index = Lexer.BWS(value, index);
338
+ let comma = Lexer.COMMA(value, index);
339
+ if (!comma) return;
340
+ index = comma;
341
+ index = Lexer.BWS(value, index);
342
+ }
343
+ let typeName = NameOrIdentifier.qualifiedTypeName(value, index);
344
+ if (!typeName) return;
345
+ index = typeName.next;
346
+ index = Lexer.BWS(value, index);
347
+ let close = Lexer.CLOSE(value, index);
348
+ if (!close) return;
349
+ index = close;
350
+
351
+ return Lexer.tokenize(value, start, index, {
352
+ target: expr,
353
+ typename: typeName
354
+ }, Lexer.TokenType.IsOfExpression);
355
+ }
356
+ export function castExpr(value: Utils.SourceArray, index: number): Lexer.Token {
357
+ if (!Utils.equals(value, index, "cast")) return;
358
+ let start = index;
359
+ index += 4;
360
+ let open = Lexer.OPEN(value, index);
361
+ if (!open) return;
362
+ index = open;
363
+ index = Lexer.BWS(value, index);
364
+ let expr = commonExpr(value, index);
365
+ if (expr) {
366
+ index = expr.next;
367
+ index = Lexer.BWS(value, index);
368
+ let comma = Lexer.COMMA(value, index);
369
+ if (!comma) return;
370
+ index = comma;
371
+ index = Lexer.BWS(value, index);
372
+ }
373
+ let typeName = NameOrIdentifier.qualifiedTypeName(value, index);
374
+ if (!typeName) return;
375
+ index = typeName.next;
376
+ index = Lexer.BWS(value, index);
377
+ let close = Lexer.CLOSE(value, index);
378
+ if (!close) return;
379
+ index = close;
380
+
381
+ return Lexer.tokenize(value, start, index, {
382
+ target: expr,
383
+ typename: typeName
384
+ }, Lexer.TokenType.CastExpression);
385
+ }
386
+
387
+ export function negateExpr(value: Utils.SourceArray, index: number): Lexer.Token {
388
+ if (value[index] !== 0x2d) return;
389
+ let start = index;
390
+ index++;
391
+ index = Lexer.BWS(value, index);
392
+ let expr = commonExpr(value, index);
393
+ if (!expr) return;
394
+
395
+ return Lexer.tokenize(value, start, expr.next, expr, Lexer.TokenType.NegateExpression);
396
+ }
397
+
398
+ export function firstMemberExpr(value: Utils.SourceArray, index: number): Lexer.Token {
399
+ let token = inscopeVariableExpr(value, index);
400
+ let member;
401
+ let start = index;
402
+
403
+ if (token) {
404
+ if (value[token.next] === 0x2f) {
405
+ index = token.next + 1;
406
+ member = memberExpr(value, index);
407
+ if (!member) return;
408
+
409
+ return Lexer.tokenize(value, start, member.next, [token, member], Lexer.TokenType.FirstMemberExpression);
410
+ }
411
+ } else member = memberExpr(value, index);
412
+
413
+ token = token || member;
414
+ if (!token) return;
415
+
416
+ return Lexer.tokenize(value, start, token.next, token, Lexer.TokenType.FirstMemberExpression);
417
+ }
418
+ export function memberExpr(value: Utils.SourceArray, index: number): Lexer.Token {
419
+ let start = index;
420
+ let token = NameOrIdentifier.qualifiedEntityTypeName(value, index);
421
+ if (token) {
422
+ if (value[token.next] !== 0x2f) return;
423
+ index = token.next + 1;
424
+ }
425
+
426
+ let next = propertyPathExpr(value, index) ||
427
+ boundFunctionExpr(value, index);
428
+ if (!next) return;
429
+ return Lexer.tokenize(value, start, next.next, token ? { name: token, value: next } : next, Lexer.TokenType.MemberExpression);
430
+ }
431
+ export function propertyPathExpr(value: Utils.SourceArray, index: number): Lexer.Token {
432
+ let token: any = NameOrIdentifier.odataIdentifier(value, index);
433
+ let start = index;
434
+ if (token) {
435
+ index = token.next;
436
+ let nav = collectionPathExpr(value, token.next) ||
437
+ collectionNavigationExpr(value, token.next) ||
438
+ singleNavigationExpr(value, token.next) ||
439
+ complexPathExpr(value, token.next) ||
440
+ singlePathExpr(value, token.next);
441
+
442
+ if (nav) {
443
+ index = nav.next;
444
+ token = {
445
+ current: Lexer.clone(token),
446
+ next: nav
447
+ };
448
+ }
449
+ }else if (!token) {
450
+ token = NameOrIdentifier.streamProperty(value, index);
451
+ if (token) index = token.next;
452
+ }
453
+
454
+ if (!token) return;
455
+ return Lexer.tokenize(value, start, index, token, Lexer.TokenType.PropertyPathExpression);
456
+ }
457
+ export function inscopeVariableExpr(value: Utils.SourceArray, index: number): Lexer.Token {
458
+ return implicitVariableExpr(value, index) ||
459
+ (isLambdaPredicate ? lambdaVariableExpr(value, index) : undefined);
460
+ }
461
+ export function implicitVariableExpr(value: Utils.SourceArray, index: number): Lexer.Token {
462
+ if (Utils.equals(value, index, "$it")) return Lexer.tokenize(value, index, index + 3, "$it", Lexer.TokenType.ImplicitVariableExpression);
463
+ }
464
+ let isLambdaPredicate = false;
465
+ let hasLambdaVariableExpr = false;
466
+ export function lambdaVariableExpr(value: Utils.SourceArray, index: number): Lexer.Token {
467
+ let token = NameOrIdentifier.odataIdentifier(value, index, Lexer.TokenType.LambdaVariableExpression);
468
+ if (token) {
469
+ hasLambdaVariableExpr = true;
470
+ return token;
471
+ }
472
+ }
473
+ export function lambdaPredicateExpr(value: Utils.SourceArray, index: number): Lexer.Token {
474
+ isLambdaPredicate = true;
475
+ let token = boolCommonExpr(value, index);
476
+ isLambdaPredicate = false;
477
+ if (token && hasLambdaVariableExpr) {
478
+ hasLambdaVariableExpr = false;
479
+ return Lexer.tokenize(value, token.position, token.next, token, Lexer.TokenType.LambdaPredicateExpression);
480
+ }
481
+ }
482
+ export function anyExpr(value: Utils.SourceArray, index: number): Lexer.Token {
483
+ if (!Utils.equals(value, index, "any")) return;
484
+ let start = index;
485
+ index += 3;
486
+ let open = Lexer.OPEN(value, index);
487
+ if (!open) return;
488
+ index = open;
489
+ index = Lexer.BWS(value, index);
490
+ let variable = lambdaVariableExpr(value, index);
491
+ let predicate;
492
+ if (variable) {
493
+ index = variable.next;
494
+ index = Lexer.BWS(value, index);
495
+ let colon = Lexer.COLON(value, index);
496
+ if (!colon) return;
497
+ index = colon;
498
+ index = Lexer.BWS(value, index);
499
+ predicate = lambdaPredicateExpr(value, index);
500
+ if (!predicate) return;
501
+ index = predicate.next;
502
+ }
503
+ index = Lexer.BWS(value, index);
504
+ let close = Lexer.CLOSE(value, index);
505
+ if (!close) return;
506
+ index = close;
507
+
508
+ return Lexer.tokenize(value, start, index, {
509
+ variable: variable,
510
+ predicate: predicate
511
+ }, Lexer.TokenType.AnyExpression);
512
+ }
513
+ export function allExpr(value: Utils.SourceArray, index: number): Lexer.Token {
514
+ if (!Utils.equals(value, index, "all")) return;
515
+ let start = index;
516
+ index += 3;
517
+
518
+ let open = Lexer.OPEN(value, index);
519
+ if (!open) return;
520
+ index = open;
521
+
522
+ index = Lexer.BWS(value, index);
523
+ let variable = lambdaVariableExpr(value, index);
524
+ if (!variable) return;
525
+ index = variable.next;
526
+
527
+ index = Lexer.BWS(value, index);
528
+
529
+ let colon = Lexer.COLON(value, index);
530
+ if (!colon) return;
531
+ index = colon;
532
+
533
+ index = Lexer.BWS(value, index);
534
+
535
+ let predicate = lambdaPredicateExpr(value, index);
536
+ if (!predicate) return;
537
+ index = predicate.next;
538
+
539
+ index = Lexer.BWS(value, index);
540
+
541
+ let close = Lexer.CLOSE(value, index);
542
+ if (!close) return;
543
+ index = close;
544
+
545
+ return Lexer.tokenize(value, start, index, {
546
+ variable: variable,
547
+ predicate: predicate
548
+ }, Lexer.TokenType.AllExpression);
549
+ }
550
+
551
+ export function collectionNavigationExpr(value: Utils.SourceArray, index: number): Lexer.Token {
552
+ let start = index;
553
+ let entity, predicate, navigation, path;
554
+ if (value[index] === 0x2f) {
555
+ index++;
556
+ entity = NameOrIdentifier.qualifiedEntityTypeName(value, index);
557
+ if (!entity) return;
558
+ index = entity.next;
559
+ }
560
+
561
+ predicate = keyPredicate(value, index);
562
+
563
+ if (predicate) {
564
+ index = predicate.next;
565
+ navigation = singleNavigationExpr(value, index);
566
+ if (navigation) index = navigation.next;
567
+ } else {
568
+ path = collectionPathExpr(value, index);
569
+ if (path) index = path.next;
570
+ }
571
+
572
+ if (index > start) {
573
+ return Lexer.tokenize(value, start, index, {
574
+ entity: entity,
575
+ predicate: predicate,
576
+ navigation: navigation,
577
+ path: path
578
+ }, Lexer.TokenType.CollectionNavigationExpression);
579
+ }
580
+ }
581
+ export function keyPredicate(value: Utils.SourceArray, index: number, metadataContext?: any): Lexer.Token {
582
+ return simpleKey(value, index, metadataContext) ||
583
+ compoundKey(value, index);
584
+ }
585
+ export function simpleKey(value: Utils.SourceArray, index: number, metadataContext?: any): Lexer.Token {
586
+ let open = Lexer.OPEN(value, index);
587
+ if (!open) return;
588
+ let start = index;
589
+ index = open;
590
+
591
+ let token = keyPropertyValue(value, index);
592
+ if (!token) return;
593
+
594
+ let close = Lexer.CLOSE(value, token.next);
595
+ if (!close) return;
596
+
597
+ let key;
598
+ if (typeof metadataContext === "object" &&
599
+ metadataContext.key &&
600
+ metadataContext.key.propertyRefs &&
601
+ metadataContext.key.propertyRefs[0] &&
602
+ metadataContext.key.propertyRefs[0].name) {
603
+ key = metadataContext.key.propertyRefs[0].name;
604
+ }
605
+
606
+ return Lexer.tokenize(value, start, close, { key: key, value: token }, Lexer.TokenType.SimpleKey);
607
+ }
608
+ export function compoundKey(value: Utils.SourceArray, index: number): Lexer.Token {
609
+ let open = Lexer.OPEN(value, index);
610
+ if (!open) return;
611
+ let start = index;
612
+ index = open;
613
+
614
+ let pair = keyValuePair(value, index);
615
+ if (!pair) return;
616
+
617
+ let keys = [];
618
+ while (pair) {
619
+ keys.push(pair);
620
+ let comma = Lexer.COMMA(value, pair.next);
621
+ if (comma) pair = keyValuePair(value, comma);
622
+ else pair = null;
623
+ }
624
+
625
+ index = keys[keys.length - 1].next;
626
+ let close = Lexer.CLOSE(value, index);
627
+ if (!close) return;
628
+ index = close;
629
+
630
+ return Lexer.tokenize(value, start, index, keys, Lexer.TokenType.CompoundKey);
631
+ }
632
+ export function keyValuePair(value: Utils.SourceArray, index: number): Lexer.Token {
633
+ let prop = NameOrIdentifier.primitiveKeyProperty(value, index) ||
634
+ keyPropertyAlias(value, index);
635
+
636
+ if (!prop) return;
637
+ let eq = Lexer.EQ(value, prop.next);
638
+ if (!eq) return;
639
+
640
+ let val = keyPropertyValue(value, eq);
641
+ if (val) return Lexer.tokenize(value, index, val.next, {
642
+ key: prop,
643
+ value: val
644
+ }, Lexer.TokenType.KeyValuePair);
645
+ }
646
+ export function keyPropertyValue(value: Utils.SourceArray, index: number): Lexer.Token {
647
+ let token = PrimitiveLiteral.primitiveLiteral(value, index);
648
+ if (token) {
649
+ token.type = Lexer.TokenType.KeyPropertyValue;
650
+ return token;
651
+ }
652
+ }
653
+ export function keyPropertyAlias(value: Utils.SourceArray, index: number): Lexer.Token { return NameOrIdentifier.odataIdentifier(value, index, Lexer.TokenType.KeyPropertyAlias); }
654
+
655
+ export function singleNavigationExpr(value: Utils.SourceArray, index: number): Lexer.Token {
656
+ if (value[index] !== 0x2f) return;
657
+ let member = memberExpr(value, index + 1);
658
+ if (member) return Lexer.tokenize(value, index, member.next, member, Lexer.TokenType.SingleNavigationExpression);
659
+ }
660
+ export function collectionPathExpr(value: Utils.SourceArray, index: number): Lexer.Token {
661
+ let token = countExpr(value, index);
662
+ if (!token) {
663
+ if (value[index] === 0x2f) {
664
+ token = boundFunctionExpr(value, index + 1) ||
665
+ anyExpr(value, index + 1) ||
666
+ allExpr(value, index + 1);
667
+ }
668
+ }
669
+
670
+ if (token) return Lexer.tokenize(value, index, token.next, token, Lexer.TokenType.CollectionPathExpression);
671
+ }
672
+ export function complexPathExpr(value: Utils.SourceArray, index: number): Lexer.Token {
673
+ if (value[index] !== 0x2f) return;
674
+ let start = index;
675
+ index++;
676
+ let token = NameOrIdentifier.qualifiedComplexTypeName(value, index);
677
+ if (token) {
678
+ if (value[token.next] !== 0x2f) return;
679
+ index = token.next + 1;
680
+ }
681
+
682
+ let expr = propertyPathExpr(value, index) ||
683
+ boundFunctionExpr(value, index);
684
+
685
+ if (expr) return Lexer.tokenize(value, start, expr.next, token ? [token, expr] : [expr], Lexer.TokenType.ComplexPathExpression);
686
+ }
687
+ export function singlePathExpr(value: Utils.SourceArray, index: number): Lexer.Token {
688
+ if (value[index] !== 0x2f) return;
689
+ let boundFunction = boundFunctionExpr(value, index + 1);
690
+ if (boundFunction) return Lexer.tokenize(value, index, boundFunction.next, boundFunction, Lexer.TokenType.SinglePathExpression);
691
+ }
692
+ export function functionExpr(value: Utils.SourceArray, index: number): Lexer.Token {
693
+ let namespaceNext = NameOrIdentifier.namespace(value, index);
694
+ if (namespaceNext === index || value[namespaceNext] !== 0x2e) return;
695
+ let start = index;
696
+ index = namespaceNext + 1;
697
+
698
+ let token = NameOrIdentifier.odataIdentifier(value, index);
699
+
700
+ if (!token) return;
701
+ token.position = start;
702
+ token.value.namespace = Utils.stringify(value, start, namespaceNext);
703
+ token.raw = Utils.stringify(value, start, token.next);
704
+
705
+ index = token.next;
706
+ let params = functionExprParameters(value, index);
707
+
708
+ if (!params) return;
709
+
710
+ index = params.next;
711
+ let expr = collectionPathExpr(value, index) ||
712
+ collectionNavigationExpr(value, index) ||
713
+ singleNavigationExpr(value, index) ||
714
+ complexPathExpr(value, index) ||
715
+ singlePathExpr(value, index);
716
+
717
+ if (expr) index = expr.next;
718
+
719
+ return Lexer.tokenize(value, start, index, {
720
+ fn: token,
721
+ params: params,
722
+ expression: expr
723
+ }, Lexer.TokenType.FunctionExpression);
724
+ }
725
+ export function boundFunctionExpr(value: Utils.SourceArray, index: number): Lexer.Token { return functionExpr(value, index); }
726
+
727
+ export function functionExprParameters(value: Utils.SourceArray, index: number): Lexer.Token {
728
+ let open = Lexer.OPEN(value, index);
729
+ if (!open) return;
730
+ let start = index;
731
+ index = open;
732
+
733
+ let params = [];
734
+ let expr = functionExprParameter(value, index);
735
+ while (expr) {
736
+ params.push(expr);
737
+ let comma = Lexer.COMMA(value, expr.next);
738
+ if (comma) {
739
+ index = comma;
740
+ expr = functionExprParameter(value, index);
741
+ if (!expr) return;
742
+ } else {
743
+ index = expr.next;
744
+ expr = null;
745
+ }
746
+ }
747
+
748
+ let close = Lexer.CLOSE(value, index);
749
+ if (!close) return;
750
+ index = close;
751
+
752
+ return Lexer.tokenize(value, start, index, params, Lexer.TokenType.FunctionExpressionParameters);
753
+ }
754
+ export function functionExprParameter(value: Utils.SourceArray, index: number): Lexer.Token {
755
+ let name = parameterName(value, index);
756
+ if (!name) return;
757
+ let eq = Lexer.EQ(value, name.next);
758
+ if (!name || !eq) return;
759
+
760
+ let start = index;
761
+ index = eq;
762
+
763
+ let param = parameterAlias(value, index) ||
764
+ parameterValue(value, index);
765
+
766
+ if (!param) return;
767
+ return Lexer.tokenize(value, start, param.next, {
768
+ name: name,
769
+ value: param
770
+ }, Lexer.TokenType.FunctionExpressionParameter);
771
+ }
772
+ export function parameterName(value: Utils.SourceArray, index: number): Lexer.Token { return NameOrIdentifier.odataIdentifier(value, index, Lexer.TokenType.ParameterName); }
773
+ export function parameterAlias(value: Utils.SourceArray, index: number): Lexer.Token {
774
+ let at = Lexer.AT(value, index);
775
+ if (!at) return;
776
+ let id = NameOrIdentifier.odataIdentifier(value, at);
777
+ if (id) return Lexer.tokenize(value, index, id.next, id.value, Lexer.TokenType.ParameterAlias);
778
+ }
779
+ export function parameterValue(value: Utils.SourceArray, index: number): Lexer.Token {
780
+ let token = ArrayOrObject.arrayOrObject(value, index) ||
781
+ commonExpr(value, index);
782
+ if (token) return Lexer.tokenize(value, index, token.next, token.value, Lexer.TokenType.ParameterValue);
783
+ }
784
+
785
+ export function countExpr(value: Utils.SourceArray, index: number): Lexer.Token {
786
+ if (Utils.equals(value, index, "/$count")) return Lexer.tokenize(value, index, index + 7, "/$count", Lexer.TokenType.CountExpression);
787
+ }
788
+ export function refExpr(value: Utils.SourceArray, index: number): Lexer.Token {
789
+ if (Utils.equals(value, index, "/$ref")) return Lexer.tokenize(value, index, index + 5, "/$ref", Lexer.TokenType.RefExpression);
790
+ }
791
+ export function valueExpr(value: Utils.SourceArray, index: number): Lexer.Token {
792
+ if (Utils.equals(value, index, "/$value")) return Lexer.tokenize(value, index, index + 7, "/$value", Lexer.TokenType.ValueExpression);
793
+ }
794
+
795
+ export function rootExpr(value: Utils.SourceArray, index: number): Lexer.Token {
796
+ if (!Utils.equals(value, index, "$root/")) return;
797
+ let start = index;
798
+ index += 6;
799
+
800
+ let entitySet = NameOrIdentifier.entitySetName(value, index);
801
+ let predicate, entity, token;
802
+ if (entitySet) predicate = keyPredicate(value, entitySet.next);
803
+ if (!(entitySet && predicate)) {
804
+ entity = NameOrIdentifier.singletonEntity(value, index);
805
+ if (!entity) return;
806
+ token = {
807
+ entity: entity
808
+ };
809
+ }else token = {
810
+ entitySet: entitySet,
811
+ keys: predicate
812
+ };
813
+
814
+ index = (predicate || entity).next;
815
+ let nav = singleNavigationExpr(value, index);
816
+ if (nav) index = nav.next;
817
+
818
+ return Lexer.tokenize(value, start, index, {
819
+ current: token,
820
+ next: nav
821
+ }, Lexer.TokenType.RootExpression);
822
+ }
823
+ }
824
+
825
+ export default Expressions;