dhall 0.3.0 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/bin/dhall-compile +38 -4
- data/bin/json-to-dhall +1 -1
- data/bin/yaml-to-dhall +1 -1
- data/dhall.gemspec +4 -0
- data/lib/dhall/as_dhall.rb +6 -0
- data/lib/dhall/ast.rb +291 -116
- data/lib/dhall/binary.rb +92 -17
- data/lib/dhall/builtins.rb +179 -238
- data/lib/dhall/coder.rb +6 -1
- data/lib/dhall/normalize.rb +59 -31
- data/lib/dhall/parser.citrus +73 -43
- data/lib/dhall/parser.rb +136 -103
- data/lib/dhall/resolve.rb +42 -32
- data/lib/dhall/typecheck.rb +171 -34
- data/lib/dhall/types.rb +19 -0
- data/lib/dhall/util.rb +49 -0
- data/lib/dhall.rb +1 -0
- metadata +60 -4
- data/lib/dhall/visitor.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c6ba874fec536af3a57ea4a0ca59f040076ebc03ed639dcd44a5a2b79e8bf252
|
4
|
+
data.tar.gz: 4408343df3c63a8c96f6e191f3109a2110ae4b6f3ab06aee58c15b2e7439f6ef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3fdb1ed15e039261aedfc608d612eb4739b7a0204aa26524d66e8999d14ed71cc4e2b5964077f88cf860a99454548c7c2aae2188de9a9687fb173e780441fe4
|
7
|
+
data.tar.gz: 0b9b101c0ccaec5d6be7bbfab0a3698c1eb81f91c06ba9efe663391ce56e8e71613fb0f4cd37af12cc68e7973278fcd9f47190d80a0369c14230a3e0480cdda1
|
data/bin/dhall-compile
CHANGED
@@ -13,19 +13,43 @@ def compile(source)
|
|
13
13
|
resolver: Dhall::Resolvers::Default.new(
|
14
14
|
max_depth: Float::INFINITY
|
15
15
|
)
|
16
|
-
)
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
module FilenameWriter
|
20
|
+
def self.write(_, out, dhall)
|
21
|
+
warn out
|
22
|
+
out.dirname.mkpath
|
23
|
+
out.write(dhall.to_binary)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module CacheWriter
|
28
|
+
def self.write(output_directory, out, dhall)
|
29
|
+
base = "1220#{dhall.digest.hexdigest}"
|
30
|
+
out = out.dirname + base
|
31
|
+
if output_directory
|
32
|
+
out = output_directory + base
|
33
|
+
out.dirname.mkpath
|
34
|
+
end
|
35
|
+
warn out
|
36
|
+
out.write(dhall.to_cbor)
|
37
|
+
end
|
17
38
|
end
|
18
39
|
|
19
40
|
def compile_file(file_path, relative_to: Pathname.new("."))
|
41
|
+
$stderr.print "#{file_path} => "
|
20
42
|
out = file_path.sub_ext(@extension)
|
21
43
|
if @output_directory
|
22
44
|
out = @output_directory + out.relative_path_from(relative_to)
|
23
|
-
out.dirname.mkpath
|
24
45
|
end
|
25
|
-
|
26
|
-
|
46
|
+
compile(file_path.expand_path).then do |dhall|
|
47
|
+
@writer.write(@output_directory, out, dhall)
|
48
|
+
end
|
27
49
|
end
|
28
50
|
|
51
|
+
@writer = FilenameWriter
|
52
|
+
# rubocop:disable Metrics/BlockLength
|
29
53
|
opt_parser = OptionParser.new do |opts|
|
30
54
|
opts.banner = "Usage: dhall-compile [options] [-] [files_and_dirs]"
|
31
55
|
|
@@ -45,11 +69,21 @@ opt_parser = OptionParser.new do |opts|
|
|
45
69
|
@extension = ext ? ".#{ext}" : ""
|
46
70
|
end
|
47
71
|
|
72
|
+
opts.on(
|
73
|
+
"-c",
|
74
|
+
"--cache",
|
75
|
+
"Write output in standard dhall file cache format"
|
76
|
+
) do
|
77
|
+
@extension = ""
|
78
|
+
@writer = CacheWriter
|
79
|
+
end
|
80
|
+
|
48
81
|
opts.on("-h", "--help", "Show this usage information") do
|
49
82
|
warn opts
|
50
83
|
exit
|
51
84
|
end
|
52
85
|
end
|
86
|
+
# rubocop:enable Metrics/BlockLength
|
53
87
|
|
54
88
|
opt_parser.parse!
|
55
89
|
|
data/bin/json-to-dhall
CHANGED
data/bin/yaml-to-dhall
CHANGED
data/dhall.gemspec
CHANGED
@@ -25,12 +25,16 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
|
26
26
|
spec.require_paths = ["lib"]
|
27
27
|
|
28
|
+
spec.add_dependency "base32", "~> 0.3.2"
|
28
29
|
spec.add_dependency "cbor", "~> 0.5.9.3"
|
29
30
|
spec.add_dependency "citrus", "~> 3.0"
|
31
|
+
spec.add_dependency "lazy_object", "~> 0.0.3"
|
32
|
+
spec.add_dependency "multihashes", "~> 0.2.0"
|
30
33
|
spec.add_dependency "promise.rb", "~> 0.7.4"
|
31
34
|
spec.add_dependency "value_semantics", "~> 3.0"
|
32
35
|
|
33
36
|
spec.add_development_dependency "abnf", "~> 0.0.1"
|
37
|
+
spec.add_development_dependency "minitest-fail-fast", "~> 0.1.0"
|
34
38
|
spec.add_development_dependency "simplecov", "~> 0.16.1"
|
35
39
|
spec.add_development_dependency "webmock", "~> 3.5"
|
36
40
|
end
|
data/lib/dhall/as_dhall.rb
CHANGED
data/lib/dhall/ast.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "base32"
|
4
|
+
require "lazy_object"
|
5
|
+
require "multihashes"
|
3
6
|
require "uri"
|
4
7
|
require "value_semantics"
|
5
8
|
|
@@ -33,8 +36,7 @@ module Dhall
|
|
33
36
|
end
|
34
37
|
|
35
38
|
def *(other)
|
36
|
-
|
37
|
-
when Natural
|
39
|
+
if other.is_a?(Natural) && other.zero?
|
38
40
|
other * self
|
39
41
|
else
|
40
42
|
Operator::Times.new(lhs: self, rhs: other)
|
@@ -68,7 +70,7 @@ module Dhall
|
|
68
70
|
def dhall_eq(other)
|
69
71
|
if self == other
|
70
72
|
Bool.new(value: true)
|
71
|
-
elsif other.
|
73
|
+
elsif other == Bool.new(value: true)
|
72
74
|
other.dhall_eq(self)
|
73
75
|
else
|
74
76
|
Operator::Equal.new(lhs: self, rhs: other)
|
@@ -102,6 +104,10 @@ module Dhall
|
|
102
104
|
end
|
103
105
|
end
|
104
106
|
|
107
|
+
def annotate(type)
|
108
|
+
TypeAnnotation.new(value: self, type: type)
|
109
|
+
end
|
110
|
+
|
105
111
|
def to_s
|
106
112
|
inspect
|
107
113
|
end
|
@@ -128,7 +134,7 @@ module Dhall
|
|
128
134
|
def flatten
|
129
135
|
f, args = if function.is_a?(Application)
|
130
136
|
function.flatten
|
131
|
-
elsif function.is_a?(
|
137
|
+
elsif function.is_a?(BuiltinFunction) &&
|
132
138
|
(unfilled = function.unfill).is_a?(Application)
|
133
139
|
unfilled.flatten
|
134
140
|
else
|
@@ -216,7 +222,29 @@ module Dhall
|
|
216
222
|
end
|
217
223
|
end
|
218
224
|
|
219
|
-
class
|
225
|
+
class RubyObjectRaw < Expression
|
226
|
+
def initialize(object)
|
227
|
+
@object = object
|
228
|
+
end
|
229
|
+
|
230
|
+
def unwrap
|
231
|
+
@object
|
232
|
+
end
|
233
|
+
|
234
|
+
def respond_to_missing?(m)
|
235
|
+
super || @object.respond_to?(m)
|
236
|
+
end
|
237
|
+
|
238
|
+
def method_missing(m, *args, &block)
|
239
|
+
if @object.respond_to?(m)
|
240
|
+
@object.public_send(m, *args, &block)
|
241
|
+
else
|
242
|
+
super
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
class FunctionProxyRaw < Function
|
220
248
|
def initialize(callable, curry: true)
|
221
249
|
@callable = if !curry
|
222
250
|
callable
|
@@ -230,7 +258,7 @@ module Dhall
|
|
230
258
|
end
|
231
259
|
|
232
260
|
def call(*args, &block)
|
233
|
-
@callable.call(*args.map { |arg| arg&.as_dhall }, &block)
|
261
|
+
RubyObjectRaw.new(@callable.call(*args.map { |arg| arg&.as_dhall }, &block))
|
234
262
|
end
|
235
263
|
|
236
264
|
def as_json
|
@@ -238,6 +266,12 @@ module Dhall
|
|
238
266
|
end
|
239
267
|
end
|
240
268
|
|
269
|
+
class FunctionProxy < FunctionProxyRaw
|
270
|
+
def call(*args, &block)
|
271
|
+
super.unwrap.as_dhall
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
241
275
|
class Bool < Expression
|
242
276
|
include(ValueSemantics.for_attributes do
|
243
277
|
value Bool()
|
@@ -317,6 +351,33 @@ module Dhall
|
|
317
351
|
[3, OPERATORS.index(self.class), lhs.as_json, rhs.as_json]
|
318
352
|
end
|
319
353
|
|
354
|
+
module FetchFromMerge
|
355
|
+
def fetch_second_record(first, second, selector)
|
356
|
+
rec = self.class.new(
|
357
|
+
self.class::FETCH2K => second.slice(selector),
|
358
|
+
self.class::FETCH1K => first
|
359
|
+
).normalize
|
360
|
+
|
361
|
+
if rec.class == self.class
|
362
|
+
RecordSelection.new(record: rec, selector: selector)
|
363
|
+
else
|
364
|
+
rec.fetch(selector)
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
def fetch(selector)
|
369
|
+
first = public_send(self.class::FETCH1K)
|
370
|
+
second = public_send(self.class::FETCH2K)
|
371
|
+
if first.is_a?(Record)
|
372
|
+
first.fetch(selector) { second.fetch(selector) }
|
373
|
+
elsif second.is_a?(Record)
|
374
|
+
fetch_second_record(first, second, selector)
|
375
|
+
else
|
376
|
+
super
|
377
|
+
end
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
320
381
|
class Or < Operator; end
|
321
382
|
class And < Operator; end
|
322
383
|
class Equal < Operator; end
|
@@ -325,17 +386,27 @@ module Dhall
|
|
325
386
|
class Times < Operator; end
|
326
387
|
class TextConcatenate < Operator; end
|
327
388
|
class ListConcatenate < Operator; end
|
328
|
-
class RecursiveRecordMerge < Operator
|
329
|
-
|
389
|
+
class RecursiveRecordMerge < Operator
|
390
|
+
FETCH1K = :lhs
|
391
|
+
FETCH2K = :rhs
|
392
|
+
include FetchFromMerge
|
393
|
+
end
|
394
|
+
class RightBiasedRecordMerge < Operator
|
395
|
+
FETCH1K = :rhs
|
396
|
+
FETCH2K = :lhs
|
397
|
+
include FetchFromMerge
|
398
|
+
end
|
330
399
|
class RecursiveRecordTypeMerge < Operator; end
|
331
400
|
class ImportFallback < Operator; end
|
401
|
+
class Equivalent < Operator; end
|
332
402
|
|
333
403
|
OPERATORS = [
|
334
404
|
Or, And, Equal, NotEqual,
|
335
405
|
Plus, Times,
|
336
406
|
TextConcatenate, ListConcatenate,
|
337
407
|
RecursiveRecordMerge, RightBiasedRecordMerge, RecursiveRecordTypeMerge,
|
338
|
-
ImportFallback
|
408
|
+
ImportFallback,
|
409
|
+
Equivalent
|
339
410
|
].freeze
|
340
411
|
end
|
341
412
|
|
@@ -344,9 +415,18 @@ module Dhall
|
|
344
415
|
|
345
416
|
include(ValueSemantics.for_attributes do
|
346
417
|
elements Util::ArrayOf.new(Expression, min: 1)
|
347
|
-
|
418
|
+
type Either(nil, Expression), default: nil
|
348
419
|
end)
|
349
420
|
|
421
|
+
def initialize(attrs)
|
422
|
+
if attrs.key?(:element_type)
|
423
|
+
et = attrs.delete(:element_type)
|
424
|
+
attrs[:type] = self.class.as_dhall.call(et) if et
|
425
|
+
end
|
426
|
+
|
427
|
+
super
|
428
|
+
end
|
429
|
+
|
350
430
|
def self.of(*args, type: nil)
|
351
431
|
if args.empty?
|
352
432
|
EmptyList.new(element_type: type)
|
@@ -359,11 +439,13 @@ module Dhall
|
|
359
439
|
Builtins[:List]
|
360
440
|
end
|
361
441
|
|
362
|
-
def
|
363
|
-
|
364
|
-
|
365
|
-
argument
|
366
|
-
|
442
|
+
def element_type
|
443
|
+
if type.nil?
|
444
|
+
elsif type.is_a?(Application) && type.function == Builtins[:List]
|
445
|
+
type.argument
|
446
|
+
else
|
447
|
+
raise "Cannot get element_type of: #{type.inspect}"
|
448
|
+
end
|
367
449
|
end
|
368
450
|
|
369
451
|
def as_json
|
@@ -371,9 +453,10 @@ module Dhall
|
|
371
453
|
end
|
372
454
|
|
373
455
|
def map(type: nil, &block)
|
456
|
+
type = type.nil? ? nil : Builtins[:List].call(type.as_dhall)
|
374
457
|
with(
|
375
|
-
elements:
|
376
|
-
|
458
|
+
elements: elements.each_with_index.map(&block),
|
459
|
+
type: type
|
377
460
|
)
|
378
461
|
end
|
379
462
|
|
@@ -421,11 +504,22 @@ module Dhall
|
|
421
504
|
|
422
505
|
class EmptyList < List
|
423
506
|
include(ValueSemantics.for_attributes do
|
424
|
-
|
507
|
+
type Either(nil, Expression)
|
425
508
|
end)
|
426
509
|
|
510
|
+
def initialize(attrs)
|
511
|
+
if attrs.key?(:element_type)
|
512
|
+
et = attrs.delete(:element_type)
|
513
|
+
attrs[:type] = self.class.as_dhall.call(et) if et
|
514
|
+
end
|
515
|
+
|
516
|
+
super
|
517
|
+
end
|
518
|
+
|
427
519
|
def as_json
|
428
520
|
[4, element_type.as_json]
|
521
|
+
rescue
|
522
|
+
[28, type.as_json]
|
429
523
|
end
|
430
524
|
|
431
525
|
def map(type: nil)
|
@@ -460,6 +554,10 @@ module Dhall
|
|
460
554
|
self
|
461
555
|
end
|
462
556
|
|
557
|
+
def join(*)
|
558
|
+
""
|
559
|
+
end
|
560
|
+
|
463
561
|
def concat(other)
|
464
562
|
other
|
465
563
|
end
|
@@ -547,7 +645,7 @@ module Dhall
|
|
547
645
|
include(ValueSemantics.for_attributes do
|
548
646
|
record Expression
|
549
647
|
input Expression
|
550
|
-
type Either(Expression, nil)
|
648
|
+
type Either(Expression, nil), default: nil
|
551
649
|
end)
|
552
650
|
|
553
651
|
def as_json
|
@@ -556,6 +654,18 @@ module Dhall
|
|
556
654
|
end
|
557
655
|
end
|
558
656
|
|
657
|
+
class ToMap < Expression
|
658
|
+
include(ValueSemantics.for_attributes do
|
659
|
+
record Expression
|
660
|
+
type Either(Expression, nil), default: nil
|
661
|
+
end)
|
662
|
+
|
663
|
+
def as_json
|
664
|
+
[27, record.as_json] +
|
665
|
+
(type.nil? ? [] : [type.as_json])
|
666
|
+
end
|
667
|
+
end
|
668
|
+
|
559
669
|
class RecordType < Expression
|
560
670
|
include(ValueSemantics.for_attributes do
|
561
671
|
record Util::HashOf.new(::String, Expression, min: 1)
|
@@ -793,11 +903,38 @@ module Dhall
|
|
793
903
|
selectors Util::ArrayOf.new(::String, min: 1)
|
794
904
|
end)
|
795
905
|
|
906
|
+
def self.for(record, selectors)
|
907
|
+
if selectors.empty?
|
908
|
+
EmptyRecordProjection.new(record: record)
|
909
|
+
else
|
910
|
+
new(record: record, selectors: selectors)
|
911
|
+
end
|
912
|
+
end
|
913
|
+
|
914
|
+
def fetch(selector)
|
915
|
+
record.fetch(selector)
|
916
|
+
end
|
917
|
+
|
796
918
|
def as_json
|
797
919
|
[10, record.as_json, *selectors]
|
798
920
|
end
|
799
921
|
end
|
800
922
|
|
923
|
+
class RecordProjectionByExpression < Expression
|
924
|
+
include(ValueSemantics.for_attributes do
|
925
|
+
record Expression
|
926
|
+
selector Expression
|
927
|
+
end)
|
928
|
+
|
929
|
+
def fetch(selector)
|
930
|
+
record.fetch(selector)
|
931
|
+
end
|
932
|
+
|
933
|
+
def as_json
|
934
|
+
[10, record.as_json, [selector.as_json]]
|
935
|
+
end
|
936
|
+
end
|
937
|
+
|
801
938
|
class EmptyRecordProjection < Expression
|
802
939
|
include(ValueSemantics.for_attributes do
|
803
940
|
record Expression
|
@@ -968,8 +1105,8 @@ module Dhall
|
|
968
1105
|
class If < Expression
|
969
1106
|
include(ValueSemantics.for_attributes do
|
970
1107
|
predicate Expression
|
971
|
-
|
972
|
-
|
1108
|
+
def_attr :then, Expression
|
1109
|
+
def_attr :else, Expression
|
973
1110
|
end)
|
974
1111
|
|
975
1112
|
def as_json
|
@@ -1189,91 +1326,92 @@ module Dhall
|
|
1189
1326
|
class Import < Expression
|
1190
1327
|
class IntegrityCheck
|
1191
1328
|
include(ValueSemantics.for_attributes do
|
1192
|
-
|
1193
|
-
|
1329
|
+
code ::Integer
|
1330
|
+
digest ::String
|
1194
1331
|
end)
|
1195
1332
|
|
1196
1333
|
class FailureException < StandardError; end
|
1197
1334
|
|
1198
|
-
def
|
1199
|
-
|
1200
|
-
protocol: protocol,
|
1201
|
-
data: data
|
1202
|
-
)
|
1335
|
+
def to_s
|
1336
|
+
"#{Multihashes::TABLE[code].sub(/\Asha2-/, "sha")}:#{hexdigest}"
|
1203
1337
|
end
|
1204
1338
|
|
1205
|
-
def
|
1206
|
-
"
|
1339
|
+
def hexdigest
|
1340
|
+
digest.unpack("H*").first.encode(Encoding::UTF_8)
|
1207
1341
|
end
|
1208
1342
|
|
1209
|
-
def
|
1210
|
-
|
1343
|
+
def ipfs
|
1344
|
+
"/ipfs/b#{Base32.encode("\x01\x55" + as_json).downcase.sub(/=*$/, "")}"
|
1345
|
+
end
|
1211
1346
|
|
1347
|
+
def check(expr)
|
1212
1348
|
expr = expr.normalize
|
1213
1349
|
return expr if expr.cache_key == to_s
|
1214
1350
|
|
1215
|
-
raise FailureException, "#{expr}
|
1351
|
+
raise FailureException, "#{expr} hash #{expr.cache_key}" \
|
1352
|
+
" does not match #{self}"
|
1216
1353
|
end
|
1217
1354
|
|
1218
1355
|
def as_json
|
1219
|
-
|
1356
|
+
Multihashes.encode(digest, Multihashes::TABLE[code])
|
1220
1357
|
end
|
1221
1358
|
end
|
1222
1359
|
|
1223
|
-
class
|
1224
|
-
|
1225
|
-
headers Either(nil, Expression)
|
1226
|
-
authority ::String
|
1227
|
-
path ArrayOf(::String)
|
1228
|
-
query Either(nil, ::String)
|
1229
|
-
end)
|
1360
|
+
class NoIntegrityCheck < IntegrityCheck
|
1361
|
+
def initialize; end
|
1230
1362
|
|
1231
|
-
def
|
1232
|
-
|
1233
|
-
headers: headers,
|
1234
|
-
authority: authority,
|
1235
|
-
path: path,
|
1236
|
-
query: query,
|
1237
|
-
)
|
1363
|
+
def to_s
|
1364
|
+
""
|
1238
1365
|
end
|
1239
1366
|
|
1240
|
-
def
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
*hash.fetch(:path, path),
|
1245
|
-
hash.fetch(:query, query)
|
1246
|
-
)
|
1367
|
+
def hexdigest; end
|
1368
|
+
|
1369
|
+
def check(expr)
|
1370
|
+
expr.normalize
|
1247
1371
|
end
|
1248
1372
|
|
1249
|
-
def
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1373
|
+
def as_json
|
1374
|
+
nil
|
1375
|
+
end
|
1376
|
+
end
|
1377
|
+
|
1378
|
+
Location = LazyObject.new do
|
1379
|
+
UnionType.new(
|
1380
|
+
alternatives: {
|
1381
|
+
"Local" => Builtins[:Text],
|
1382
|
+
"Remote" => Builtins[:Text],
|
1383
|
+
"Environment" => Builtins[:Text],
|
1384
|
+
"Missing" => nil
|
1385
|
+
}
|
1386
|
+
)
|
1387
|
+
end
|
1388
|
+
|
1389
|
+
class URI
|
1390
|
+
include(ValueSemantics.for_attributes do
|
1391
|
+
uri ::URI
|
1392
|
+
headers Either(nil, Expression), default: nil
|
1393
|
+
end)
|
1394
|
+
|
1395
|
+
def with(attrs)
|
1396
|
+
if attrs.key?(:path)
|
1397
|
+
attrs[:uri] =
|
1398
|
+
uri + Util.path_components_to_uri(*attrs.delete(:path))
|
1399
|
+
end
|
1400
|
+
|
1401
|
+
super
|
1257
1402
|
end
|
1258
1403
|
|
1259
1404
|
def headers
|
1260
1405
|
header_type = RecordType.new(
|
1261
1406
|
record: {
|
1262
|
-
"
|
1263
|
-
"
|
1407
|
+
"mapKey" => Builtins[:Text],
|
1408
|
+
"mapValue" => Builtins[:Text]
|
1264
1409
|
}
|
1265
1410
|
)
|
1266
1411
|
|
1267
1412
|
super || EmptyList.new(element_type: header_type)
|
1268
1413
|
end
|
1269
1414
|
|
1270
|
-
def uri
|
1271
|
-
escaped_path = path.map do |c|
|
1272
|
-
::URI.encode_www_form_component(c).gsub("+", "%20")
|
1273
|
-
end
|
1274
|
-
URI("#{scheme}://#{authority}/#{escaped_path.join("/")}?#{query}")
|
1275
|
-
end
|
1276
|
-
|
1277
1415
|
def chain_onto(relative_to)
|
1278
1416
|
if headers.is_a?(Import)
|
1279
1417
|
with(headers: headers.with(path: headers.real_path(relative_to)))
|
@@ -1284,23 +1422,43 @@ module Dhall
|
|
1284
1422
|
|
1285
1423
|
def canonical
|
1286
1424
|
with(
|
1287
|
-
path: (path[1..-1] + [""])
|
1288
|
-
.reduce([[], path.first]) { |(pth, prev), c|
|
1425
|
+
path: (path[1..-1] + [""]).reduce([[], path.first]) { |(pth, prev), c|
|
1289
1426
|
c == ".." ? [pth, prev] : [pth + [prev], c]
|
1290
1427
|
}.first.reject { |c| c == "." }
|
1291
1428
|
)
|
1292
1429
|
end
|
1293
1430
|
|
1431
|
+
def port
|
1432
|
+
uri.port && uri.port != uri.default_port ? uri.port : nil
|
1433
|
+
end
|
1434
|
+
|
1435
|
+
def authority
|
1436
|
+
[
|
1437
|
+
uri.userinfo,
|
1438
|
+
[uri.host, port].compact.join(":")
|
1439
|
+
].compact.join("@")
|
1440
|
+
end
|
1441
|
+
|
1294
1442
|
def origin
|
1295
|
-
"#{scheme}://#{authority}"
|
1443
|
+
"#{uri.scheme}://#{authority}"
|
1296
1444
|
end
|
1297
1445
|
|
1298
1446
|
def to_s
|
1299
1447
|
uri.to_s
|
1300
1448
|
end
|
1301
1449
|
|
1450
|
+
def location
|
1451
|
+
Union.from(Location, "Remote", to_s.as_dhall)
|
1452
|
+
end
|
1453
|
+
|
1454
|
+
def path
|
1455
|
+
path = uri.path.split(/\//, -1)
|
1456
|
+
path = path[1..-1] if path.length > 1 && path.first.empty?
|
1457
|
+
path
|
1458
|
+
end
|
1459
|
+
|
1302
1460
|
def as_json
|
1303
|
-
[@headers&.as_json, authority, *path, query]
|
1461
|
+
[@headers&.as_json, authority, *path, uri.query]
|
1304
1462
|
end
|
1305
1463
|
end
|
1306
1464
|
|
@@ -1308,20 +1466,12 @@ module Dhall
|
|
1308
1466
|
def resolve(resolver)
|
1309
1467
|
resolver.resolve_http(self)
|
1310
1468
|
end
|
1311
|
-
|
1312
|
-
def scheme
|
1313
|
-
"http"
|
1314
|
-
end
|
1315
1469
|
end
|
1316
1470
|
|
1317
1471
|
class Https < URI
|
1318
1472
|
def resolve(resolver)
|
1319
1473
|
resolver.resolve_https(self)
|
1320
1474
|
end
|
1321
|
-
|
1322
|
-
def scheme
|
1323
|
-
"https"
|
1324
|
-
end
|
1325
1475
|
end
|
1326
1476
|
|
1327
1477
|
class Path
|
@@ -1366,6 +1516,10 @@ module Dhall
|
|
1366
1516
|
pathname.to_s
|
1367
1517
|
end
|
1368
1518
|
|
1519
|
+
def location
|
1520
|
+
Union.from(Location, "Local", to_s.as_dhall)
|
1521
|
+
end
|
1522
|
+
|
1369
1523
|
def as_json
|
1370
1524
|
path
|
1371
1525
|
end
|
@@ -1376,8 +1530,8 @@ module Dhall
|
|
1376
1530
|
Pathname.new("/").join(*path)
|
1377
1531
|
end
|
1378
1532
|
|
1379
|
-
def to_uri(scheme,
|
1380
|
-
scheme.new(
|
1533
|
+
def to_uri(scheme, base_uri)
|
1534
|
+
scheme.new(uri: base_uri + Util.path_components_to_uri(*path))
|
1381
1535
|
end
|
1382
1536
|
|
1383
1537
|
def chain_onto(relative_to)
|
@@ -1394,6 +1548,10 @@ module Dhall
|
|
1394
1548
|
Pathname.new(".").join(*path)
|
1395
1549
|
end
|
1396
1550
|
|
1551
|
+
def to_s
|
1552
|
+
"./#{pathname}"
|
1553
|
+
end
|
1554
|
+
|
1397
1555
|
def chain_onto(relative_to)
|
1398
1556
|
relative_to.with(
|
1399
1557
|
path: relative_to.path[0..-2] + path
|
@@ -1473,6 +1631,10 @@ module Dhall
|
|
1473
1631
|
end}"
|
1474
1632
|
end
|
1475
1633
|
|
1634
|
+
def location
|
1635
|
+
Union.from(Location, "Environment", to_s.as_dhall)
|
1636
|
+
end
|
1637
|
+
|
1476
1638
|
def hash
|
1477
1639
|
@var.hash
|
1478
1640
|
end
|
@@ -1480,7 +1642,7 @@ module Dhall
|
|
1480
1642
|
def eql?(other)
|
1481
1643
|
other.is_a?(self.class) && other.var == var
|
1482
1644
|
end
|
1483
|
-
alias eql?
|
1645
|
+
alias == eql?
|
1484
1646
|
|
1485
1647
|
def as_json
|
1486
1648
|
@var
|
@@ -1506,6 +1668,15 @@ module Dhall
|
|
1506
1668
|
"missing"
|
1507
1669
|
end
|
1508
1670
|
|
1671
|
+
def location
|
1672
|
+
Union.from(Location, "Missing", nil)
|
1673
|
+
end
|
1674
|
+
|
1675
|
+
def eql?(other)
|
1676
|
+
other.class == self.class
|
1677
|
+
end
|
1678
|
+
alias == eql?
|
1679
|
+
|
1509
1680
|
def as_json
|
1510
1681
|
[]
|
1511
1682
|
end
|
@@ -1525,9 +1696,16 @@ module Dhall
|
|
1525
1696
|
end
|
1526
1697
|
end
|
1527
1698
|
|
1699
|
+
class AsLocation
|
1700
|
+
def self.call(*)
|
1701
|
+
raise "AsLocation is only a marker, you don't actually call it"
|
1702
|
+
end
|
1703
|
+
end
|
1704
|
+
|
1528
1705
|
IMPORT_TYPES = [
|
1529
1706
|
Expression,
|
1530
|
-
Text
|
1707
|
+
Text,
|
1708
|
+
AsLocation
|
1531
1709
|
].freeze
|
1532
1710
|
|
1533
1711
|
PATH_TYPES = [
|
@@ -1537,14 +1715,14 @@ module Dhall
|
|
1537
1715
|
].freeze
|
1538
1716
|
|
1539
1717
|
include(ValueSemantics.for_attributes do
|
1540
|
-
integrity_check IntegrityCheck, default:
|
1718
|
+
integrity_check IntegrityCheck, default: NoIntegrityCheck.new
|
1541
1719
|
import_type Class
|
1542
1720
|
path Either(*PATH_TYPES)
|
1543
1721
|
end)
|
1544
1722
|
|
1545
1723
|
def initialize(integrity_check, import_type, path)
|
1546
1724
|
super(
|
1547
|
-
integrity_check: integrity_check ||
|
1725
|
+
integrity_check: integrity_check || NoIntegrityCheck.new,
|
1548
1726
|
import_type: import_type,
|
1549
1727
|
path: path
|
1550
1728
|
)
|
@@ -1562,15 +1740,18 @@ module Dhall
|
|
1562
1740
|
path.chain_onto(relative_to).canonical
|
1563
1741
|
end
|
1564
1742
|
|
1565
|
-
def
|
1566
|
-
|
1743
|
+
def parse_resolve_check(raw, deadline: Util::NoDeadline.new, **kwargs)
|
1744
|
+
import_type.call(raw, deadline: deadline).resolve(**kwargs).then do |e|
|
1745
|
+
integrity_check.check(TypeChecker.annotate(e))
|
1746
|
+
end
|
1567
1747
|
end
|
1568
1748
|
|
1569
1749
|
def cache_key(relative_to)
|
1570
|
-
|
1750
|
+
key = integrity_check.to_s
|
1751
|
+
if key.empty?
|
1571
1752
|
real_path(relative_to)
|
1572
1753
|
else
|
1573
|
-
|
1754
|
+
key
|
1574
1755
|
end
|
1575
1756
|
end
|
1576
1757
|
|
@@ -1609,10 +1790,10 @@ module Dhall
|
|
1609
1790
|
|
1610
1791
|
def flatten
|
1611
1792
|
flattened = body.is_a?(LetIn) ? body.flatten : body
|
1612
|
-
if flattened.is_a?(
|
1613
|
-
LetBlock.
|
1793
|
+
if flattened.is_a?(LetBlock)
|
1794
|
+
LetBlock.new(lets: lets + flattened.lets, body: flattened.body)
|
1614
1795
|
else
|
1615
|
-
|
1796
|
+
LetBlock.new(lets: lets, body: body)
|
1616
1797
|
end
|
1617
1798
|
end
|
1618
1799
|
|
@@ -1635,28 +1816,16 @@ module Dhall
|
|
1635
1816
|
end
|
1636
1817
|
|
1637
1818
|
def as_json
|
1638
|
-
|
1819
|
+
flatten.as_json
|
1639
1820
|
end
|
1640
1821
|
end
|
1641
1822
|
|
1642
|
-
class LetBlock
|
1823
|
+
class LetBlock
|
1643
1824
|
include(ValueSemantics.for_attributes do
|
1644
|
-
lets Util::ArrayOf.new(Let
|
1825
|
+
lets Util::ArrayOf.new(Let)
|
1645
1826
|
body Expression
|
1646
1827
|
end)
|
1647
1828
|
|
1648
|
-
def self.for(lets:, body:)
|
1649
|
-
if lets.length == 1
|
1650
|
-
LetIn.new(let: lets.first, body: body)
|
1651
|
-
else
|
1652
|
-
new(lets: lets, body: body)
|
1653
|
-
end
|
1654
|
-
end
|
1655
|
-
|
1656
|
-
def flatten
|
1657
|
-
unflatten.flatten
|
1658
|
-
end
|
1659
|
-
|
1660
1829
|
def unflatten
|
1661
1830
|
lets.reverse.reduce(body) do |inside, let|
|
1662
1831
|
letin = LetIn.new(let: let, body: inside)
|
@@ -1664,10 +1833,6 @@ module Dhall
|
|
1664
1833
|
end
|
1665
1834
|
end
|
1666
1835
|
|
1667
|
-
def desugar
|
1668
|
-
unflatten(&:desugar)
|
1669
|
-
end
|
1670
|
-
|
1671
1836
|
def as_json
|
1672
1837
|
[25, *lets.flat_map(&:as_json), body.as_json]
|
1673
1838
|
end
|
@@ -1683,4 +1848,14 @@ module Dhall
|
|
1683
1848
|
[26, value.as_json, type.as_json]
|
1684
1849
|
end
|
1685
1850
|
end
|
1851
|
+
|
1852
|
+
class Assertion < Expression
|
1853
|
+
include(ValueSemantics.for_attributes do
|
1854
|
+
type Expression
|
1855
|
+
end)
|
1856
|
+
|
1857
|
+
def as_json
|
1858
|
+
[19, type.as_json]
|
1859
|
+
end
|
1860
|
+
end
|
1686
1861
|
end
|