json_p3 0.2.1
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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/.rubocop.yml +14 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +7 -0
- data/LICENCE +21 -0
- data/README.md +353 -0
- data/Rakefile +23 -0
- data/Steepfile +27 -0
- data/lib/json_p3/cache.rb +40 -0
- data/lib/json_p3/environment.rb +76 -0
- data/lib/json_p3/errors.rb +49 -0
- data/lib/json_p3/filter.rb +426 -0
- data/lib/json_p3/function.rb +16 -0
- data/lib/json_p3/function_extensions/count.rb +15 -0
- data/lib/json_p3/function_extensions/length.rb +17 -0
- data/lib/json_p3/function_extensions/match.rb +62 -0
- data/lib/json_p3/function_extensions/pattern.rb +39 -0
- data/lib/json_p3/function_extensions/search.rb +44 -0
- data/lib/json_p3/function_extensions/value.rb +15 -0
- data/lib/json_p3/lexer.rb +420 -0
- data/lib/json_p3/node.rb +42 -0
- data/lib/json_p3/parser.rb +553 -0
- data/lib/json_p3/path.rb +42 -0
- data/lib/json_p3/segment.rb +102 -0
- data/lib/json_p3/selector.rb +285 -0
- data/lib/json_p3/token.rb +74 -0
- data/lib/json_p3/unescape.rb +112 -0
- data/lib/json_p3/version.rb +5 -0
- data/lib/json_p3.rb +17 -0
- data/performance/benchmark.rb +33 -0
- data/performance/benchmark_ips.rb +29 -0
- data/performance/benchmark_small_citylots.rb +18 -0
- data/performance/memory_profile.rb +19 -0
- data/performance/memory_profile_small_citylots.rb +14 -0
- data/performance/profile.rb +30 -0
- data/sig/json_p3.rbs +1058 -0
- data.tar.gz.sig +1 -0
- metadata +110 -0
- metadata.gz.sig +0 -0
data/sig/json_p3.rbs
ADDED
@@ -0,0 +1,1058 @@
|
|
1
|
+
# RFC 9535 JSONPath query expressions for JSON.
|
2
|
+
module JSONP3
|
3
|
+
DefaultEnvironment: JSONPathEnvironment
|
4
|
+
|
5
|
+
def self.find: (String path, untyped data) -> JSONPathNodeList
|
6
|
+
|
7
|
+
def self.compile: (String path) -> JSONPath
|
8
|
+
end
|
9
|
+
|
10
|
+
module JSONP3
|
11
|
+
# A least recently used cache relying on Ruby hash insertion order.
|
12
|
+
class LRUCache
|
13
|
+
@data: untyped
|
14
|
+
|
15
|
+
@max_size: Integer
|
16
|
+
|
17
|
+
attr_reader max_size: Integer
|
18
|
+
|
19
|
+
def initialize: (Integer max_size) -> void
|
20
|
+
|
21
|
+
# Return the cached value or nil if _key_ does not exist.
|
22
|
+
def []: (untyped key) -> (nil | untyped)
|
23
|
+
|
24
|
+
def []=: (untyped key, untyped value) -> untyped
|
25
|
+
|
26
|
+
def length: () -> Integer
|
27
|
+
|
28
|
+
def keys: () -> Array[untyped]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module JSONP3
|
33
|
+
# JSONPath configuration
|
34
|
+
class JSONPathEnvironment
|
35
|
+
MAX_INT_INDEX: Numeric
|
36
|
+
|
37
|
+
MIN_INT_INDEX: Numeric
|
38
|
+
|
39
|
+
MAX_RECURSION_DEPTH: Integer
|
40
|
+
|
41
|
+
# XXX: I don't known how to specify a class rather than a class instance.
|
42
|
+
NAME_SELECTOR: untyped
|
43
|
+
|
44
|
+
INDEX_SELECTOR: untyped
|
45
|
+
|
46
|
+
@parser: Parser
|
47
|
+
|
48
|
+
@function_extensions: Hash[String, FunctionExtension]
|
49
|
+
|
50
|
+
attr_accessor function_extensions: Hash[String, FunctionExtension]
|
51
|
+
|
52
|
+
def initialize: () -> void
|
53
|
+
|
54
|
+
# Prepare JSONPath expression _query_ for repeated application.
|
55
|
+
# @param query [String]
|
56
|
+
# @return [JSONPath]
|
57
|
+
def compile: (String query) -> JSONPath
|
58
|
+
|
59
|
+
# Apply JSONPath expression _query_ to _value_.
|
60
|
+
# @param query [String]
|
61
|
+
# @param value [JSON-like data]
|
62
|
+
# @return [Array<JSONPath>]
|
63
|
+
def find: (String query, untyped value) -> JSONPathNodeList
|
64
|
+
|
65
|
+
def setup_function_extensions: () -> void
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
module JSONP3
|
70
|
+
# An exception raised when a JSONPathEnvironment is misconfigured.
|
71
|
+
class JSONPathEnvironmentError < StandardError
|
72
|
+
end
|
73
|
+
|
74
|
+
# Base class for JSONPath exceptions that happen when parsing or evaluating a query.
|
75
|
+
class JSONPathError < StandardError
|
76
|
+
FULL_MESSAGE: bool
|
77
|
+
|
78
|
+
@token: Token
|
79
|
+
|
80
|
+
def initialize: (String msg, Token token) -> void
|
81
|
+
end
|
82
|
+
|
83
|
+
class JSONPathSyntaxError < JSONPathError
|
84
|
+
end
|
85
|
+
|
86
|
+
class JSONPathTypeError < JSONPathError
|
87
|
+
end
|
88
|
+
|
89
|
+
class JSONPathNameError < JSONPathError
|
90
|
+
end
|
91
|
+
|
92
|
+
class JSONPathRecursionError < JSONPathError
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
module JSONP3
|
97
|
+
# Base class for all filter expression nodes.
|
98
|
+
class Expression
|
99
|
+
@token: Token
|
100
|
+
|
101
|
+
# @dynamic token
|
102
|
+
attr_reader token: Token
|
103
|
+
|
104
|
+
def initialize: (Token token) -> void
|
105
|
+
|
106
|
+
# Evaluate the filter expressin in the given context.
|
107
|
+
def evaluate: (FilterContext _context) -> untyped
|
108
|
+
end
|
109
|
+
|
110
|
+
# An expression that evaluates to true or false.
|
111
|
+
class FilterExpression < Expression
|
112
|
+
@expression: Expression
|
113
|
+
|
114
|
+
attr_reader expression: Expression
|
115
|
+
|
116
|
+
def initialize: (Token token, Expression expression) -> void
|
117
|
+
|
118
|
+
def evaluate: (FilterContext context) -> untyped
|
119
|
+
|
120
|
+
def to_s: () -> String
|
121
|
+
|
122
|
+
def ==: (untyped other) -> bool
|
123
|
+
|
124
|
+
alias eql? ==
|
125
|
+
|
126
|
+
def hash: () -> Integer
|
127
|
+
end
|
128
|
+
|
129
|
+
# Base class for expression literals.
|
130
|
+
class FilterExpressionLiteral < Expression
|
131
|
+
@value: untyped
|
132
|
+
|
133
|
+
attr_reader value: untyped
|
134
|
+
|
135
|
+
def initialize: (Token token, untyped value) -> void
|
136
|
+
|
137
|
+
def evaluate: (FilterContext _context) -> untyped
|
138
|
+
|
139
|
+
def to_s: () -> String
|
140
|
+
|
141
|
+
def ==: (untyped other) -> bool
|
142
|
+
|
143
|
+
alias eql? ==
|
144
|
+
|
145
|
+
def hash: () -> Integer
|
146
|
+
end
|
147
|
+
|
148
|
+
# Literal true or false.
|
149
|
+
class BooleanLiteral < FilterExpressionLiteral
|
150
|
+
end
|
151
|
+
|
152
|
+
# A double or single quoted string literal.
|
153
|
+
class StringLiteral < FilterExpressionLiteral
|
154
|
+
def to_s: () -> String
|
155
|
+
end
|
156
|
+
|
157
|
+
# A literal integer.
|
158
|
+
class IntegerLiteral < FilterExpressionLiteral
|
159
|
+
end
|
160
|
+
|
161
|
+
# A literal float
|
162
|
+
class FloatLiteral < FilterExpressionLiteral
|
163
|
+
end
|
164
|
+
|
165
|
+
# A literal null
|
166
|
+
class NullLiteral < FilterExpressionLiteral
|
167
|
+
def to_s: () -> "null"
|
168
|
+
end
|
169
|
+
|
170
|
+
# An expression prefixed with the logical not operator.
|
171
|
+
class LogicalNotExpression < Expression
|
172
|
+
@expression: Expression
|
173
|
+
|
174
|
+
attr_reader expression: Expression
|
175
|
+
|
176
|
+
def initialize: (Token token, Expression expression) -> void
|
177
|
+
|
178
|
+
def evaluate: (FilterContext context) -> untyped
|
179
|
+
|
180
|
+
def to_s: () -> ::String
|
181
|
+
|
182
|
+
def ==: (untyped other) -> bool
|
183
|
+
|
184
|
+
alias eql? ==
|
185
|
+
|
186
|
+
def hash: () -> Integer
|
187
|
+
end
|
188
|
+
|
189
|
+
# Base class for expression with a left expression, operator and right expression.
|
190
|
+
class InfixExpression < Expression
|
191
|
+
@left: Expression
|
192
|
+
|
193
|
+
@right: Expression
|
194
|
+
|
195
|
+
attr_reader left: Expression
|
196
|
+
|
197
|
+
attr_reader right: Expression
|
198
|
+
|
199
|
+
def initialize: (Token token, Expression left, Expression right) -> void
|
200
|
+
|
201
|
+
def evaluate: (FilterContext _context) -> untyped
|
202
|
+
|
203
|
+
def to_s: () -> String
|
204
|
+
|
205
|
+
def ==: (untyped other) -> bool
|
206
|
+
|
207
|
+
alias eql? ==
|
208
|
+
|
209
|
+
def hash: () -> Integer
|
210
|
+
end
|
211
|
+
|
212
|
+
# A logical `&&` expression.
|
213
|
+
class LogicalAndExpression < InfixExpression
|
214
|
+
def evaluate: (FilterContext context) -> untyped
|
215
|
+
|
216
|
+
def to_s: () -> ::String
|
217
|
+
end
|
218
|
+
|
219
|
+
# A logical `||` expression.
|
220
|
+
class LogicalOrExpression < InfixExpression
|
221
|
+
def evaluate: (FilterContext context) -> untyped
|
222
|
+
|
223
|
+
def to_s: () -> ::String
|
224
|
+
end
|
225
|
+
|
226
|
+
# An `==` expression.
|
227
|
+
class EqExpression < InfixExpression
|
228
|
+
def evaluate: (FilterContext context) -> untyped
|
229
|
+
|
230
|
+
def to_s: () -> ::String
|
231
|
+
end
|
232
|
+
|
233
|
+
# A `!=` expression.
|
234
|
+
class NeExpression < InfixExpression
|
235
|
+
def evaluate: (FilterContext context) -> untyped
|
236
|
+
|
237
|
+
def to_s: () -> ::String
|
238
|
+
end
|
239
|
+
|
240
|
+
# A `<=` expression.
|
241
|
+
class LeExpression < InfixExpression
|
242
|
+
def evaluate: (FilterContext context) -> untyped
|
243
|
+
|
244
|
+
def to_s: () -> ::String
|
245
|
+
end
|
246
|
+
|
247
|
+
# A `>=` expression.
|
248
|
+
class GeExpression < InfixExpression
|
249
|
+
def evaluate: (FilterContext context) -> untyped
|
250
|
+
|
251
|
+
def to_s: () -> ::String
|
252
|
+
end
|
253
|
+
|
254
|
+
# A `<` expression.
|
255
|
+
class LtExpression < InfixExpression
|
256
|
+
def evaluate: (FilterContext context) -> untyped
|
257
|
+
|
258
|
+
def to_s: () -> ::String
|
259
|
+
end
|
260
|
+
|
261
|
+
# A `>` expression.
|
262
|
+
class GtExpression < InfixExpression
|
263
|
+
def evaluate: (FilterContext context) -> untyped
|
264
|
+
|
265
|
+
def to_s: () -> ::String
|
266
|
+
end
|
267
|
+
|
268
|
+
# Base class for all embedded filter queries
|
269
|
+
class QueryExpression < Expression
|
270
|
+
@query: JSONPath
|
271
|
+
|
272
|
+
attr_reader query: JSONPath
|
273
|
+
|
274
|
+
def initialize: (Token token, JSONPath query) -> void
|
275
|
+
|
276
|
+
def evaluate: (FilterContext _context) -> untyped
|
277
|
+
|
278
|
+
def to_s: () -> String
|
279
|
+
|
280
|
+
def ==: (untyped other) -> bool
|
281
|
+
|
282
|
+
alias eql? ==
|
283
|
+
|
284
|
+
def hash: () -> Integer
|
285
|
+
end
|
286
|
+
|
287
|
+
# An embedded query starting at the current node.
|
288
|
+
class RelativeQueryExpression < QueryExpression
|
289
|
+
def evaluate: (FilterContext context) -> untyped
|
290
|
+
|
291
|
+
def to_s: () -> ::String
|
292
|
+
end
|
293
|
+
|
294
|
+
# An embedded query starting at the root node.
|
295
|
+
class RootQueryExpression < QueryExpression
|
296
|
+
def evaluate: (FilterContext context) -> untyped
|
297
|
+
|
298
|
+
def to_s: () -> String
|
299
|
+
end
|
300
|
+
|
301
|
+
# A filter function call.
|
302
|
+
class FunctionExpression < Expression
|
303
|
+
@name: String
|
304
|
+
|
305
|
+
@args: Array[Expression]
|
306
|
+
|
307
|
+
attr_reader name: String
|
308
|
+
|
309
|
+
attr_reader args: Array[Expression]
|
310
|
+
|
311
|
+
# @param name [String]
|
312
|
+
# @param args [Array<Expression>]
|
313
|
+
def initialize: (Token token, String name, Array[Expression] args) -> void
|
314
|
+
|
315
|
+
def evaluate: (FilterContext context) -> untyped
|
316
|
+
|
317
|
+
def to_s: () -> ::String
|
318
|
+
|
319
|
+
def ==: (untyped other) -> bool
|
320
|
+
|
321
|
+
alias eql? ==
|
322
|
+
|
323
|
+
def hash: () -> Integer
|
324
|
+
|
325
|
+
private
|
326
|
+
|
327
|
+
def unpack_node_lists: (FunctionExtension func, Array[untyped] args) -> Array[untyped]
|
328
|
+
end
|
329
|
+
|
330
|
+
def self.truthy?: (untyped obj) -> bool
|
331
|
+
|
332
|
+
def self.eq?: (Expression left, Expression right) -> bool
|
333
|
+
|
334
|
+
def self.lt?: (Expression left, Expression right) -> bool
|
335
|
+
|
336
|
+
# Contextural information and data used for evaluating a filter expression.
|
337
|
+
class FilterContext
|
338
|
+
@env: JSONPathEnvironment
|
339
|
+
|
340
|
+
@current: untyped
|
341
|
+
|
342
|
+
@root: untyped
|
343
|
+
|
344
|
+
attr_reader env: JSONPathEnvironment
|
345
|
+
|
346
|
+
attr_reader current: untyped
|
347
|
+
|
348
|
+
attr_reader root: untyped
|
349
|
+
|
350
|
+
def initialize: (JSONPathEnvironment env, untyped current, untyped root) -> void
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
module JSONP3
|
355
|
+
class ExpressionType
|
356
|
+
VALUE: :value_expression
|
357
|
+
|
358
|
+
LOGICAL: :logical_expression
|
359
|
+
|
360
|
+
NODES: :nodes_expression
|
361
|
+
end
|
362
|
+
|
363
|
+
# Base class for all filter functions.
|
364
|
+
class FunctionExtension
|
365
|
+
ARG_TYPES: ::Array[Symbol]
|
366
|
+
|
367
|
+
RETURN_TYPE: Symbol
|
368
|
+
|
369
|
+
def call: (*untyped _args, **untyped _kwargs) -> untyped
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
module JSONP3
|
374
|
+
# Return an array of tokens for the JSONPath expression _query_.
|
375
|
+
#
|
376
|
+
# @param query [String] the JSONPath expression to tokenize.
|
377
|
+
# @return [Array<Token>]
|
378
|
+
def self.tokenize: (String query) -> Array[Token]
|
379
|
+
|
380
|
+
# JSONPath query expreession lexical scanner.
|
381
|
+
#
|
382
|
+
# @see tokenize
|
383
|
+
class Lexer
|
384
|
+
@filter_depth: Integer
|
385
|
+
|
386
|
+
@paren_stack: Array[Integer]
|
387
|
+
|
388
|
+
@tokens: Array[Token]
|
389
|
+
|
390
|
+
@start: Integer
|
391
|
+
|
392
|
+
@query: String
|
393
|
+
|
394
|
+
@scanner: untyped
|
395
|
+
|
396
|
+
RE_INT: ::Regexp
|
397
|
+
|
398
|
+
RE_NAME: ::Regexp
|
399
|
+
|
400
|
+
RE_WHITESPACE: ::Regexp
|
401
|
+
|
402
|
+
S_ESCAPES: Set[String]
|
403
|
+
|
404
|
+
# @dynamic tokens
|
405
|
+
attr_reader tokens: Array[Token]
|
406
|
+
|
407
|
+
def initialize: (String query) -> void
|
408
|
+
|
409
|
+
def run: () -> void
|
410
|
+
|
411
|
+
# Generate a new token with the given type.
|
412
|
+
# @param token_type [Symbol] one of the constants defined on the _Token_ class.
|
413
|
+
# @param value [String | nil] a the token's value, if it is known, otherwise the
|
414
|
+
# value will be sliced from @query. This is a performance optimisation.
|
415
|
+
def emit: (Symbol token_type, ?untyped value) -> void
|
416
|
+
|
417
|
+
def next: () -> String
|
418
|
+
|
419
|
+
def ignore: () -> void
|
420
|
+
|
421
|
+
def backup: () -> void
|
422
|
+
|
423
|
+
def peek: () -> String
|
424
|
+
|
425
|
+
# Advance the lexer if the next character is equal to _char_.
|
426
|
+
def accept?: (String | Regexp pattern) -> bool
|
427
|
+
|
428
|
+
# Accept a run of digits, possibly preceded by a negative sign.
|
429
|
+
# Does not handle exponents.
|
430
|
+
def accept_int?: () -> bool
|
431
|
+
|
432
|
+
def ignore_whitespace?: () -> (false | true)
|
433
|
+
|
434
|
+
def error: (String message) -> void
|
435
|
+
|
436
|
+
def lex_root: () -> (nil | :lex_segment)
|
437
|
+
|
438
|
+
def lex_segment: () -> (nil | :lex_shorthand_selector | untyped)
|
439
|
+
|
440
|
+
def lex_descendant_segment: () -> untyped
|
441
|
+
|
442
|
+
def lex_shorthand_selector: () -> (nil | :lex_segment)
|
443
|
+
|
444
|
+
def lex_inside_bracketed_segment: () -> untyped
|
445
|
+
|
446
|
+
def lex_inside_filter: () -> untyped
|
447
|
+
|
448
|
+
def self.lex_string_factory: (String quote, Symbol state, Symbol token) -> untyped
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
type location_element = String | Integer | Array[location_element]
|
453
|
+
|
454
|
+
module JSONP3
|
455
|
+
# A JSON-like value and its location.
|
456
|
+
class JSONPathNode
|
457
|
+
@value: untyped
|
458
|
+
|
459
|
+
@location: Array[location_element]
|
460
|
+
|
461
|
+
@root: untyped
|
462
|
+
|
463
|
+
# @dynamic value, location, root
|
464
|
+
attr_reader value: untyped
|
465
|
+
|
466
|
+
# @dynamic value, location, root
|
467
|
+
attr_reader location: Array[location_element]
|
468
|
+
|
469
|
+
# @dynamic value, location, root
|
470
|
+
attr_reader root: untyped
|
471
|
+
|
472
|
+
# @param value [JSON-like] the value at this node.
|
473
|
+
# @param location [Array<String | Integer | Array<String | Integer>>] the sequence of
|
474
|
+
# names and/or indicies leading to _value_ in _root_.
|
475
|
+
# @param root [JSON-like] the root value containing _value_ at _location_.
|
476
|
+
def initialize: (untyped value, Array[location_element] location, untyped root) -> void
|
477
|
+
|
478
|
+
# Return the normalized path to this node.
|
479
|
+
# @return [String] the normalized path.
|
480
|
+
def path: () -> ::String
|
481
|
+
|
482
|
+
# Return a new node that is a child of this node.
|
483
|
+
# @param value the JSON-like value at the new node.
|
484
|
+
# @param key [Integer, String] the array index or hash key assiciated with _value_.
|
485
|
+
def new_child: (untyped value, String | Integer key) -> JSONPathNode
|
486
|
+
|
487
|
+
def to_s: () -> ::String
|
488
|
+
end
|
489
|
+
|
490
|
+
# An array of JSONPathNode instances.
|
491
|
+
class JSONPathNodeList < Array[JSONPathNode]
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
module JSONP3
|
496
|
+
# Step through tokens
|
497
|
+
class Stream
|
498
|
+
@tokens: Array[Token]
|
499
|
+
|
500
|
+
@index: Integer
|
501
|
+
|
502
|
+
@eoi: Token
|
503
|
+
|
504
|
+
def initialize: (Array[Token] tokens) -> void
|
505
|
+
|
506
|
+
def next: () -> Token
|
507
|
+
|
508
|
+
def peek: () -> Token
|
509
|
+
|
510
|
+
def expect: (Symbol token_type) -> void
|
511
|
+
|
512
|
+
def expect_not: (Symbol token_type, String message) -> void
|
513
|
+
|
514
|
+
def to_s: () -> ::String
|
515
|
+
end
|
516
|
+
|
517
|
+
class Precedence
|
518
|
+
LOWEST: 1
|
519
|
+
|
520
|
+
LOGICAL_OR: 3
|
521
|
+
|
522
|
+
LOGICAL_AND: 4
|
523
|
+
|
524
|
+
RELATIONAL: 5
|
525
|
+
|
526
|
+
PREFIX: 7
|
527
|
+
end
|
528
|
+
|
529
|
+
# A JSONPath expression parser.
|
530
|
+
class Parser
|
531
|
+
@env: JSONPathEnvironment
|
532
|
+
|
533
|
+
@name_selector: untyped
|
534
|
+
|
535
|
+
@index_selector: untyped
|
536
|
+
|
537
|
+
def initialize: (JSONPathEnvironment env) -> void
|
538
|
+
|
539
|
+
# Parse an array of tokens into an abstract syntax tree.
|
540
|
+
# @param tokens [Array<Token>] tokens from the lexer.
|
541
|
+
# @return [Array<Segment>]
|
542
|
+
def parse: (Array[Token] tokens) -> Array[Segment]
|
543
|
+
|
544
|
+
def parse_query: (Stream stream) -> Array[Segment]
|
545
|
+
|
546
|
+
def parse_selectors: (Stream stream) -> Array[Selector]
|
547
|
+
|
548
|
+
def parse_bracketed_selection: (Stream stream) -> Array[Selector]
|
549
|
+
|
550
|
+
def parse_index_or_slice: (Stream stream) -> Selector
|
551
|
+
|
552
|
+
def parse_slice_selector: (Stream stream) -> Selector
|
553
|
+
|
554
|
+
def parse_filter_selector: (Stream stream) -> Selector
|
555
|
+
|
556
|
+
def parse_filter_expression: (Stream stream, ?Integer precedence) -> Expression
|
557
|
+
|
558
|
+
def parse_integer_literal: (Stream stream) -> Expression
|
559
|
+
|
560
|
+
def parse_float_literal: (Stream stream) -> Expression
|
561
|
+
|
562
|
+
def parse_function_expression: (Stream stream) -> Expression
|
563
|
+
|
564
|
+
def parse_grouped_expression: (Stream stream) -> Expression
|
565
|
+
|
566
|
+
def parse_prefix_expression: (Stream stream) -> Expression
|
567
|
+
|
568
|
+
def parse_root_query: (Stream stream) -> Expression
|
569
|
+
|
570
|
+
def parse_relative_query: (Stream stream) -> Expression
|
571
|
+
|
572
|
+
def parse_infix_expression: (Stream stream, Expression left) -> Expression
|
573
|
+
|
574
|
+
def parse_i_json_int: (Token token) -> Integer
|
575
|
+
|
576
|
+
def decode_string_literal: (Token token) -> String
|
577
|
+
|
578
|
+
def raise_for_non_comparable_function: (Expression expression) -> void
|
579
|
+
|
580
|
+
def raise_for_uncompared_literal: (Expression expression) -> void
|
581
|
+
|
582
|
+
def validate_function_extension_signature: (Token token, untyped args) -> void
|
583
|
+
|
584
|
+
def function_return_type: (Expression expression) -> (Symbol | nil)
|
585
|
+
|
586
|
+
PRECEDENCES: ::Hash[Symbol, Integer]
|
587
|
+
|
588
|
+
BINARY_OPERATORS: ::Hash[Symbol, "&&" | "||" | "==" | ">=" | ">" | "<=" | "<" | "!="]
|
589
|
+
|
590
|
+
COMPARISON_OPERATORS: Set[String]
|
591
|
+
end
|
592
|
+
end
|
593
|
+
|
594
|
+
module JSONP3
|
595
|
+
# A compiled JSONPath expression ready to be applied to JSON-like values.
|
596
|
+
class JSONPath
|
597
|
+
@env: JSONPathEnvironment
|
598
|
+
|
599
|
+
@segments: Array[Segment]
|
600
|
+
|
601
|
+
def initialize: (JSONPathEnvironment env, Array[Segment] segments) -> void
|
602
|
+
|
603
|
+
def to_s: () -> ::String
|
604
|
+
|
605
|
+
# Apply this JSONPath expression to JSON-like value _root_.
|
606
|
+
# @param root [Array, Hash, String, Integer] the root JSON-like value to apply this query to.
|
607
|
+
# @return [Array<JSONPathNode>] the sequence of nodes found while applying this query to _root_.
|
608
|
+
def find: (untyped root) -> untyped
|
609
|
+
|
610
|
+
alias apply find
|
611
|
+
|
612
|
+
# Return true if this JSONPath expression is a singular query.
|
613
|
+
def singular?: () -> (false | true)
|
614
|
+
|
615
|
+
# Return true if this JSONPath expression has no segments.
|
616
|
+
def empty?: () -> (false | true)
|
617
|
+
end
|
618
|
+
end
|
619
|
+
|
620
|
+
module JSONP3
|
621
|
+
# Base class for all JSONPath segments.
|
622
|
+
class Segment
|
623
|
+
@env: JSONPathEnvironment
|
624
|
+
|
625
|
+
@token: Token
|
626
|
+
|
627
|
+
@selectors: Array[Selector]
|
628
|
+
|
629
|
+
# @dynamic token, selectors
|
630
|
+
attr_reader token: Token
|
631
|
+
|
632
|
+
# @dynamic token, selectors
|
633
|
+
attr_reader selectors: Array[Selector]
|
634
|
+
|
635
|
+
def initialize: (JSONPathEnvironment env, Token token, Array[Selector] selectors) -> void
|
636
|
+
|
637
|
+
# Select the children of each node in _nodes_.
|
638
|
+
def resolve: (Array[JSONPathNode] _nodes) -> Array[JSONPathNode]
|
639
|
+
end
|
640
|
+
|
641
|
+
# The child selection segment.
|
642
|
+
class ChildSegment < Segment
|
643
|
+
def resolve: (Array[JSONPathNode] nodes) -> Array[JSONPathNode]
|
644
|
+
|
645
|
+
def to_s: () -> ::String
|
646
|
+
|
647
|
+
def ==: (untyped other) -> bool
|
648
|
+
|
649
|
+
alias eql? ==
|
650
|
+
|
651
|
+
def hash: () -> Integer
|
652
|
+
end
|
653
|
+
|
654
|
+
# The recursive descent segment
|
655
|
+
class RecursiveDescentSegment < Segment
|
656
|
+
def resolve: (Array[JSONPathNode] nodes) -> Array[JSONPathNode]
|
657
|
+
|
658
|
+
def to_s: () -> ::String
|
659
|
+
|
660
|
+
def ==: (untyped other) -> bool
|
661
|
+
|
662
|
+
alias eql? ==
|
663
|
+
|
664
|
+
def hash: () -> Integer
|
665
|
+
|
666
|
+
def visit: (JSONPathNode node, ?::Integer depth) -> Array[JSONPathNode]
|
667
|
+
end
|
668
|
+
end
|
669
|
+
|
670
|
+
module JSONP3
|
671
|
+
# Base class for all JSONPath selectors
|
672
|
+
class Selector
|
673
|
+
@env: JSONPathEnvironment
|
674
|
+
|
675
|
+
@token: Token
|
676
|
+
|
677
|
+
# @dynamic token
|
678
|
+
attr_reader token: Token
|
679
|
+
|
680
|
+
def initialize: (JSONPathEnvironment env, Token token) -> void
|
681
|
+
|
682
|
+
# Apply this selector to _node_.
|
683
|
+
# @return [Array<JSONPathNode>]
|
684
|
+
def resolve: (JSONPathNode _node) -> Array[JSONPathNode]
|
685
|
+
|
686
|
+
# Return true if this selector is a singular selector.
|
687
|
+
def singular?: () -> false
|
688
|
+
end
|
689
|
+
|
690
|
+
# The name selector select values from hashes given a key.
|
691
|
+
class NameSelector < Selector
|
692
|
+
@name: String
|
693
|
+
|
694
|
+
# @dynamic name
|
695
|
+
attr_reader name: String
|
696
|
+
|
697
|
+
def initialize: (JSONPathEnvironment env, Token token, String name) -> void
|
698
|
+
|
699
|
+
def resolve: (JSONPathNode node) -> ::Array[JSONPathNode]
|
700
|
+
|
701
|
+
def singular?: () -> true
|
702
|
+
|
703
|
+
def to_s: () -> String
|
704
|
+
|
705
|
+
def ==: (untyped other) -> bool
|
706
|
+
|
707
|
+
alias eql? ==
|
708
|
+
|
709
|
+
def hash: () -> Integer
|
710
|
+
end
|
711
|
+
|
712
|
+
class SymbolNameSelector < NameSelector
|
713
|
+
@name: String
|
714
|
+
|
715
|
+
@sym: Symbol
|
716
|
+
|
717
|
+
# @dynamic name
|
718
|
+
attr_reader name: String
|
719
|
+
|
720
|
+
def initialize: (JSONPathEnvironment env, Token token, String name) -> void
|
721
|
+
|
722
|
+
def resolve: (JSONPathNode node) -> ::Array[JSONPathNode]
|
723
|
+
|
724
|
+
def singular?: () -> true
|
725
|
+
|
726
|
+
def to_s: () -> String
|
727
|
+
|
728
|
+
def ==: (untyped other) -> bool
|
729
|
+
|
730
|
+
alias eql? ==
|
731
|
+
|
732
|
+
def hash: () -> Integer
|
733
|
+
end
|
734
|
+
|
735
|
+
# The index selector selects values from arrays given an index.
|
736
|
+
class IndexSelector < Selector
|
737
|
+
@index: Integer
|
738
|
+
|
739
|
+
# @dynamic index
|
740
|
+
attr_reader index: Integer
|
741
|
+
|
742
|
+
def initialize: (JSONPathEnvironment env, Token token, Integer index) -> void
|
743
|
+
|
744
|
+
def resolve: (JSONPathNode node) -> Array[JSONPathNode]
|
745
|
+
|
746
|
+
def singular?: () -> true
|
747
|
+
|
748
|
+
def to_s: () -> String
|
749
|
+
|
750
|
+
def ==: (untyped other) -> bool
|
751
|
+
|
752
|
+
alias eql? ==
|
753
|
+
|
754
|
+
def hash: () -> Integer
|
755
|
+
|
756
|
+
private
|
757
|
+
|
758
|
+
def normalize: (Integer index, Integer length) -> Integer
|
759
|
+
end
|
760
|
+
|
761
|
+
# The wildcard selector selects all elements from an array or values from a hash.
|
762
|
+
class WildcardSelector < Selector
|
763
|
+
def resolve: (JSONPathNode node) -> Array[JSONPathNode]
|
764
|
+
|
765
|
+
def to_s: () -> "*"
|
766
|
+
|
767
|
+
def ==: (untyped other) -> bool
|
768
|
+
|
769
|
+
alias eql? ==
|
770
|
+
|
771
|
+
def hash: () -> Integer
|
772
|
+
end
|
773
|
+
|
774
|
+
# The slice selector selects a range of elements from an array.
|
775
|
+
class SliceSelector < Selector
|
776
|
+
@start: (Integer | nil)
|
777
|
+
|
778
|
+
@stop: (Integer | nil)
|
779
|
+
|
780
|
+
@step: Integer
|
781
|
+
|
782
|
+
# @dynamic start, stop, step
|
783
|
+
attr_reader start: (Integer | nil)
|
784
|
+
|
785
|
+
# @dynamic start, stop, step
|
786
|
+
attr_reader stop: (Integer | nil)
|
787
|
+
|
788
|
+
# @dynamic start, stop, step
|
789
|
+
attr_reader step: Integer
|
790
|
+
|
791
|
+
def initialize: (JSONPathEnvironment env, Token token, (Integer | nil) start, (Integer | nil) stop, (Integer | nil) step) -> void
|
792
|
+
|
793
|
+
def resolve: (JSONPathNode node) -> Array[JSONPathNode]
|
794
|
+
|
795
|
+
def to_s: () -> ::String
|
796
|
+
|
797
|
+
def ==: (untyped other) -> bool
|
798
|
+
|
799
|
+
alias eql? ==
|
800
|
+
|
801
|
+
def hash: () -> Integer
|
802
|
+
|
803
|
+
private
|
804
|
+
|
805
|
+
def normalized_start: (Integer length) -> Integer
|
806
|
+
|
807
|
+
def normalized_stop: (Integer length) -> Integer
|
808
|
+
end
|
809
|
+
|
810
|
+
# Select array elements or hash values according to a filter expression.
|
811
|
+
class FilterSelector < Selector
|
812
|
+
@expression: Expression
|
813
|
+
|
814
|
+
# @dynamic expression
|
815
|
+
attr_reader expression: Expression
|
816
|
+
|
817
|
+
def initialize: (JSONPathEnvironment env, Token token, Expression expression) -> void
|
818
|
+
|
819
|
+
def resolve: (JSONPathNode node) -> Array[JSONPathNode]
|
820
|
+
|
821
|
+
def to_s: () -> ::String
|
822
|
+
|
823
|
+
def ==: (untyped other) -> bool
|
824
|
+
|
825
|
+
alias eql? ==
|
826
|
+
|
827
|
+
def hash: () -> Integer
|
828
|
+
end
|
829
|
+
end
|
830
|
+
|
831
|
+
module JSONP3
|
832
|
+
# Tokens are produced by the lexer and consumed by the parser. Each token contains sub
|
833
|
+
# string from a JSONPath expression, its location within the JSONPath expression and a
|
834
|
+
# symbol indicating what type of token it is.
|
835
|
+
class Token
|
836
|
+
@type: Symbol
|
837
|
+
|
838
|
+
@value: String
|
839
|
+
|
840
|
+
@start: Integer
|
841
|
+
|
842
|
+
@query: String
|
843
|
+
|
844
|
+
@message: (String | nil)
|
845
|
+
|
846
|
+
EOI: :token_eoi
|
847
|
+
|
848
|
+
ERROR: :token_error
|
849
|
+
|
850
|
+
SHORTHAND_NAME: :token_shorthand_name
|
851
|
+
|
852
|
+
COLON: :token_colon
|
853
|
+
|
854
|
+
COMMA: :token_comma
|
855
|
+
|
856
|
+
DOT: :token_dot
|
857
|
+
|
858
|
+
DOUBLE_DOT: :token_double_dot
|
859
|
+
|
860
|
+
FILTER: :token_filter
|
861
|
+
|
862
|
+
INDEX: :token_index
|
863
|
+
|
864
|
+
LBRACKET: :token_lbracket
|
865
|
+
|
866
|
+
NAME: :token_name
|
867
|
+
|
868
|
+
RBRACKET: :token_rbracket
|
869
|
+
|
870
|
+
ROOT: :token_root
|
871
|
+
|
872
|
+
WILD: :token_wild
|
873
|
+
|
874
|
+
AND: :token_and
|
875
|
+
|
876
|
+
CURRENT: :token_current
|
877
|
+
|
878
|
+
DOUBLE_QUOTE_STRING: :token_double_quote_string
|
879
|
+
|
880
|
+
EQ: :token_eq
|
881
|
+
|
882
|
+
FALSE: :token_false
|
883
|
+
|
884
|
+
FLOAT: :token_float
|
885
|
+
|
886
|
+
FUNCTION: :token_function
|
887
|
+
|
888
|
+
GE: :token_ge
|
889
|
+
|
890
|
+
GT: :token_gt
|
891
|
+
|
892
|
+
INT: :token_int
|
893
|
+
|
894
|
+
LE: :token_le
|
895
|
+
|
896
|
+
LPAREN: :token_lparen
|
897
|
+
|
898
|
+
LT: :token_lt
|
899
|
+
|
900
|
+
NE: :token_ne
|
901
|
+
|
902
|
+
NOT: :token_not
|
903
|
+
|
904
|
+
NULL: :token_null
|
905
|
+
|
906
|
+
OP: :token_op
|
907
|
+
|
908
|
+
OR: :token_or
|
909
|
+
|
910
|
+
RPAREN: :token_rparen
|
911
|
+
|
912
|
+
SINGLE_QUOTE_STRING: :token_single_quote_string
|
913
|
+
|
914
|
+
TRUE: :token_true
|
915
|
+
|
916
|
+
# @dynamic type, value, start, query
|
917
|
+
attr_reader type: Symbol
|
918
|
+
|
919
|
+
# @dynamic type, value, start, query
|
920
|
+
attr_reader value: String
|
921
|
+
|
922
|
+
# @dynamic type, value, start, query
|
923
|
+
attr_reader start: Integer
|
924
|
+
|
925
|
+
# @dynamic type, value, start, query
|
926
|
+
attr_reader query: String
|
927
|
+
|
928
|
+
# @dynamic type, value, start, query
|
929
|
+
attr_reader message: (String | nil)
|
930
|
+
|
931
|
+
def initialize: (Symbol type, String value, Integer start, String query, ?message: (String | nil)?) -> void
|
932
|
+
|
933
|
+
def ==: (untyped other) -> bool
|
934
|
+
|
935
|
+
alias eql? ==
|
936
|
+
|
937
|
+
def hash: () -> Integer
|
938
|
+
end
|
939
|
+
end
|
940
|
+
|
941
|
+
module JSONP3
|
942
|
+
# Replace escape sequences with their equivalent Unicode code point.
|
943
|
+
# @param value [String]
|
944
|
+
# @param quote [String] one of '"' or "'".
|
945
|
+
# @param token [Token]
|
946
|
+
# @return [String] A new string without escape seqeuences.
|
947
|
+
def self.unescape_string: (String value, String quote, Token token) -> String
|
948
|
+
|
949
|
+
def self.decode_hex_char: (untyped value, untyped index, Token token) -> ::Array[untyped]
|
950
|
+
|
951
|
+
def self.parse_hex_digits: (untyped digits, Token token) -> untyped
|
952
|
+
|
953
|
+
def self.high_surrogate?: (untyped code_point) -> untyped
|
954
|
+
|
955
|
+
def self.low_surrogate?: (untyped code_point) -> untyped
|
956
|
+
|
957
|
+
def self.code_point_to_string: (untyped code_point, Token token) -> untyped
|
958
|
+
end
|
959
|
+
|
960
|
+
module JSONP3
|
961
|
+
VERSION: String
|
962
|
+
end
|
963
|
+
|
964
|
+
module JSONP3
|
965
|
+
# The standard `count` function.
|
966
|
+
class Count < FunctionExtension
|
967
|
+
ARG_TYPES: ::Array[Symbol]
|
968
|
+
|
969
|
+
RETURN_TYPE: Symbol
|
970
|
+
|
971
|
+
def call: (JSONPathNodeList node_list) -> untyped
|
972
|
+
end
|
973
|
+
end
|
974
|
+
|
975
|
+
module JSONP3
|
976
|
+
# The standard `length` function.
|
977
|
+
class Length < FunctionExtension
|
978
|
+
ARG_TYPES: ::Array[Symbol]
|
979
|
+
|
980
|
+
RETURN_TYPE: Symbol
|
981
|
+
|
982
|
+
def call: (untyped obj) -> (:nothing | untyped)
|
983
|
+
end
|
984
|
+
end
|
985
|
+
|
986
|
+
module JSONP3
|
987
|
+
# The standard `match` function.
|
988
|
+
class Match < FunctionExtension
|
989
|
+
@cache_size: Integer
|
990
|
+
|
991
|
+
@raise_errors: (true | false)
|
992
|
+
|
993
|
+
@cache: LRUCache
|
994
|
+
|
995
|
+
ARG_TYPES: ::Array[Symbol]
|
996
|
+
|
997
|
+
RETURN_TYPE: Symbol
|
998
|
+
|
999
|
+
# @param cache_size [Integer] the maximum size of the regexp cache. Set it to
|
1000
|
+
# zero or negative to disable the cache.
|
1001
|
+
# @param raise_errors [bool] if _false_ (the default), return _false_ when this
|
1002
|
+
# function causes a RegexpError instead of raising the exception.
|
1003
|
+
def initialize: (?::Integer cache_size, ?raise_errors: bool) -> void
|
1004
|
+
|
1005
|
+
# @param value [String]
|
1006
|
+
# @param pattern [String]
|
1007
|
+
# @return bool
|
1008
|
+
def call: (untyped value, untyped pattern) -> untyped
|
1009
|
+
|
1010
|
+
private
|
1011
|
+
|
1012
|
+
def full_match: (String pattern) -> String
|
1013
|
+
end
|
1014
|
+
end
|
1015
|
+
|
1016
|
+
module JSONP3
|
1017
|
+
# Map I-Regexp pattern to Ruby regex pattern.
|
1018
|
+
# @param pattern [String]
|
1019
|
+
# @return [String]
|
1020
|
+
def self.map_iregexp: (String pattern) -> String
|
1021
|
+
end
|
1022
|
+
|
1023
|
+
module JSONP3
|
1024
|
+
# The standard `search` function.
|
1025
|
+
class Search < FunctionExtension
|
1026
|
+
@cache_size: Integer
|
1027
|
+
|
1028
|
+
@raise_errors: (true | false)
|
1029
|
+
|
1030
|
+
@cache: LRUCache
|
1031
|
+
|
1032
|
+
ARG_TYPES: ::Array[Symbol]
|
1033
|
+
|
1034
|
+
RETURN_TYPE: Symbol
|
1035
|
+
|
1036
|
+
# @param cache_size [Integer] the maximum size of the regexp cache. Set it to
|
1037
|
+
# zero or negative to disable the cache.
|
1038
|
+
# @param raise_errors [bool] if _false_ (the default), return _false_ when this
|
1039
|
+
# function causes a RegexpError instead of raising the exception.
|
1040
|
+
def initialize: (?::Integer cache_size, ?raise_errors: bool) -> void
|
1041
|
+
|
1042
|
+
# @param value [String]
|
1043
|
+
# @param pattern [String]
|
1044
|
+
# @return bool
|
1045
|
+
def call: (untyped value, untyped pattern) -> untyped
|
1046
|
+
end
|
1047
|
+
end
|
1048
|
+
|
1049
|
+
module JSONP3
|
1050
|
+
# The standard `value` function.
|
1051
|
+
class Value < FunctionExtension
|
1052
|
+
ARG_TYPES: ::Array[Symbol]
|
1053
|
+
|
1054
|
+
RETURN_TYPE: Symbol
|
1055
|
+
|
1056
|
+
def call: (JSONPathNodeList node_list) -> (untyped | :nothing)
|
1057
|
+
end
|
1058
|
+
end
|