rdl 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +7 -6
- data/CHANGES.md +29 -0
- data/README.md +94 -26
- data/lib/rdl/boot.rb +82 -41
- data/lib/rdl/boot_rails.rb +5 -0
- data/lib/rdl/config.rb +9 -1
- data/lib/rdl/query.rb +2 -2
- data/lib/rdl/typecheck.rb +972 -225
- data/lib/rdl/types/annotated_arg.rb +8 -0
- data/lib/rdl/types/ast_node.rb +73 -0
- data/lib/rdl/types/bot.rb +8 -0
- data/lib/rdl/types/bound_arg.rb +63 -0
- data/lib/rdl/types/computed.rb +48 -0
- data/lib/rdl/types/dependent_arg.rb +9 -0
- data/lib/rdl/types/dynamic.rb +61 -0
- data/lib/rdl/types/finite_hash.rb +54 -9
- data/lib/rdl/types/generic.rb +33 -0
- data/lib/rdl/types/intersection.rb +8 -0
- data/lib/rdl/types/lexer.rex +6 -1
- data/lib/rdl/types/lexer.rex.rb +13 -1
- data/lib/rdl/types/method.rb +14 -0
- data/lib/rdl/types/nominal.rb +8 -0
- data/lib/rdl/types/non_null.rb +8 -0
- data/lib/rdl/types/optional.rb +8 -0
- data/lib/rdl/types/parser.racc +31 -5
- data/lib/rdl/types/parser.tab.rb +540 -302
- data/lib/rdl/types/rdl_types.rb +45 -0
- data/lib/rdl/types/singleton.rb +14 -1
- data/lib/rdl/types/string.rb +104 -0
- data/lib/rdl/types/structural.rb +8 -0
- data/lib/rdl/types/top.rb +8 -0
- data/lib/rdl/types/tuple.rb +32 -8
- data/lib/rdl/types/type.rb +54 -11
- data/lib/rdl/types/union.rb +41 -2
- data/lib/rdl/types/var.rb +10 -0
- data/lib/rdl/types/vararg.rb +8 -0
- data/lib/rdl/util.rb +13 -10
- data/lib/rdl/wrap.rb +271 -27
- data/lib/rdl_disable.rb +16 -2
- data/lib/types/active_record.rb +1 -0
- data/lib/types/core/array.rb +442 -23
- data/lib/types/core/basic_object.rb +3 -3
- data/lib/types/core/bigdecimal.rb +5 -0
- data/lib/types/core/class.rb +2 -0
- data/lib/types/core/dir.rb +3 -3
- data/lib/types/core/enumerable.rb +4 -4
- data/lib/types/core/enumerator.rb +1 -1
- data/lib/types/core/file.rb +4 -4
- data/lib/types/core/float.rb +203 -0
- data/lib/types/core/hash.rb +390 -15
- data/lib/types/core/integer.rb +223 -10
- data/lib/types/core/io.rb +2 -2
- data/lib/types/core/kernel.rb +8 -5
- data/lib/types/core/marshal.rb +3 -0
- data/lib/types/core/module.rb +3 -3
- data/lib/types/core/numeric.rb +0 -2
- data/lib/types/core/object.rb +5 -5
- data/lib/types/core/pathname.rb +2 -2
- data/lib/types/core/process.rb +1 -3
- data/lib/types/core/range.rb +1 -1
- data/lib/types/core/regexp.rb +2 -2
- data/lib/types/core/set.rb +1 -1
- data/lib/types/core/string.rb +408 -16
- data/lib/types/core/symbol.rb +3 -3
- data/lib/types/core/time.rb +1 -1
- data/lib/types/core/uri.rb +13 -13
- data/lib/types/rails/_helpers.rb +7 -1
- data/lib/types/rails/action_controller/mime_responds.rb +2 -0
- data/lib/types/rails/active_record/associations.rb +42 -30
- data/lib/types/rails/active_record/comp_types.rb +637 -0
- data/lib/types/rails/active_record/finder_methods.rb +1 -1
- data/lib/types/rails/active_record/model_schema.rb +28 -16
- data/lib/types/rails/active_record/relation.rb +5 -3
- data/lib/types/rails/active_record/sql-strings.rb +166 -0
- data/lib/types/rails/string.rb +1 -1
- data/lib/types/sequel.rb +1 -0
- data/lib/types/sequel/comp_types.rb +581 -0
- data/rdl.gemspec +5 -4
- data/test/test_alias.rb +4 -0
- data/test/test_array_types.rb +244 -0
- data/test/test_bound_types.rb +80 -0
- data/test/test_contract.rb +4 -0
- data/test/test_dsl.rb +5 -0
- data/test/test_dyn_comptype_checks.rb +206 -0
- data/test/test_generic.rb +21 -20
- data/test/test_hash_types.rb +322 -0
- data/test/test_intersection.rb +1 -0
- data/test/test_le.rb +29 -4
- data/test/test_member.rb +3 -1
- data/test/test_parser.rb +5 -0
- data/test/test_query.rb +1 -0
- data/test/test_rdl.rb +63 -28
- data/test/test_rdl_type.rb +4 -0
- data/test/test_string_types.rb +102 -0
- data/test/test_type_contract.rb +59 -37
- data/test/test_typecheck.rb +480 -75
- data/test/test_types.rb +17 -0
- data/test/test_wrap.rb +5 -0
- metadata +35 -5
- data/lib/types/rails/active_record/schema_types.rb +0 -51
@@ -1,9 +1,9 @@
|
|
1
1
|
RDL.nowrap :BasicObject
|
2
2
|
|
3
|
-
RDL.type :BasicObject, :==, '(%any other) -> %bool'
|
3
|
+
RDL.type :BasicObject, :==, '(%any other) -> %bool', effect: [:+, :+]
|
4
4
|
RDL.type :BasicObject, :equal?, '(%any other) -> %bool'
|
5
|
-
RDL.type :BasicObject, :!, '() -> %bool'
|
6
|
-
RDL.type :BasicObject, :!=, '(%any other) -> %bool'
|
5
|
+
RDL.type :BasicObject, :!, '() -> %bool', effect: [:+, :+]
|
6
|
+
RDL.type :BasicObject, :!=, '(%any other) -> %bool', effect: [:+, :+]
|
7
7
|
RDL.type :BasicObject, :instance_eval, '(String, ?String filename, ?Integer lineno) -> %any'
|
8
8
|
RDL.type :BasicObject, :instance_eval, '() { () -> %any } -> %any'
|
9
9
|
RDL.type :BasicObject, :instance_exec, '(*%any args) { (*%any) -> %any } -> %any'
|
@@ -1,5 +1,10 @@
|
|
1
1
|
RDL.nowrap :BigDecimal
|
2
2
|
|
3
|
+
class BigDecimal < Numeric; end ## Hacky way around existing issue.
|
4
|
+
## The issue is any types that even reference BigDecimal, e.g., Integer#+ etc., will
|
5
|
+
## call const_get on it, but without the above, the class is undefined.
|
6
|
+
## May want to come up with more elegant solution in the future.
|
7
|
+
|
3
8
|
RDL.type :BigDecimal, :%, '(%numeric) -> BigDecimal'
|
4
9
|
RDL.pre(:BigDecimal, :%) { |x| x!=0&&(if x.is_a?(Float) then x!=Float::INFINITY && !x.nan? else true end)}
|
5
10
|
|
data/lib/types/core/class.rb
CHANGED
@@ -13,3 +13,5 @@ RDL.type :Class, :instance_methods, '(?%bool) -> Array<Symbol>'
|
|
13
13
|
RDL.type :Class, :class, '() -> Class'
|
14
14
|
RDL.type :Class, :superclass, '() -> Class'
|
15
15
|
RDL.type :Class, :name, '() -> String'
|
16
|
+
RDL.type :Class, :==, '(%any) -> %bool', effect: [:+, :+]
|
17
|
+
RDL.type :Class, :===, '(%any) -> %bool', effect: [:+, :+]
|
data/lib/types/core/dir.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
RDL.nowrap :Dir
|
2
2
|
|
3
|
-
RDL.rdl_alias :Dir, :[], :glob
|
3
|
+
RDL.rdl_alias :Dir, :'self.[]', :'self.glob'
|
4
4
|
|
5
5
|
RDL.type :Dir, 'self.chdir', '(?(String or Pathname)) -> 0'
|
6
6
|
RDL.type :Dir, 'self.chdir', '(?(String or Pathname)) { (String) -> u } -> u'
|
@@ -12,8 +12,8 @@ RDL.type :Dir, 'self.exist?', '(String file) -> %bool'
|
|
12
12
|
RDL.type :Dir, 'self.foreach', '(String dir, ?Encoding) { (String) -> %any } -> nil'
|
13
13
|
RDL.type :Dir, 'self.foreach', '(String dir, ?Encoding) -> Enumerator<String>'
|
14
14
|
RDL.type :Dir, 'self.getwd', '() -> String'
|
15
|
-
RDL.type :Dir, 'self.glob', '(String or Array<String> pattern, ?
|
16
|
-
RDL.type :Dir, 'self.glob', '(String or Array<String> pattern, ?
|
15
|
+
RDL.type :Dir, 'self.glob', '(String or Array<String> pattern, ?Fixnum flags) -> Array<String>'
|
16
|
+
RDL.type :Dir, 'self.glob', '(String or Array<String> pattern, ?Fixnum flags) { (String) -> %any} -> nil'
|
17
17
|
RDL.type :Dir, 'self.home', '(?String) -> String'
|
18
18
|
RDL.type :Dir, 'self.mkdir', '(String, ?Integer) -> 0'
|
19
19
|
RDL.type :Dir, 'self.open', '(String, ?Encoding) -> Dir'
|
@@ -2,8 +2,8 @@ RDL.nowrap :Enumerable
|
|
2
2
|
|
3
3
|
RDL.type_params :Enumerable, [:t], :all?
|
4
4
|
|
5
|
-
RDL.type :Enumerable, :all?, '() -> %bool'
|
6
|
-
RDL.type :Enumerable, :all?, '() { (t) -> %bool } -> %bool'
|
5
|
+
RDL.type :Enumerable, :all?, '() -> %bool', effect: [:blockdep, :blockdep]
|
6
|
+
RDL.type :Enumerable, :all?, '() { (t) -> %bool } -> %bool', effect: [:blockdep, :blockdep]
|
7
7
|
RDL.type :Enumerable, :any?, '() -> %bool'
|
8
8
|
RDL.type :Enumerable, :any?, '() { (t) -> %bool } -> %bool'
|
9
9
|
# RDL.type :Enumerable, :chunk, '(XXXX : *XXXX)' # TODO
|
@@ -24,8 +24,8 @@ RDL.type :Enumerable, :each_cons, '(Integer n) { (Array<t>) -> %any } -> nil'
|
|
24
24
|
RDL.type :Enumerable, :each_cons, '(Integer n) -> Enumerator<t>'
|
25
25
|
# RDL.type :Enumerable, :each_entry, '(XXXX : *XXXX)' # TODO
|
26
26
|
RDL.rdl_alias :Enumerable, :each_slice, :each_cons
|
27
|
-
RDL.type :Enumerable, :each_with_index, '() { (t, Integer) -> %any } -> Enumerable<t>' # args! note may not return self
|
28
|
-
RDL.type :Enumerable, :each_with_index, '() -> Enumerable<t>' # args! note may not return self
|
27
|
+
RDL.type :Enumerable, :each_with_index, '() { (t, Integer) -> %any } -> Enumerable<t>', effect: [:blockdep, :blockdep] # args! note may not return self
|
28
|
+
RDL.type :Enumerable, :each_with_index, '() -> Enumerable<t>', effect: [:blockdep, :blockdep] # args! note may not return self
|
29
29
|
# RDL.type :Enumerable, :each_with_object, '(XXXX : XXXX)' #TODO
|
30
30
|
RDL.type :Enumerable, :entries, '() -> Array<t>' # TODO args?
|
31
31
|
RDL.rdl_alias :Enumerable, :find, :detect
|
@@ -18,7 +18,7 @@ RDL.type :Enumerator, :next, '() -> t'
|
|
18
18
|
RDL.type :Enumerator, :next_values, '() -> Array<t>'
|
19
19
|
RDL.type :Enumerator, :peek, '() -> t'
|
20
20
|
RDL.type :Enumerator, :peek_values, '() -> Array<t>'
|
21
|
-
RDL.type :Enumerator, :
|
21
|
+
RDL.type :Enumerator, :rewind, '() -> self'
|
22
22
|
RDL.type :Enumerator, :size, '() -> Integer or Float or nil'
|
23
23
|
RDL.rdl_alias :Enumerator, :with_index, :each_with_index
|
24
24
|
RDL.rdl_alias :Enumerator, :with_object, :each_with_object
|
data/lib/types/core/file.rb
CHANGED
@@ -23,7 +23,7 @@ RDL.type :File, 'self.expand_path', '(%path file, ?%path dir) -> String abs_file
|
|
23
23
|
RDL.type :File, 'self.extname', '(String path) -> String'
|
24
24
|
RDL.type :File, 'self.file?', '(String or IO file) -> %bool'
|
25
25
|
RDL.type :File, 'self.fnmatch', '(String pattern, String path, ?Integer flags) -> %bool'
|
26
|
-
RDL.rdl_alias :File, :fnmatch
|
26
|
+
RDL.rdl_alias :File, :'self.fnmatch?', :'self.fnmatch'
|
27
27
|
RDL.type :File, 'self.ftype', '(String file) -> String' # TODO: return in set of strings
|
28
28
|
RDL.type :File, 'self.grpowned?', '(String or IO file) -> %bool'
|
29
29
|
RDL.type :File, 'self.identical?', '(String or IO file_1, String or IO file_2) -> %bool'
|
@@ -41,7 +41,7 @@ RDL.type :File, 'self.pipe?', '(String file) -> %bool'
|
|
41
41
|
RDL.type :File, 'self.readable?', '(String file) -> %bool'
|
42
42
|
RDL.type :File, 'self.readable_real?', '(String file) -> %bool'
|
43
43
|
RDL.type :File, 'self.readlink', '(String link) -> String file'
|
44
|
-
RDL.type :File, 'self.
|
44
|
+
RDL.type :File, 'self.realdirpath', '(String pathname, ?String dir) -> String real_pathname'
|
45
45
|
RDL.type :File, 'self.realpath', '(String pathname, ?String dir) -> String real_pathname'
|
46
46
|
RDL.type :File, 'self.rename', '(String old, String new) -> 0'
|
47
47
|
RDL.type :File, 'self.setgid?', '(String file) -> %bool'
|
@@ -56,7 +56,7 @@ RDL.type :File, 'self.symlink', '(String old, String new) -> 0'
|
|
56
56
|
RDL.type :File, 'self.symlink?', '(String file) -> %bool'
|
57
57
|
RDL.type :File, 'self.truncate', '(String file, Integer) -> 0'
|
58
58
|
RDL.type :File, 'self.umask', '(?Integer) -> Integer'
|
59
|
-
RDL.rdl_alias :File, :unlink, :delete
|
59
|
+
RDL.rdl_alias :File, :'self.unlink', :'self.delete'
|
60
60
|
RDL.type :File, 'self.utime', '(Time atime, Time mtime, *String files) -> Integer'
|
61
61
|
RDL.type :File, 'self.world_readable?', '(String or IO file) -> Integer or nil'
|
62
62
|
RDL.type :File, 'self.world_writable?', '(String or IO file) -> Integer or nil'
|
@@ -105,7 +105,7 @@ RDL.type :'File::Stat', :mode, '() -> Integer'
|
|
105
105
|
RDL.type :'File::Stat', :mtime, '() -> Time'
|
106
106
|
RDL.type :'File::Stat', :nlink, '() -> Integer'
|
107
107
|
RDL.type :'File::Stat', :owned?, '() -> %bool'
|
108
|
-
RDL.type :'File::Stat', :
|
108
|
+
RDL.type :'File::Stat', :pipe?, '() -> %bool'
|
109
109
|
RDL.type :'File::Stat', :rdev, '() -> Integer or nil'
|
110
110
|
RDL.type :'File::Stat', :rdev_major, '() -> Integer'
|
111
111
|
RDL.type :'File::Stat', :rdev_minor, '() -> Integer'
|
data/lib/types/core/float.rb
CHANGED
@@ -1,5 +1,208 @@
|
|
1
1
|
RDL.nowrap :Float
|
2
2
|
|
3
|
+
RDL.type :Float, :%, '(Integer x {{ x != 0 }}) -> ``sing_or_type(trec, targs, :%, "Float")``'
|
4
|
+
RDL.type :Float, :%, '(Float x {{ x != 0 }}) -> ``sing_or_type(trec, targs, :%, "Float")``'
|
5
|
+
RDL.type :Float, :%, '(Rational x {{ x != 0 }}) -> ``sing_or_type(trec, targs, :%, "Float")``'
|
6
|
+
RDL.type :Float, :%, '(BigDecimal x {{ x != 0 && !self.infinite? && !self.nan? }}) -> ``sing_or_type(trec, targs, :%, "BigDecimal")``'
|
7
|
+
|
8
|
+
RDL.type :Float, :*, '(Integer) -> ``sing_or_type(trec, targs, :*, "Float")``'
|
9
|
+
RDL.type :Float, :*, '(Float) -> ``sing_or_type(trec, targs, :*, "Float")``'
|
10
|
+
RDL.type :Float, :*, '(Rational) -> ``sing_or_type(trec, targs, :*, "Float")``'
|
11
|
+
RDL.type :Float, :*, '(BigDecimal x {{ !self.infinite? && !self.nan? }}) -> ``sing_or_type(trec, targs, :*, "BigDecimal")``'
|
12
|
+
RDL.type :Float, :*, '(Complex) -> ``sing_or_type(trec, targs, :*, "Complex")``'
|
13
|
+
RDL.pre(:Float, :*) { |x| if (x.real.is_a?(BigDecimal)||x.imaginary.is_a?(BigDecimal)) then (if x.real.is_a?(Float) then (x.real!=Float::INFINITY && !(x.real.nan?)) elsif(x.imaginary.is_a?(Float)) then x.imaginary!=Float::INFINITY && !(x.imaginary.nan?) else true end) && self!=Float::INFINITY && !(self.nan?) else true end} #can't have a complex with part BigDecimal, other part infinity/NAN
|
14
|
+
|
15
|
+
RDL.type :Float, :**, '(Integer) -> ``sing_or_type(trec, targs, :**, "Float")``'
|
16
|
+
RDL.type :Float, :**, '(Float) -> ``sing_or_type(trec, targs, :**, "%numeric")``'
|
17
|
+
RDL.type :Float, :**, '(Rational) -> ``sing_or_type(trec, targs, :**, "%numeric")``'
|
18
|
+
RDL.type :Float, :**, '(BigDecimal) -> ``sing_or_type(trec, targs, :**, "BigDecimal")``'
|
19
|
+
RDL.pre(:Float, :**) { |x| x!=BigDecimal::INFINITY && if self<0 then x<=-1||x>=0 else true end}
|
20
|
+
RDL.post(:Float, :**) { |x| x.real?}
|
21
|
+
RDL.type :Float, :**, '(Complex) -> ``sing_or_type(trec, targs, :**, "Complex")``'
|
22
|
+
RDL.pre(:Float, :**) { |x| x != 0 && if (x.real.is_a?(BigDecimal)||x.imaginary.is_a?(BigDecimal)) then (if x.real.is_a?(Float) then (x.real!=Float::INFINITY && !(x.real.nan?)) elsif(x.imaginary.is_a?(Float)) then x.imaginary!=Float::INFINITY && !(x.imaginary.nan?) else true end) && self!=Float::INFINITY && !(self.nan?) else true end}
|
23
|
+
|
24
|
+
RDL.type :Float, :+, '(Integer) -> ``sing_or_type(trec, targs, :+, "Float")``'
|
25
|
+
RDL.type :Float, :+, '(Float) -> ``sing_or_type(trec, targs, :+, "Float")``'
|
26
|
+
RDL.type :Float, :+, '(Rational) -> ``sing_or_type(trec, targs, :+, "Float")``'
|
27
|
+
RDL.type :Float, :+, '(BigDecimal x {{ !self.infinite? && !self.nan? }}) -> ``sing_or_type(trec, targs, :+, "BigDecimal")``'
|
28
|
+
RDL.type :Float, :+, '(Complex) -> ``sing_or_type(trec, targs, :+, "Complex")``'
|
29
|
+
RDL.pre(:Float, :+) { |x| if x.real.is_a?(BigDecimal) then self!=Float::INFINITY && !(self.nan?) else true end}
|
30
|
+
|
31
|
+
RDL.type :Float, :-, '(Integer) -> ``sing_or_type(trec, targs, :-, "Float")``'
|
32
|
+
RDL.type :Float, :-, '(Float) -> ``sing_or_type(trec, targs, :-, "Float")``'
|
33
|
+
RDL.type :Float, :-, '(Rational) -> ``sing_or_type(trec, targs, :-, "Float")``'
|
34
|
+
RDL.type :Float, :-, '(BigDecimal x {{ !self.infinite? && !self.nan? }}) -> ``sing_or_type(trec, targs, :-, "BigDecimal")``'
|
35
|
+
RDL.type :Float, :-, '(Complex) -> ``sing_or_type(trec, targs, :-, "Complex")``'
|
36
|
+
RDL.pre(:Float, :-) { |x| if x.real.is_a?(BigDecimal) then self!=Float::INFINITY && !(self.nan?) else true end}
|
37
|
+
|
38
|
+
RDL.type :Float, :-@, '() -> ``sing_or_type(trec, targs, :-@, "Float")``'
|
39
|
+
|
40
|
+
RDL.type :Float, :+@, '() -> ``sing_or_type(trec, targs, :+@, "Float")``'
|
41
|
+
|
42
|
+
RDL.type :Float, :/, '(Integer x {{ x != 0 }}) -> ``sing_or_type(trec, targs, :/, "Float")``'
|
43
|
+
RDL.type :Float, :/, '(Float x {{ x != 0 }}) -> ``sing_or_type(trec, targs, :/, "Float")``'
|
44
|
+
RDL.type :Float, :/, '(Rational x {{ x != 0 }}) -> ``sing_or_type(trec, targs, :/, "Float")``'
|
45
|
+
RDL.type :Float, :/, '(BigDecimal x {{ x != 0 && !self.infinite? && !self.nan? }}) -> ``sing_or_type(trec, targs, :/, "BigDecimal")``'
|
46
|
+
RDL.type :Float, :/, '(Complex x {{ x != 0 }}) -> ``sing_or_type(trec, targs, :/, "Complex")``'
|
47
|
+
RDL.pre(:Float, :/) { |x| if (x.real.is_a?(BigDecimal)||x.imaginary.is_a?(BigDecimal)) then (if x.real.is_a?(Float) then (x.real!=Float::INFINITY && !(x.real.nan?)) elsif(x.imaginary.is_a?(Float)) then x.imaginary!=Float::INFINITY && !(x.imaginary.nan?) else true end) && self!=Float::INFINITY && !(self.nan?) else true end && if (x.real.is_a?(Rational) && x.imaginary.is_a?(Float)) then !x.imaginary.nan? else true end}
|
48
|
+
|
49
|
+
RDL.type :Float, :<, '(Integer) -> ``sing_or_type(trec, targs, :<, "%bool")``'
|
50
|
+
RDL.type :Float, :<, '(Float) -> ``sing_or_type(trec, targs, :<, "%bool")``'
|
51
|
+
RDL.type :Float, :<, '(Rational) -> ``sing_or_type(trec, targs, :<, "%bool")``'
|
52
|
+
RDL.type :Float, :<, '(BigDecimal x {{ !self.nan? && !self.infinite? }}) -> ``sing_or_type(trec, targs, :<, "%bool")``'
|
53
|
+
|
54
|
+
RDL.type :Float, :<=, '(Integer) -> ``sing_or_type(trec, targs, :<=, "%bool")``'
|
55
|
+
RDL.type :Float, :<=, '(Float) -> ``sing_or_type(trec, targs, :<=, "%bool")``'
|
56
|
+
RDL.type :Float, :<=, '(Rational) -> ``sing_or_type(trec, targs, :<=, "%bool")``'
|
57
|
+
RDL.type :Float, :<=, '(BigDecimal x {{ !self.nan? && !self.infinite? }}) -> ``sing_or_type(trec, targs, :<=, "%bool")``'
|
58
|
+
|
59
|
+
RDL.type :Float, :<=>, '(Integer) -> ``sing_or_type(trec, targs, :<=>, "Integer")``'
|
60
|
+
RDL.post(:Float, :<=>) { |x| x == -1 || x==0 || x==1}
|
61
|
+
RDL.type :Float, :<=>, '(Float) -> ``sing_or_type(trec, targs, :<=>, "Integer")``'
|
62
|
+
RDL.post(:Float, :<=>) { |x| x == -1 || x==0 || x==1}
|
63
|
+
RDL.type :Float, :<=>, '(Rational) -> ``sing_or_type(trec, targs, :<=>, "Integer")``'
|
64
|
+
RDL.post(:Float, :<=>) { |x| x == -1 || x==0 || x==1}
|
65
|
+
RDL.type :Float, :<=>, '(BigDecimal x {{ !self.infinite? && !self.nan? }}) -> ``sing_or_type(trec, targs, :<=>, "Integer")``'
|
66
|
+
RDL.post(:Float, :<=>) { |x| x == -1 || x==0 || x==1}
|
67
|
+
|
68
|
+
RDL.type :Float, :==, '(Object) -> ``sing_or_type(trec, targs, :==, "%bool")``'
|
69
|
+
RDL.pre(:Float, :==) { |x| if (x.is_a?(BigDecimal)) then (!self.nan? && self!=Float::INFINITY) else true end}
|
70
|
+
|
71
|
+
RDL.type :Float, :===, '(Object) -> ``sing_or_type(trec, targs, :===, "%bool")``'
|
72
|
+
RDL.pre(:Float, :===) { |x| if (x.is_a?(BigDecimal)) then (!self.nan? && self!=Float::INFINITY) else true end}
|
73
|
+
|
74
|
+
RDL.type :Float, :>, '(Integer) -> ``sing_or_type(trec, targs, :>, "%bool")``'
|
75
|
+
RDL.type :Float, :>, '(Float) -> ``sing_or_type(trec, targs, :>, "%bool")``'
|
76
|
+
RDL.type :Float, :>, '(Rational) -> ``sing_or_type(trec, targs, :>, "%bool")``'
|
77
|
+
RDL.type :Float, :>, '(BigDecimal x {{ !self.infinite? && !self.nan? }}) -> ``sing_or_type(trec, targs, :>, "%bool")``'
|
78
|
+
|
79
|
+
RDL.type :Float, :>=, '(Integer) -> ``sing_or_type(trec, targs, :>=, "%bool")``'
|
80
|
+
RDL.type :Float, :>=, '(Float) -> ``sing_or_type(trec, targs, :>=, "%bool")``'
|
81
|
+
RDL.type :Float, :>=, '(Rational) -> ``sing_or_type(trec, targs, :>=, "%bool")``'
|
82
|
+
RDL.type :Float, :>=, '(BigDecimal x {{ !self.infinite? && !self.nan? }}) -> ``sing_or_type(trec, targs, :>=, "%bool")``'
|
83
|
+
|
84
|
+
RDL.type :Float, :abs, '() -> Float r {{ r>=0 || (if self.nan? then r.nan? end) }}' ## TODO
|
85
|
+
|
86
|
+
RDL.type :Float, :abs2, '() -> Float r {{ r>=0 || (if self.nan? then r.nan? end) }}' ## TODO
|
87
|
+
|
88
|
+
RDL.type :Float, :div, '(Integer x {{ x != 0 && !self.infinite? && !self.nan? }}) -> ``sing_or_type(trec, targs, :div, "Integer")``'
|
89
|
+
RDL.type :Float, :div, '(Float x {{ x != 0 && !self.infinite? && !self.nan? }}) -> ``sing_or_type(trec, targs, :div, "Integer")``'
|
90
|
+
RDL.type :Float, :div, '(Rational x {{ x != 0 && !self.infinite? && !self.nan? }}) -> ``sing_or_type(trec, targs, :div, "Integer")``'
|
91
|
+
RDL.type :Float, :div, '(BigDecimal x {{ x != 0 && !x.nan? && !self.infinite? && !self.nan? }}) -> ``sing_or_type(trec, targs, :div, "Integer")``'
|
92
|
+
|
93
|
+
RDL.type :Float, :divmod, '(%real) -> [%real, %real]'
|
94
|
+
RDL.pre(:Float, :divmod) { |x| x != 0 && if x.is_a?(Float) then !x.nan? else true end && self!=Float::INFINITY && !self.nan?}
|
95
|
+
|
96
|
+
RDL.type :Float, :angle, '() -> ``sing_or_type(trec, targs, :angle, "%numeric")``'
|
97
|
+
RDL.post(:Float, :angle) { |r,x| r == 0 || r == Math::PI || r == Float::NAN}
|
98
|
+
|
99
|
+
RDL.type :Float, :arg, '() -> ``sing_or_type(trec, targs, :rg, "%numeric")``'
|
100
|
+
RDL.post(:Float, :arg) { |r,x| r == 0 || r == Math::PI || r == Float::NAN}
|
101
|
+
|
102
|
+
RDL.type :Float, :ceil, '() -> ``sing_or_type(trec, targs, :ceil, "Integer")``'
|
103
|
+
RDL.pre(:Float, :ceil) { !self.infinite? && !self.nan?}
|
104
|
+
|
105
|
+
RDL.type :Float, :coerce, '(%real) -> [Float, Float]'
|
106
|
+
|
107
|
+
RDL.type :Float, :denominator, '() -> Integer r {{ r>0 }}' ## TODO
|
108
|
+
|
109
|
+
RDL.type :Float, :equal?, '(Object) -> ``sing_or_type(trec, targs, :equal?, "%bool")``'
|
110
|
+
|
111
|
+
RDL.type :Float, :eql?, '(Object) -> ``sing_or_type(trec, targs, :eql?, "%bool")``'
|
112
|
+
|
113
|
+
RDL.type :Float, :fdiv, '(Integer) -> ``sing_or_type(trec, targs, :fdiv, "Float")``'
|
114
|
+
RDL.type :Float, :fdiv, '(Float) -> ``sing_or_type(trec, targs, :fdiv, "Float")``'
|
115
|
+
RDL.type :Float, :fdiv, '(Rational) -> ``sing_or_type(trec, targs, :fdiv, "Float")``'
|
116
|
+
RDL.type :Float, :fdiv, '(BigDecimal x {{ !self.infinite? && !self.nan? }}) -> ``sing_or_type(trec, targs, :fdiv, "BigDecimal")``'
|
117
|
+
RDL.type :Float, :fdiv, '(Complex) -> ``sing_or_type(trec, targs, :fdiv, "Complex")``'
|
118
|
+
RDL.pre(:Float, :fdiv) { |x| x != 0 && if (x.real.is_a?(BigDecimal)||x.imaginary.is_a?(BigDecimal)) then (if x.real.is_a?(Float) then (x.real!=Float::INFINITY && !(x.real.nan?)) elsif(x.imaginary.is_a?(Float)) then x.imaginary!=Float::INFINITY && !(x.imaginary.nan?) else true end) && self!=Float::INFINITY && !(self.nan?) else true end && if (x.real.is_a?(Rational) && x.imaginary.is_a?(Float)) then !x.imaginary.nan? else true end}
|
119
|
+
|
120
|
+
RDL.type :Float, :finite?, '() -> ``sing_or_type(trec, targs, :finite?, "%bool")``'
|
121
|
+
|
122
|
+
RDL.type :Float, :floor, '() -> ``sing_or_type(trec, targs, :floor, "Integer")``'
|
123
|
+
RDL.pre(:Float, :ceil) { !self.infinite? && !self.nan?}
|
124
|
+
|
125
|
+
RDL.type :Float, :hash, '() -> Integer'
|
126
|
+
|
127
|
+
RDL.type :Float, :infinite?, '() -> ``sing_or_type(trec, targs, :infinite?, "Integer")``'
|
128
|
+
RDL.post(:Float, :infinite?) { |r,x| r == -1 || r == 1 || r == nil }
|
129
|
+
|
130
|
+
RDL.type :Float, :to_s, '() -> String'
|
131
|
+
RDL.type :Float, :inspect, '() -> String'
|
132
|
+
|
133
|
+
RDL.type :Float, :magnitude, '() -> ``sing_or_type(trec, targs, :magnitude, "Float")``'
|
134
|
+
RDL.post(:Float, :magnitude) { |r,x| r>=0 }
|
135
|
+
|
136
|
+
RDL.type :Float, :modulo, '(Integer x {{ x != 0 }}) -> ``sing_or_type(trec, targs, :modulo, "Float")``'
|
137
|
+
RDL.type :Float, :modulo, '(Float x {{ x != 0 }}) -> ``sing_or_type(trec, targs, :modulo, "Float")``'
|
138
|
+
RDL.type :Float, :modulo, '(Rational x {{ x != 0 }}) -> ``sing_or_type(trec, targs, :modulo, "Float")``'
|
139
|
+
RDL.type :Float, :modulo, '(BigDecimal x {{ x != 0 && !self.infinite? && !self.nan? }}) -> ``sing_or_type(trec, targs, :modulo, "BigDecimal")``'
|
140
|
+
|
141
|
+
RDL.type :Float, :nan?, '() -> ``sing_or_type(trec, targs, :nan?, "%bool")``'
|
142
|
+
|
143
|
+
RDL.type :Float, :next_float, '() -> ``sing_or_type(trec, targs, :next_float, "Float")``'
|
144
|
+
|
145
|
+
RDL.type :Float, :numerator, '() -> ``sing_or_type(trec, targs, :numerator, "Integer")``'
|
146
|
+
|
147
|
+
RDL.type :Float, :phase, '() -> ``sing_or_type(trec, targs, :phase, "%numeric")``'
|
148
|
+
RDL.post(:Float, :phase) { |r,x| r == 0 || r == Math::PI || r == Float::NAN}
|
149
|
+
|
150
|
+
RDL.type :Float, :prev_float, '() -> ``sing_or_type(trec, targs, :prev_float, "Float")``'
|
151
|
+
|
152
|
+
RDL.type :Float, :quo, '(Integer x {{ x != 0 }}) -> ``sing_or_type(trec, targs, :quo, "Float")``'
|
153
|
+
RDL.type :Float, :quo, '(Float x {{ x != 0 }}) -> ``sing_or_type(trec, targs, :quo, "Float")``'
|
154
|
+
RDL.type :Float, :quo, '(Rational x {{ x != 0 }}) -> ``sing_or_type(trec, targs, :quo, "Float")``'
|
155
|
+
RDL.type :Float, :quo, '(BigDecimal x {{ x != 0 && !self.infinite? && !self.nan? }}) -> ``sing_or_type(trec, targs, :quo, "BigDecimal")``'
|
156
|
+
RDL.type :Float, :quo, '(Complex x {{ x != 0 }}) -> ``sing_or_type(trec, targs, :quo, "Complex")``'
|
157
|
+
RDL.pre(:Float, :quo) { |x| if (x.real.is_a?(BigDecimal)||x.imaginary.is_a?(BigDecimal)) then (if x.real.is_a?(Float) then (x.real!=Float::INFINITY && !(x.real.nan?)) elsif(x.imaginary.is_a?(Float)) then x.imaginary!=Float::INFINITY && !(x.imaginary.nan?) else true end) && self!=Float::INFINITY && !(self.nan?) else true end && if (x.real.is_a?(Rational) && x.imaginary.is_a?(Float)) then !x.imaginary.nan? else true end}
|
158
|
+
|
159
|
+
RDL.type :Float, :rationalize, '() -> ``sing_or_type(trec, targs, :rationalize, "Rational")``'
|
160
|
+
RDL.pre(:Float, :rationalize) { !self.infinite? && !self.nan?}
|
161
|
+
|
162
|
+
RDL.type :Float, :rationalize, '(%numeric) -> ``sing_or_type(trec, targs, :rationalize, "Rational")``'
|
163
|
+
RDL.pre(:Float, :rationalize) { |x| if x.is_a?(Float) then x!=Float::INFINITY && !x.nan? else true end}
|
164
|
+
|
165
|
+
RDL.type :Float, :round, '() -> ``sing_or_type(trec, targs, :round, "Integer")``'
|
166
|
+
RDL.pre(:Float, :round) { !self.infinite? && !self.nan?}
|
167
|
+
|
168
|
+
RDL.type :Float, :round, '(%numeric) -> ``sing_or_type(trec, targs, :round, "%numeric")``'
|
169
|
+
RDL.pre(:Float, :round) { |x| x != 0 && if x.is_a?(Complex) then x.imaginary==0 && (if x.real.is_a?(Float)||x.real.is_a?(BigDecimal) then !x.real.infinite? && !x.real.nan? else true end) elsif x.is_a?(Float) then x!=Float::INFINITY && !x.nan? elsif x.is_a?(BigDecimal) then x!=BigDecimal::INFINITY && !x.nan? else true end} #Also, x must be in range [-2**31, 2**31].
|
170
|
+
|
171
|
+
RDL.type :Float, :to_f, '() -> self'
|
172
|
+
|
173
|
+
RDL.type :Float, :to_i, '() -> ``sing_or_type(trec, targs, :to_i, "Integer")``'
|
174
|
+
RDL.pre(:Float, :to_i) { !self.infinite? && !self.nan?}
|
175
|
+
|
176
|
+
RDL.type :Float, :to_int, '() -> ``sing_or_type(trec, targs, :to_int, "Integer")``'
|
177
|
+
RDL.pre(:Float, :to_int) { !self.infinite? && !self.nan?}
|
178
|
+
|
179
|
+
RDL.type :Float, :to_r, '() -> ``sing_or_type(trec, targs, :to_r, "Rational")``'
|
180
|
+
RDL.pre(:Float, :to_r) { !self.infinite? && !self.nan?}
|
181
|
+
|
182
|
+
RDL.type :Float, :truncate, '() -> ``sing_or_type(trec, targs, :truncate, "Integer")``'
|
183
|
+
|
184
|
+
RDL.type :Float, :zero?, '() -> ``sing_or_type(trec, targs, :zero, "%bool")``'
|
185
|
+
|
186
|
+
RDL.type :Float, :conj, '() -> ``sing_or_type(trec, targs, :conj, "Float")``'
|
187
|
+
RDL.type :Float, :conjugate, '() -> ``sing_or_type(trec, targs, :conjugate, "Float")``'
|
188
|
+
|
189
|
+
RDL.type :Float, :imag, '() -> Integer r {{ r==0 }}' ## TODO
|
190
|
+
RDL.type :Float, :imaginary, '() -> Integer r {{ r==0 }}' ## TODO
|
191
|
+
|
192
|
+
RDL.type :Float, :real, '() -> ``sing_or_type(trec, targs, :real, "Float")``'
|
193
|
+
|
194
|
+
RDL.type :Float, :real?, '() -> ``sing_or_type(trec, targs, :real?, "%bool")``'
|
195
|
+
|
196
|
+
RDL.type :Float, :to_c, '() -> Complex r {{ r.imaginary == 0 }}' ## TODO
|
197
|
+
|
198
|
+
RDL.type :Float, :coerce, '(%numeric) -> [Float, Float]'
|
199
|
+
RDL.pre(:Float, :coerce) { |x| if x.is_a?(Complex) then x.imaginary==0 else true end}
|
200
|
+
|
201
|
+
|
202
|
+
|
203
|
+
######### Non-dependent types below #########
|
204
|
+
|
205
|
+
|
3
206
|
RDL.type :Float, :%, '(Integer x {{ x != 0 }}) -> Float'
|
4
207
|
RDL.type :Float, :%, '(Float x {{ x != 0 }}) -> Float'
|
5
208
|
RDL.type :Float, :%, '(Rational x {{ x != 0 }}) -> Float'
|
data/lib/types/core/hash.rb
CHANGED
@@ -2,14 +2,386 @@ RDL.nowrap :Hash
|
|
2
2
|
|
3
3
|
RDL.type_params :Hash, [:k, :v], :all?
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
RDL
|
5
|
+
def Hash.output_type(trec, targs, meth_name, default1, default2=default1, nil_default: false, use_sing_val: true)
|
6
|
+
case trec
|
7
|
+
when RDL::Type::FiniteHashType
|
8
|
+
if targs.empty? || targs.all? { |t| t.is_a?(RDL::Type::SingletonType) }
|
9
|
+
vals = RDL.type_cast((if use_sing_val then targs.map { |t| RDL.type_cast(t, "RDL::Type::SingletonType").val } else targs end), "Array<%any>", force: true)
|
10
|
+
res = RDL.type_cast(trec.elts.send(meth_name, *vals), "Object", force: true)
|
11
|
+
if nil_default && res.nil?
|
12
|
+
if default1 == :promoted_val
|
13
|
+
return trec.promote.params[1]
|
14
|
+
elsif default1 == :promoted_key
|
15
|
+
return trec.promote.params[0]
|
16
|
+
else
|
17
|
+
return RDL::Globals.parser.scan_str "#T #{default1}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
to_type(res)
|
21
|
+
else
|
22
|
+
if default1 == :promoted_val
|
23
|
+
x = trec.promote.params[1]
|
24
|
+
return x
|
25
|
+
elsif default1 == :promoted_key
|
26
|
+
return trec.promote.params[0]
|
27
|
+
else
|
28
|
+
RDL::Globals.parser.scan_str "#T #{default1}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
else
|
32
|
+
RDL::Globals.parser.scan_str "#T #{default2}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
RDL.type Hash, 'self.output_type', "(RDL::Type::Type, Array<RDL::Type::Type>, Symbol, Symbol or String, ?(Symbol or String), { nil_default: ?%bool, use_sing_val: ?%bool } ) -> RDL::Type::Type", typecheck: :type_code, wrap: false, effect: [:+, :+]
|
36
|
+
|
37
|
+
|
38
|
+
def Hash.to_type(t)
|
39
|
+
case t
|
40
|
+
when RDL::Type::Type
|
41
|
+
t
|
42
|
+
when Array
|
43
|
+
RDL::Type::TupleType.new(*(t.map { |i| to_type(i) }))
|
44
|
+
else
|
45
|
+
## symbols, ints, nil, ...
|
46
|
+
RDL::Type::SingletonType.new(t)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
RDL.type Hash, 'self.to_type', "(%any) -> RDL::Type::Type", typecheck: :type_code, wrap: false, effect: [:+, :+]
|
50
|
+
|
51
|
+
def Hash.any_or_k(trec)
|
52
|
+
case trec
|
53
|
+
when RDL::Type::FiniteHashType
|
54
|
+
RDL::Globals.types[:top]
|
55
|
+
else
|
56
|
+
RDL::Globals.parser.scan_str "#T k"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
RDL.type Hash, 'self.any_or_k', "(RDL::Type::Type) -> RDL::Type::Type", typecheck: :type_code, wrap: false, effect: [:+, :+]
|
60
|
+
|
61
|
+
def Hash.any_or_v(trec)
|
62
|
+
case trec
|
63
|
+
when RDL::Type::FiniteHashType
|
64
|
+
RDL::Globals.types[:top]
|
65
|
+
else
|
66
|
+
RDL::Globals.parser.scan_str "#T v"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
RDL.type Hash, 'self.any_or_v', "(RDL::Type::Type) -> RDL::Type::Type", typecheck: :type_code, wrap: false, effect: [:+, :+]
|
70
|
+
|
71
|
+
def Hash.promoted_or_v(trec)
|
72
|
+
case trec
|
73
|
+
when RDL::Type::FiniteHashType
|
74
|
+
trec.promote.params[1]
|
75
|
+
else
|
76
|
+
RDL::Globals.parser.scan_str "#T v"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
RDL.type Hash, 'self.promoted_or_v', "(RDL::Type::Type) -> RDL::Type::Type", typecheck: :type_code, wrap: false, effect: [:+, :+]
|
80
|
+
|
81
|
+
|
82
|
+
def Hash.weak_promote(val)
|
83
|
+
case val
|
84
|
+
when RDL::Type::UnionType
|
85
|
+
if val.types.all? { |t| t.is_a?(RDL::Type::SingletonType) }
|
86
|
+
klass = RDL.type_cast(val.types[0], "RDL::Type::SingletonType", force: true).nominal.klass
|
87
|
+
if val.types.all? { |t| RDL.type_cast(t, "RDL::Type::SingletonType", force: true).nominal.klass == klass }
|
88
|
+
return RDL::Type::NominalType.new(klass)
|
89
|
+
else
|
90
|
+
return val
|
91
|
+
end
|
92
|
+
else
|
93
|
+
return val
|
94
|
+
end
|
95
|
+
else
|
96
|
+
val
|
97
|
+
end
|
98
|
+
end
|
99
|
+
RDL.type Hash, 'self.weak_promote', "(RDL::Type::Type) -> RDL::Type::Type", typecheck: :type_code, wrap: false, effect: [:+, :+]
|
100
|
+
|
101
|
+
#RDL.type :Hash, 'self.[]', '(*%any) -> ``hash_create_output_from_list(targs)``'
|
102
|
+
RDL.type :Hash, 'self.[]', '(*%any) -> ``hash_create_output(targs)``'
|
103
|
+
|
104
|
+
def Hash.hash_create_output_from_list(targs)
|
105
|
+
raise RDL::Typecheck::StaticTypeError, "Hash[...] expect only 1 argument. Have #{targs}." if targs.size > 1
|
106
|
+
raise RDL::Typecheck::StaticTypeError, "The argument has to be an array or tuple" unless (targs[0].is_a?(RDL::Type::GenericType) && targs[0].base.klass == Array)
|
107
|
+
|
108
|
+
case targs[0].params[0]
|
109
|
+
when RDL::Type::GenericType
|
110
|
+
return RDL::Globals.parser.scan_str "#T Hash<#{targs[0].params[0].params[0]}, #{targs[0].params[0].params[0]}>"
|
111
|
+
when RDL::Type::TupleType
|
112
|
+
return RDL::Type::GenericType.new(RDL::Type::NominalType.new(Hash), targs[0].params[0].params[0], targs[0].params[0].params[1])
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def Hash.hash_create_output(targs)
|
117
|
+
return hash_create_output_from_list(targs) if targs.size == 1
|
118
|
+
|
119
|
+
raise RDL::Typecheck::StaticTypeError, "Hash.[] expects an even number of arguments. Have #{targs}." if targs.size.odd?
|
120
|
+
args = RDL.type_cast([], "Array<%any>", force: true)
|
121
|
+
i = -1
|
122
|
+
args = targs.map { |a| i = i+1 ; if i.even? && a.is_a?(RDL::Type::SingletonType) then RDL.type_cast(a, "RDL::Type::SingletonType", force: true).val else a end }
|
123
|
+
RDL::Type::FiniteHashType.new(RDL.type_cast(Hash[*args], "Hash<%any, RDL::Type::Type>", force: true), nil)
|
124
|
+
end
|
125
|
+
RDL.type Hash, 'self.hash_create_output', "(Array<RDL::Type::Type>) -> RDL::Type::Type", typecheck: :type_code, wrap: false, effect: [:+, :+]
|
126
|
+
|
127
|
+
RDL.type :Hash, :[], '(``any_or_k(trec)``) -> ``output_type(trec, targs, :[], :promoted_val, "v", nil_default: true)``', effect: [:+, :+]
|
128
|
+
|
129
|
+
RDL.type :Hash, :[]=, '(``any_or_k(trec)``, ``any_or_v(trec)``) -> ``assign_output(trec, targs)``'
|
130
|
+
|
131
|
+
|
132
|
+
def Hash.assign_output(trec, targs)
|
133
|
+
case trec
|
134
|
+
when RDL::Type::FiniteHashType
|
135
|
+
case targs[0]
|
136
|
+
when RDL::Type::SingletonType ### TODO: adjust for strings
|
137
|
+
argval = RDL.type_cast(targs[0], "RDL::Type::SingletonType", force: true).val
|
138
|
+
trec.elts[argval] = RDL::Type::UnionType.new(trec.elts[argval], targs[1]).canonical
|
139
|
+
trec.elts[argval] = weak_promote(trec.elts[argval]) if RDL::Config.instance.weak_update_promote
|
140
|
+
raise RDL::Typecheck::StaticTypeError, "Failed to mutate hash: new hash does not match prior type constraints." unless trec.check_bounds(true)
|
141
|
+
return targs[1]
|
142
|
+
else
|
143
|
+
raise "Unable to promote tuple #{trec} to Hash." unless trec.promote!(targs[0], targs[1])
|
144
|
+
return targs[1]
|
145
|
+
end
|
146
|
+
else
|
147
|
+
RDL::Globals.parser.scan_str "#T v"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
RDL.type Hash, 'self.assign_output', "(RDL::Type::Type, Array<RDL::Type::Type>) -> RDL::Type::Type", typecheck: :type_code, wrap: false, effect: [:~, :+]
|
151
|
+
|
152
|
+
RDL.type :Hash, :store, '(``any_or_k(trec)``, ``any_or_v(trec)``) -> ``assign_output(trec, targs)``'
|
153
|
+
RDL.type :Hash, :assoc, '(``any_or_k(trec)``) -> ``RDL::Type::TupleType.new(targs[0], output_type(trec, targs, :[], :promoted_val, "v", nil_default: true))``'
|
154
|
+
RDL.type :Hash, :clear, '() -> self'
|
155
|
+
RDL.type :Hash, :compare_by_identity, '() -> self'
|
156
|
+
RDL.type :Hash, :compare_by_identity?, '() -> %bool'
|
157
|
+
RDL.type :Hash, :default, '() -> ``promoted_or_v(trec)``'
|
158
|
+
RDL.type :Hash, :default, '(``any_or_k(trec)``) -> ``promoted_or_v(trec)``'
|
159
|
+
RDL.type :Hash, :default=, '(``promoted_or_v(trec)``) -> ``promoted_or_v(trec)``'
|
160
|
+
|
161
|
+
RDL.type :Hash, :delete, '(``any_or_k(trec)``) -> ``delete_output(trec, targs, false)``'
|
162
|
+
RDL.type :Hash, :delete, '(``any_or_k(trec)``) { (``any_or_k(trec)``) -> u } -> ``delete_output(trec, targs, true)``'
|
163
|
+
|
164
|
+
def Hash.delete_output(trec, targs, block)
|
165
|
+
case trec
|
166
|
+
when RDL::Type::FiniteHashType
|
167
|
+
case targs[0]
|
168
|
+
when RDL::Type::SingletonType
|
169
|
+
argval = RDL.type_cast(targs[0], "RDL::Type::SingletonType", force: true).val
|
170
|
+
if trec.elts.include?(argval)
|
171
|
+
trec.elts[argval]
|
172
|
+
else
|
173
|
+
trec.promote.params[1]
|
174
|
+
end
|
175
|
+
else
|
176
|
+
if block
|
177
|
+
RDL::Type::UnionType.new(trec.promote.params[1], RDL::Globals.parser.scan_str("#T u"))
|
178
|
+
else
|
179
|
+
trec.promote.params[1]
|
180
|
+
end
|
181
|
+
end
|
182
|
+
else
|
183
|
+
t = (if block then "u or v" else "v" end)
|
184
|
+
RDL::Globals.parser.scan_str "#T #{t}"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
RDL.type Hash, 'self.delete_output', "(RDL::Type::Type, Array<RDL::Type::Type>, %bool) -> RDL::Type::Type", typecheck: :type_code, wrap: false, effect: [:+, :+]
|
188
|
+
|
189
|
+
RDL.type :Hash, :delete_if, '() { (``any_or_k(trec)``, ``any_or_v(trec)``) -> %any } -> self'
|
190
|
+
RDL.type :Hash, :delete_if, '() -> ``RDL::Type::GenericType.new(RDL::Type::NominalType.new(Enumerator), RDL::Type::TupleType.new(any_or_k(trec), any_or_v(trec)))``' ## I had made a mistake here, type checker caught it.
|
191
|
+
RDL.type :Hash, :each, '() { (``any_or_k(trec)``, ``any_or_v(trec)``) -> %any } -> self'
|
192
|
+
RDL.type :Hash, :each, '() -> ``RDL::Type::GenericType.new(RDL::Type::NominalType.new(Enumerator), RDL::Type::TupleType.new(any_or_k(trec), any_or_v(trec)))``' ## I had made a mistake here, type checker caught it.
|
193
|
+
RDL.type :Hash, :each_pair, '() { (``any_or_k(trec)``, ``any_or_v(trec)``) -> %any } -> self'
|
194
|
+
RDL.type :Hash, :each_pair, '() -> ``RDL::Type::GenericType.new(RDL::Type::NominalType.new(Enumerator), RDL::Type::TupleType.new(any_or_k(trec), any_or_v(trec)))``' ## I had made a mistake here, type checker caught it.
|
195
|
+
RDL.type :Hash, :each_key, '() { (``any_or_k(trec)``) -> %any } -> self'
|
196
|
+
RDL.type :Hash, :each_key, '() -> ``RDL::Type::GenericType.new(RDL::Type::NominalType.new(Enumerator), any_or_k(trec))``'
|
197
|
+
RDL.type :Hash, :each_value, '() { (``any_or_v(trec)``) -> %any } -> self'
|
198
|
+
RDL.type :Hash, :each_value, '() -> ``RDL::Type::GenericType.new(RDL::Type::NominalType.new(Enumerator), any_or_v(trec))``'
|
199
|
+
RDL.type :Hash, :empty?, '() -> ``output_type(trec, targs, :empty?, "%bool")``'
|
200
|
+
RDL.type :Hash, :fetch, '(``any_or_k(trec)``) -> ``output_type(trec, targs, :fetch, :promoted_val, "v", nil_default: true)``'
|
201
|
+
RDL.type :Hash, :fetch, '(``any_or_k(trec)``, u) -> ``RDL::Type::UnionType.new(RDL::Globals.parser.scan_str("u"), output_type(trec, targs, :fetch, :promoted_val, "v", nil_default: true))``'
|
202
|
+
RDL.type :Hash, :fetch, '(``any_or_k(trec)``) { (``any_or_k(trec)``) -> u } -> ``RDL::Type::UnionType.new(RDL::Globals.parser.scan_str("u"), output_type(trec, targs, :fetch, :promoted_val, "v", nil_default: true))``'
|
203
|
+
RDL.type :Hash, :member?, '(%any) -> ``output_type(trec, targs, :member?, "%bool")``'
|
204
|
+
RDL.type :Hash, :has_key?, '(%any) -> ``output_type(trec, targs, :has_key?, "%bool")``', effect: [:+, :+]
|
205
|
+
RDL.type :Hash, :key?, '(%any) -> ``output_type(trec, targs, :key?, "%bool")``'
|
206
|
+
RDL.type :Hash, :has_value?, '(%any) -> ``output_type(trec, targs, :has_value?, "%bool")``'
|
207
|
+
RDL.type :Hash, :value?, '(%any) -> ``output_type(trec, targs, :value?, "%bool")``'
|
208
|
+
RDL.type :Hash, :to_s, '() -> String'
|
209
|
+
RDL.type :Hash, :inspect, '() -> String'
|
210
|
+
RDL.type :Hash, :invert, '() -> ``invert_output(trec)``'
|
211
|
+
|
212
|
+
|
213
|
+
def Hash.invert_output(trec)
|
214
|
+
case trec
|
215
|
+
when RDL::Type::FiniteHashType
|
216
|
+
hash = trec.elts.invert
|
217
|
+
hash = Hash[hash.map { |k, v| if !RDL.type_cast(v, "Object", force: true).is_a?(RDL::Type::Type) then [k, RDL::Type::SingletonType.new(v)] else [k, v] end }]
|
218
|
+
RDL::Type::FiniteHashType.new(RDL.type_cast(hash, "Hash<%any, RDL::Type::Type>", force: true), nil)
|
219
|
+
else
|
220
|
+
RDL::Globals.parser.scan_str "#T Hash<v, k>"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
RDL.type Hash, 'self.invert_output', "(RDL::Type::Type) -> RDL::Type::Type", typecheck: :type_code, wrap: false, effect: [:+, :+]
|
224
|
+
|
225
|
+
RDL.type :Hash, :keep_if, '() { (``any_or_k(trec)``,``any_or_v(trec)``) -> %bool } -> self'
|
226
|
+
RDL.type :Hash, :keep_if, '() -> ``RDL::Type::GenericType.new(RDL::Type::NominalType.new(Enumerator), RDL::Type::TupleType.new(any_or_k(trec), any_or_v(trec)))``' ## I had made a mistake here, type checker caught it.
|
227
|
+
RDL.type :Hash, :key, '(%any) -> ``output_type(trec, targs, :key, :promoted_key, "k", nil_default: true, use_sing_val: false)``'
|
228
|
+
RDL.type :Hash, :keys, '() -> ``output_type(trec, targs, :keys, "Array<k>")``'
|
229
|
+
RDL.type :Hash, :length, '() -> ``output_type(trec, targs, :length, "Integer")``'
|
230
|
+
RDL.type :Hash, :size, '() -> ``output_type(trec, targs, :size, "Integer")``'
|
231
|
+
RDL.type :Hash, :merge, '(``merge_input(targs)``) -> ``merge_output(trec, targs)``'
|
232
|
+
RDL.type :Hash, :merge!, '(``merge_input(targs, true)``) -> ``merge_output(trec, targs, true)``'
|
233
|
+
|
234
|
+
|
235
|
+
def Hash.merge_input(targs, mutate=false)
|
236
|
+
case targs[0]
|
237
|
+
when RDL::Type::FiniteHashType
|
238
|
+
return targs[0]
|
239
|
+
when RDL::Type::GenericType
|
240
|
+
if mutate
|
241
|
+
return RDL::Globals.parser.scan_str "#T Hash<k, v>"
|
242
|
+
else
|
243
|
+
return RDL::Globals.parser.scan_str "#T Hash<a, b>"
|
244
|
+
end
|
245
|
+
else
|
246
|
+
RDL::Globals.types[:hash]
|
247
|
+
end
|
248
|
+
end
|
249
|
+
RDL.type Hash, 'self.merge_input', "(Array<RDL::Type::Type>, ?%bool) -> RDL::Type::Type", typecheck: :type_code, wrap: false, effect: [:+, :+]
|
250
|
+
|
251
|
+
|
252
|
+
def Hash.merge_output(trec, targs, mutate=false)
|
253
|
+
case trec
|
254
|
+
when RDL::Type::NominalType
|
255
|
+
return RDL::Globals.types[:hash]
|
256
|
+
when RDL::Type::GenericType
|
257
|
+
case targs[0]
|
258
|
+
when RDL::Type::FiniteHashType
|
259
|
+
promoted = RDL.type_cast(targs[0], "RDL::Type::FiniteHashType", force: true).promote
|
260
|
+
key_union = RDL::Type::UnionType.new(promoted.params[0], trec.params[0]).canonical
|
261
|
+
value_union = RDL::Type::UnionType.new(promoted.params[1], trec.params[1]).canonical
|
262
|
+
if mutate
|
263
|
+
raise "Call to `merge!` would change type of Hash." unless (key_union == trec.params[0]) && (value_union == trec.params[1])
|
264
|
+
return trec
|
265
|
+
else
|
266
|
+
return RDL::Type::GenericType.new(trec.base, key_union, value_union)
|
267
|
+
end
|
268
|
+
when RDL::Type::GenericType
|
269
|
+
ret = (if mutate then "Hash<k, v>" else "Hash<a or k, b or v>" end)
|
270
|
+
return RDL::Globals.parser.scan_str "#T #{ret}"
|
271
|
+
else
|
272
|
+
## targs[0] should just be hash here
|
273
|
+
return RDL::Globals.types[:hash]
|
274
|
+
end
|
275
|
+
when RDL::Type::FiniteHashType
|
276
|
+
case targs[0]
|
277
|
+
when RDL::Type::FiniteHashType
|
278
|
+
arg = RDL.type_cast(targs[0], "RDL::Type::FiniteHashType", force: true)
|
279
|
+
if mutate
|
280
|
+
if arg.elts.any? { |k, v| !RDL.type_cast(k, "Object", force: true).is_a?(Symbol) }
|
281
|
+
arg_key = arg.promote.params[0]
|
282
|
+
arg_val = arg.promote.params[1]
|
283
|
+
raise "Unable to promote tuple #{trec} to Hash." unless trec.promote!(arg_key, arg_val)
|
284
|
+
return trec
|
285
|
+
end
|
286
|
+
trec.elts = RDL.type_cast(Hash[trec.elts.map { |k, v| if arg.elts.has_key?(k) then [k, RDL::Type::UnionType.new(arg.elts[k], v).canonical] else [k, v] end } ].merge(arg.elts), "Hash<%any, RDL::Type::Type>", force: true)
|
287
|
+
raise RDL::Typecheck::StaticTypeError, "Failed to mutate hash: new hash does not match prior type constraints." unless trec.check_bounds(true)
|
288
|
+
return trec
|
289
|
+
else
|
290
|
+
return RDL::Type::FiniteHashType.new(trec.elts.merge(arg.elts), nil)
|
291
|
+
end
|
292
|
+
when RDL::Type::GenericType
|
293
|
+
arg0 = RDL.type_cast(targs[0], "RDL::Type::GenericType", force: true)
|
294
|
+
promoted = trec.promote
|
295
|
+
key_union = RDL::Type::UnionType.new(promoted.params[0], arg0.params[0]).canonical
|
296
|
+
value_union = RDL::Type::UnionType.new(promoted.params[1], arg0.params[1]).canonical
|
297
|
+
if mutate
|
298
|
+
raise "Unable to promote tuple #{trec} to Hash." unless trec.promote!(arg0.params[0], arg0.params[1])
|
299
|
+
return trec
|
300
|
+
else
|
301
|
+
return RDL::Type::GenericType.new(arg0.base, key_union, value_union)
|
302
|
+
end
|
303
|
+
else
|
304
|
+
## targs[0] should just be Hash here
|
305
|
+
return RDL::Globals.types[:hash]
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
end
|
310
|
+
RDL.type Hash, 'self.merge_output', "(RDL::Type::Type, Array<RDL::Type::Type>, ?%bool) -> RDL::Type::Type", typecheck: :type_code, wrap: false, effect: [:~, :+]
|
311
|
+
|
312
|
+
RDL.type :Hash, :merge, '(Hash<a,b>) { (k,v,b) -> v or b } -> Hash<a or k, b or v>'
|
313
|
+
RDL.type :Hash, :rassoc, '(``any_or_v(trec)``) -> ``RDL::Type::TupleType.new(output_type(trec, targs, :key, :promoted_key, "k", nil_default: true, use_sing_val: false),targs[0])``'
|
314
|
+
RDL.type :Hash, :rehash, '() -> self'
|
315
|
+
RDL.type :Hash, :reject, '() -> ``RDL::Type::GenericType.new(RDL::Type::NominalType.new(Enumerator), any_or_k(trec), any_or_v(trec))``'
|
316
|
+
RDL.type :Hash, :reject, '() {(``any_or_k(trec)``,``any_or_v(trec)``) -> %bool} -> self'
|
317
|
+
RDL.type :Hash, :reject!, '() {(``any_or_k(trec)``,``any_or_v(trec)``) -> %bool} -> self'
|
318
|
+
RDL.type :Hash, :select, '() {(``any_or_k(trec)``,``any_or_v(trec)``) -> %bool} -> self'
|
319
|
+
RDL.type :Hash, :select!, '() {(``any_or_k(trec)``,``any_or_v(trec)``) -> %bool} -> self'
|
320
|
+
RDL.type :Hash, :shift, '() -> ``shift_output(trec)``'
|
321
|
+
|
322
|
+
|
323
|
+
def Hash.shift_output(trec)
|
324
|
+
case trec
|
325
|
+
when RDL::Type::FiniteHashType
|
326
|
+
promoted = trec.promote
|
327
|
+
RDL::Type::TupleType.new(*promoted.params) ## Type error found by type checker here.
|
328
|
+
else
|
329
|
+
RDL::Globals.parser.scan_str "#T [k, v]"
|
330
|
+
end
|
331
|
+
end
|
332
|
+
RDL.type Hash, 'self.shift_output', "(RDL::Type::Type) -> RDL::Type::Type", typecheck: :type_code, wrap: false, effect: [:+, :+]
|
333
|
+
|
334
|
+
RDL.type :Hash, :to_a, '() -> ``output_type(trec, targs, :to_a, "Array<[k, v]>")``'
|
335
|
+
RDL.type :Hash, :to_hash, '() -> self'
|
336
|
+
RDL.type :Hash, :values, '() -> ``output_type(trec, targs, :values, "Array<v>")``'
|
337
|
+
RDL.type :Hash, :values_at, '(``values_at_input(trec)``) -> ``values_at_output(trec, targs)``'
|
338
|
+
|
339
|
+
|
340
|
+
def Hash.values_at_input(trec)
|
341
|
+
case trec
|
342
|
+
when RDL::Type::FiniteHashType
|
343
|
+
RDL::Type::VarargType.new(RDL::Globals.types[:top])
|
344
|
+
else
|
345
|
+
RDL::Type::VarargType.new(RDL::Type::VarType.new("k"))
|
346
|
+
end
|
347
|
+
end
|
348
|
+
RDL.type Hash, 'self.values_at_input', "(RDL::Type::Type) -> RDL::Type::Type", typecheck: :type_code, wrap: false, effect: [:~, :+]
|
349
|
+
|
350
|
+
|
351
|
+
def Hash.values_at_output(trec, targs)
|
352
|
+
case trec
|
353
|
+
when RDL::Type::FiniteHashType
|
354
|
+
if targs.all? { |t| t.is_a? RDL::Type::SingletonType }
|
355
|
+
res = trec.elts.values_at(*targs.map { |t| RDL.type_cast(t, "RDL::Type::SingletonType<%any>", force: true).val })
|
356
|
+
if res.all? { |t| !t.nil? }
|
357
|
+
to_type(res)
|
358
|
+
else
|
359
|
+
RDL::Type::GenericType.new(RDL::Type::NominalType.new(Array), trec.promote.params[1])
|
360
|
+
end
|
361
|
+
else
|
362
|
+
RDL::Type::GenericType.new(RDL::Type::NominalType.new(Array), trec.promote.params[1])
|
363
|
+
end
|
364
|
+
else
|
365
|
+
RDL::Globals.parser.scan_str "#T Array<v>"
|
366
|
+
end
|
367
|
+
end
|
368
|
+
RDL.type Hash, 'self.values_at_output', "(RDL::Type::Type, Array<RDL::Type::Type>) -> RDL::Type::Type", typecheck: :type_code, wrap: false, effect: [:~, :+]
|
369
|
+
|
370
|
+
|
371
|
+
|
372
|
+
|
373
|
+
|
374
|
+
######### Non-dependent types below #########
|
375
|
+
|
376
|
+
RDL.type :Hash, 'self.[]', '(*u) -> Hash<u, u>', effect: [:+, :+] # example: Hash[1,2,3,4]
|
377
|
+
RDL.type :Hash, 'self.[]', '(Array<[a,b]>) -> Hash<a, b>', effect: [:+, :+]
|
378
|
+
RDL.type :Hash, 'self.[]', '([to_hash: () -> Hash<a, b>]) -> Hash<a, b>', effect: [:+, :+]
|
8
379
|
|
9
380
|
RDL.type :Hash, :[], '(k) -> v'
|
10
|
-
RDL.type :Hash, :[]=, '(k, v) -> v'
|
381
|
+
RDL.type :Hash, :[]=, '(k, v) -> v', effect: [:-, :+]
|
11
382
|
RDL.type :Hash, :store, '(k,v) -> v'
|
12
383
|
|
384
|
+
RDL.type :Hash, :any?, "() { (k, v) -> %any } -> %bool", effect: [:blockdep, :blockdep]
|
13
385
|
# RDL.type :Hash, :assoc, '(k) -> [k, v]' # TODO
|
14
386
|
RDL.type :Hash, :assoc, '(k) -> Array<k or v>'
|
15
387
|
RDL.type :Hash, :clear, '() -> Hash<k,v>'
|
@@ -27,41 +399,44 @@ RDL.type :Hash, :delete, '(k) -> v'
|
|
27
399
|
RDL.type :Hash, :delete, '(k) { (k) -> u } -> u or v'
|
28
400
|
RDL.type :Hash, :delete_if, '() { (k,v) -> %bool } -> Hash<k,v>'
|
29
401
|
RDL.type :Hash, :delete_if, '() -> Enumerator<[k, v]>'
|
30
|
-
RDL.type :Hash, :each, '() { (k,v) -> %any } -> Hash<k,v>'
|
31
|
-
RDL.type :Hash, :each, '() -> Enumerator<[k, v]>'
|
402
|
+
RDL.type :Hash, :each, '() { (k,v) -> %any } -> Hash<k,v>', effect: [:blockdep, :blockdep]
|
403
|
+
RDL.type :Hash, :each, '() -> Enumerator<[k, v]>', effect: [:blockdep, :blockdep]
|
32
404
|
RDL.type :Hash, :each_pair, '() { (k,v) -> %any } -> Hash<k,v>'
|
33
405
|
RDL.type :Hash, :each_pair, '() -> Enumerator<[k, v]>'
|
34
|
-
RDL.type :Hash, :each_key, '() { (k) -> %any } -> Hash<k,v>'
|
35
|
-
RDL.type :Hash, :each_key, '() -> Enumerator<[k, v]>'
|
406
|
+
RDL.type :Hash, :each_key, '() { (k) -> %any } -> Hash<k,v>', effect: [:blockdep, :blockdep]
|
407
|
+
RDL.type :Hash, :each_key, '() -> Enumerator<[k, v]>', effect: [:blockdep, :blockdep]
|
36
408
|
RDL.type :Hash, :each_value, '() { (v) -> %any } -> Hash<k,v>'
|
37
409
|
RDL.type :Hash, :each_value, '() -> Enumerator<[k, v]>'
|
38
410
|
RDL.type :Hash, :empty?, '() -> %bool'
|
411
|
+
RDL.type :Hash, :except, '(%any) -> self', effect: [:+, :+]
|
39
412
|
RDL.type :Hash, :fetch, '(k) -> v'
|
40
413
|
RDL.type :Hash, :fetch, '(k,u) -> u or v'
|
41
414
|
RDL.type :Hash, :fetch, '(k) { (k) -> u } -> u or v'
|
415
|
+
RDL.type :Hash, :map, "() { (k, v) -> x } -> Array<x>", effect: [:+, :blockdep]
|
42
416
|
RDL.type :Hash, :member?, '(t) -> %bool'
|
43
417
|
RDL.type :Hash, :has_key?, '(t) -> %bool'
|
44
418
|
RDL.type :Hash, :key?, '(t) -> %bool'
|
45
419
|
RDL.type :Hash, :has_value?, '(t) -> %bool'
|
46
420
|
RDL.type :Hash, :value?, '(t) -> %bool'
|
47
421
|
RDL.type :Hash, :to_s, '() -> String'
|
422
|
+
RDL.type :Hash, :include?, '(%any) -> %bool', effect: [:+, :+]
|
48
423
|
RDL.type :Hash, :inspect, '() -> String'
|
49
|
-
RDL.type :Hash, :invert, '() -> Hash<v,k>'
|
424
|
+
RDL.type :Hash, :invert, '() -> Hash<v,k>', effect: [:+, :+]
|
50
425
|
RDL.type :Hash, :keep_if, '() { (k,v) -> %bool } -> Hash<k,v>'
|
51
426
|
RDL.type :Hash, :keep_if, '() -> Enumerator<[k, v]>'
|
52
427
|
RDL.type :Hash, :key, '(t) -> k'
|
53
|
-
RDL.type :Hash, :keys, '() -> Array<k>'
|
428
|
+
RDL.type :Hash, :keys, '() -> Array<k>', effect: [:+, :+]
|
54
429
|
RDL.type :Hash, :length, '() -> Integer'
|
55
|
-
RDL.type :Hash, :size, '() -> Integer'
|
56
|
-
RDL.type :Hash, :merge, '(Hash<a,b>) -> Hash<a or k, b or v>'
|
57
|
-
RDL.type :Hash, :merge, '(Hash<a,b>) { (k,v,b) -> v or b } -> Hash<a or k, b or v>'
|
430
|
+
RDL.type :Hash, :size, '() -> Integer', effect: [:+, :+]
|
431
|
+
RDL.type :Hash, :merge, '(Hash<a,b>) -> Hash<a or k, b or v>', effect: [:+, :+]
|
432
|
+
RDL.type :Hash, :merge, '(Hash<a,b>) { (k,v,b) -> v or b } -> Hash<a or k, b or v>', effect: [:+, :+]
|
58
433
|
# RDL.type :Hash, :rassoc, '(k) -> Tuple<k,v>'
|
59
434
|
RDL.type :Hash, :rassoc, '(k) -> Array<k or v>'
|
60
435
|
RDL.type :Hash, :rehash, '() -> Hash<k,v>'
|
61
436
|
RDL.type :Hash, :reject, '() -> Enumerator<[k, v]>'
|
62
437
|
RDL.type :Hash, :reject, '() {(k,v) -> %bool} -> Hash<k,v>'
|
63
438
|
RDL.type :Hash, :reject!, '() {(k,v) -> %bool} -> Hash<k,v>'
|
64
|
-
RDL.type :Hash, :select, '() {(k,v) -> %bool} -> Hash<k,v>'
|
439
|
+
RDL.type :Hash, :select, '() {(k,v) -> %bool} -> Hash<k,v>', effect: [:+, :blockdep]
|
65
440
|
RDL.type :Hash, :select!, '() {(k,v) -> %bool} -> Hash<k,v>'
|
66
441
|
# RDL.type :Hash, :shift, '() -> Tuple<k,v>'
|
67
442
|
RDL.type :Hash, :shift, '() -> Array<k or v>'
|
@@ -69,4 +444,4 @@ RDL.type :Hash, :shift, '() -> Array<k or v>'
|
|
69
444
|
RDL.type :Hash, :to_a, '() -> Array<Array<k or v>>'
|
70
445
|
RDL.type :Hash, :to_hash, '() -> Hash<k,v>'
|
71
446
|
RDL.type :Hash, :values, '() -> Array<v>'
|
72
|
-
RDL.type :Hash, :values_at, '(*k) -> Array<v>'
|
447
|
+
RDL.type :Hash, :values_at, '(*k) -> Array<v>', effect: [:+, :+]
|