finitio 0.7.0.pre.rc4 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +42 -0
  3. data/Gemfile +1 -11
  4. data/Gemfile.lock +101 -54
  5. data/README.md +89 -13
  6. data/finitio.gemspec +9 -157
  7. data/lib/finitio.rb +7 -5
  8. data/lib/finitio/generation.rb +106 -0
  9. data/lib/finitio/generation/ad_type.rb +10 -0
  10. data/lib/finitio/generation/alias_type.rb +9 -0
  11. data/lib/finitio/generation/any_type.rb +11 -0
  12. data/lib/finitio/generation/builtin_type.rb +9 -0
  13. data/lib/finitio/generation/hash_based_type.rb +15 -0
  14. data/lib/finitio/generation/heuristic.rb +8 -0
  15. data/lib/finitio/generation/heuristic/constant.rb +30 -0
  16. data/lib/finitio/generation/heuristic/random.rb +52 -0
  17. data/lib/finitio/generation/rel_based_type.rb +13 -0
  18. data/lib/finitio/generation/seq_type.rb +13 -0
  19. data/lib/finitio/generation/set_type.rb +13 -0
  20. data/lib/finitio/generation/sub_type.rb +9 -0
  21. data/lib/finitio/generation/union_type.rb +10 -0
  22. data/lib/finitio/inference.rb +51 -0
  23. data/lib/finitio/json_schema.rb +16 -0
  24. data/lib/finitio/json_schema/ad_type.rb +11 -0
  25. data/lib/finitio/json_schema/alias_type.rb +9 -0
  26. data/lib/finitio/json_schema/any_type.rb +9 -0
  27. data/lib/finitio/json_schema/builtin_type.rb +27 -0
  28. data/lib/finitio/json_schema/hash_based_type.rb +25 -0
  29. data/lib/finitio/json_schema/rel_based_type.rb +13 -0
  30. data/lib/finitio/json_schema/seq_type.rb +12 -0
  31. data/lib/finitio/json_schema/set_type.rb +13 -0
  32. data/lib/finitio/json_schema/struct_type.rb +12 -0
  33. data/lib/finitio/json_schema/sub_type.rb +10 -0
  34. data/lib/finitio/json_schema/union_type.rb +11 -0
  35. data/lib/finitio/support.rb +18 -0
  36. data/lib/finitio/support/attribute.rb +8 -0
  37. data/lib/finitio/support/compilation.rb +18 -18
  38. data/lib/finitio/support/contract.rb +10 -2
  39. data/lib/finitio/support/fetch_scope.rb +19 -0
  40. data/lib/finitio/support/heading.rb +42 -1
  41. data/lib/finitio/syntax.rb +1 -1
  42. data/lib/finitio/syntax/lexer.citrus +1 -1
  43. data/lib/finitio/syntax/type.rb +2 -0
  44. data/lib/finitio/syntax/type/high_order_type_instantiation.rb +29 -0
  45. data/lib/finitio/syntax/type/high_order_vars.rb +16 -0
  46. data/lib/finitio/syntax/type/type_def.rb +11 -1
  47. data/lib/finitio/syntax/types.citrus +14 -1
  48. data/lib/finitio/system.rb +18 -4
  49. data/lib/finitio/type.rb +19 -0
  50. data/lib/finitio/type/ad_type.rb +9 -1
  51. data/lib/finitio/type/alias_type.rb +8 -0
  52. data/lib/finitio/type/any_type.rb +12 -0
  53. data/lib/finitio/type/builtin_type.rb +4 -0
  54. data/lib/finitio/type/collection_type.rb +15 -0
  55. data/lib/finitio/type/heading_based_type.rb +17 -0
  56. data/lib/finitio/type/high_order_type.rb +39 -0
  57. data/lib/finitio/type/multi_relation_type.rb +4 -0
  58. data/lib/finitio/type/multi_tuple_type.rb +4 -0
  59. data/lib/finitio/type/proxy_type.rb +10 -20
  60. data/lib/finitio/type/relation_type.rb +4 -0
  61. data/lib/finitio/type/seq_type.rb +1 -1
  62. data/lib/finitio/type/struct_type.rb +8 -0
  63. data/lib/finitio/type/sub_type.rb +8 -0
  64. data/lib/finitio/type/tuple_type.rb +4 -0
  65. data/lib/finitio/type/union_type.rb +19 -0
  66. data/lib/finitio/version.rb +2 -2
  67. data/spec/finitio/test_system.rb +0 -11
  68. data/spec/generation/test_generation.rb +169 -0
  69. data/spec/heading/test_looks_similar.rb +45 -0
  70. data/spec/heading/test_suppremum.rb +56 -0
  71. data/spec/inference/test_inference.rb +42 -0
  72. data/spec/json_schema/test_ad_type.rb +20 -0
  73. data/spec/json_schema/test_alias_type.rb +15 -0
  74. data/spec/json_schema/test_any_type.rb +11 -0
  75. data/spec/json_schema/test_builtin_type.rb +51 -0
  76. data/spec/json_schema/test_multi_relation_type.rb +58 -0
  77. data/spec/json_schema/test_multi_tuple_type.rb +50 -0
  78. data/spec/json_schema/test_relation_type.rb +30 -0
  79. data/spec/json_schema/test_seq_type.rb +18 -0
  80. data/spec/json_schema/test_set_type.rb +19 -0
  81. data/spec/json_schema/test_struct_type.rb +18 -0
  82. data/spec/json_schema/test_sub_type.rb +17 -0
  83. data/spec/json_schema/test_tuple_type.rb +26 -0
  84. data/spec/json_schema/test_union_type.rb +17 -0
  85. data/spec/regression/test_heading_extra_are_proxy_resolved.rb +41 -0
  86. data/spec/spec_helper.rb +32 -6
  87. data/spec/support/test_compare_attrs.rb +67 -0
  88. data/spec/syntax/test_compile.rb +57 -0
  89. data/spec/system/fixtures/system.fio +2 -0
  90. data/spec/{finitio → system/fixtures}/with-duplicates.fio +2 -1
  91. data/spec/system/test_check_and_warn.rb +55 -0
  92. data/spec/type/ad_type/test_initialize.rb +1 -8
  93. data/spec/type/relation_type/test_suppremum.rb +104 -0
  94. data/spec/type/seq_type/test_suppremum.rb +54 -0
  95. data/spec/type/set_type/test_suppremum.rb +54 -0
  96. data/spec/type/test_suppremum.rb +49 -0
  97. data/spec/type/test_unconstrained.rb +150 -0
  98. data/spec/type/tuple_type/test_suppremum.rb +119 -0
  99. data/spec/type/union_type/test_suppremum.rb +51 -0
  100. data/tasks/test.rake +1 -1
  101. metadata +203 -17
  102. data/spec/type/proxy_type/test_delegation.rb +0 -37
  103. data/spec/type/proxy_type/test_resolve.rb +0 -29
@@ -0,0 +1,16 @@
1
+ module Finitio
2
+ module Syntax
3
+ module HighOrderVars
4
+ include Node
5
+
6
+ def compile(system)
7
+ captures[:type_name].map{|c| c.to_s }
8
+ end
9
+
10
+ def to_ast(var_name)
11
+ [ :high_order_vars, captures[:type_name].map{|c| c.to_s } ]
12
+ end
13
+
14
+ end # module HighOrderVars
15
+ end # module Syntax
16
+ end # module Finitio
@@ -5,9 +5,19 @@ module Finitio
5
5
 
6
6
  capture :type
7
7
  capture :type_name
8
+ capture :vars
8
9
 
9
10
  def compile(system)
10
- t = type.compile(system)
11
+ if vars
12
+ vs = vars.compile(system)
13
+ overrides = Hash[vs.map{|v|
14
+ [ v.to_s, ProxyType.new(v) ]
15
+ }]
16
+ t = type.compile(system.with_scope(overrides))
17
+ t = HighOrderType.new(vs, t)
18
+ else
19
+ t = type.compile(system)
20
+ end
11
21
  n = type_name && type_name.to_str
12
22
  m = metadata
13
23
  system.add_type(t, n, m)
@@ -6,10 +6,15 @@ grammar Finitio::Syntax::Types
6
6
  include Finitio::Syntax::Literals
7
7
 
8
8
  rule type_def
9
- (metadata? type_name equal type)
9
+ (metadata? type_name ('<' vars:high_order_vars '>')? equal type)
10
10
  <Finitio::Syntax::TypeDef>
11
11
  end
12
12
 
13
+ rule high_order_vars
14
+ (type_name (comma type_name)*)
15
+ <Finitio::Syntax::HighOrderVars>
16
+ end
17
+
13
18
  rule main_type
14
19
  (metadata? type)
15
20
  <Finitio::Syntax::MainType>
@@ -58,6 +63,7 @@ grammar Finitio::Syntax::Types
58
63
  rule rel_type
59
64
  relation_type
60
65
  | tuple_type
66
+ | high_order_type_instantiation
61
67
  | collection_type
62
68
  end
63
69
 
@@ -110,6 +116,13 @@ grammar Finitio::Syntax::Types
110
116
  <Finitio::Syntax::StructType>
111
117
  end
112
118
 
119
+ # high-order types
120
+
121
+ rule high_order_type_instantiation
122
+ (high:type_name '<' vars:high_order_vars '>')
123
+ <Finitio::Syntax::HighOrderTypeInstantiation>
124
+ end
125
+
113
126
  # terminal forms
114
127
 
115
128
  rule term_type
@@ -10,7 +10,7 @@ module Finitio
10
10
  end
11
11
 
12
12
  attr_reader :types, :imports
13
- private :types, :imports
13
+ private :imports
14
14
 
15
15
  def add_import(system)
16
16
  @imports << system
@@ -89,6 +89,16 @@ module Finitio
89
89
  Syntax.compile(source, self.dup)
90
90
  end
91
91
 
92
+ def resolve_proxies(recurse = true)
93
+ rebuilt = {}
94
+ scope = FetchScope.new(self, rebuilt)
95
+ types.each_with_object(rebuilt) do |(name,type),memo|
96
+ rebuilt[name] = type.resolve_proxies(scope)
97
+ end
98
+ resolved = System.new(rebuilt, imports)
99
+ recurse ? resolved.resolve_proxies(false) : resolved
100
+ end
101
+
92
102
  def inspect
93
103
  @types.each_pair.map{|k,v| "#{k} = #{v}" }.join("\n")
94
104
  end
@@ -97,16 +107,20 @@ module Finitio
97
107
  System.new(@types.dup, @imports.dup)
98
108
  end
99
109
 
100
- def check_and_warn(io = STDERR)
110
+ def check_and_warn(logger = nil)
111
+ logger ||= begin
112
+ require 'logger'
113
+ Logger.new(STDERR)
114
+ end
101
115
  each_type do |t|
102
116
  next unless t.named?
103
117
  each_import do |i|
104
118
  next unless found = i.get_type(t.name)
105
119
  if found == t
106
- STDERR.puts "WARN: duplicate type def `#{t.name}`"
120
+ logger.info "Duplicate type def `#{t.name}`"
107
121
  break
108
122
  else
109
- STDERR.puts "NOTICE: Type erasure `#{t.name}`"
123
+ logger.warn "Type erasure `#{t.name}`"
110
124
  break
111
125
  end
112
126
  end
@@ -54,6 +54,20 @@ module Finitio
54
54
  raise NotImplementedError, "Missing #{self.class.name}#dress"
55
55
  end
56
56
 
57
+ def suppremum(other)
58
+ return self if other == self
59
+ other._suppremum(self)
60
+ end
61
+
62
+ def _suppremum(other)
63
+ UnionType.new([other, self])
64
+ end
65
+ protected :_suppremum
66
+
67
+ def unconstrained
68
+ self
69
+ end
70
+
57
71
  def to_s
58
72
  name.to_s
59
73
  end
@@ -64,6 +78,10 @@ module Finitio
64
78
  }
65
79
  end
66
80
 
81
+ def resolve_proxies(system)
82
+ raise NotImplementedError, "resolve_proxies must be overriden"
83
+ end
84
+
67
85
  protected
68
86
 
69
87
  def set_equal?(s1, s2)
@@ -94,3 +112,4 @@ require_relative 'type/multi_tuple_type'
94
112
  require_relative 'type/relation_type'
95
113
  require_relative 'type/multi_relation_type'
96
114
  require_relative 'type/ad_type'
115
+ require_relative 'type/high_order_type'
@@ -132,7 +132,7 @@ module Finitio
132
132
  end
133
133
 
134
134
  def hash
135
- [ ruby_type, contracts ].hash
135
+ ruby_type.hash ^ contracts.hash
136
136
  end
137
137
 
138
138
  def ==(other)
@@ -144,5 +144,13 @@ module Finitio
144
144
  end
145
145
  alias :eql? :==
146
146
 
147
+ def resolve_proxies(system)
148
+ AdType.new(ruby_type, contracts.map{|t| t.resolve_proxies(system)}, name, metadata)
149
+ end
150
+
151
+ def unconstrained
152
+ AdType.new(ruby_type, contracts.map{|c| c.unconstrained}, name, metadata)
153
+ end
154
+
147
155
  end # class AdType
148
156
  end # module Finitio
@@ -33,5 +33,13 @@ module Finitio
33
33
  end
34
34
  end
35
35
 
36
+ def resolve_proxies(system)
37
+ AliasType.new(target.resolve_proxies(system), name, metadata)
38
+ end
39
+
40
+ def unconstrained
41
+ AliasType.new(target.unconstrained, name, metadata)
42
+ end
43
+
36
44
  end # class AliasType
37
45
  end # module Finitio
@@ -38,6 +38,14 @@ module Finitio
38
38
  value
39
39
  end
40
40
 
41
+ def suppremum(other)
42
+ self
43
+ end
44
+
45
+ def _suppremum(other)
46
+ self
47
+ end
48
+
41
49
  def ==(other)
42
50
  super || other.is_a?(AnyType)
43
51
  end
@@ -47,5 +55,9 @@ module Finitio
47
55
  self.class.hash ^ 37
48
56
  end
49
57
 
58
+ def resolve_proxies(system)
59
+ self
60
+ end
61
+
50
62
  end # class AnyType
51
63
  end # module Finitio
@@ -53,5 +53,9 @@ module Finitio
53
53
  self.class.hash ^ ruby_type.hash
54
54
  end
55
55
 
56
+ def resolve_proxies(system)
57
+ self
58
+ end
59
+
56
60
  end # class BuiltinType
57
61
  end # module Finitio
@@ -20,5 +20,20 @@ module Finitio
20
20
  self.class.hash ^ self.elm_type.hash
21
21
  end
22
22
 
23
+ def suppremum(other)
24
+ return super unless other.is_a?(CollectionType)
25
+ return self if other.is_a?(CollectionType) && elm_type == other.elm_type
26
+ builder = self.class == other.class ? self.class : SeqType
27
+ builder.new(elm_type.suppremum(other.elm_type))
28
+ end
29
+
30
+ def resolve_proxies(system)
31
+ self.class.new(elm_type.resolve_proxies(system), name, metadata)
32
+ end
33
+
34
+ def unconstrained
35
+ self.class.new(elm_type.unconstrained, name, metadata)
36
+ end
37
+
23
38
  end # module CollectionType
24
39
  end # module Finitio
@@ -15,6 +15,15 @@ module Finitio
15
15
  heading.fetch(attrname)
16
16
  end
17
17
 
18
+ def suppremum(other, simple_class, multi_class)
19
+ return self if self == other
20
+ return super(other) unless other.is_a?(simple_class) or other.is_a?(multi_class)
21
+ return super(other) unless heading.looks_similar?(other.heading)
22
+ result_heading = heading.suppremum(other.heading)
23
+ builder = result_heading.multi? ? multi_class : simple_class
24
+ builder.new(result_heading)
25
+ end
26
+
18
27
  def ==(other)
19
28
  super || (other.is_a?(self.class) && heading == other.heading)
20
29
  end
@@ -24,5 +33,13 @@ module Finitio
24
33
  self.class.hash ^ heading.hash
25
34
  end
26
35
 
36
+ def resolve_proxies(system)
37
+ self.class.new(heading.resolve_proxies(system), name, metadata)
38
+ end
39
+
40
+ def unconstrained
41
+ self.class.new(heading.unconstrained, name, metadata)
42
+ end
43
+
27
44
  end # module HeadingBasedType
28
45
  end # module Finitio
@@ -0,0 +1,39 @@
1
+ module Finitio
2
+ class HighOrderType < Type
3
+
4
+ def initialize(vars, defn, name = nil, metadata = nil)
5
+ super(name, metadata)
6
+ @vars = vars
7
+ @defn = defn
8
+ end
9
+ attr_reader :vars, :defn
10
+
11
+ def default_name
12
+ "Type<#{vars.join(',')}>"
13
+ end
14
+
15
+ def suppremum(other)
16
+ raise NotImplementedError, "Suppremum is not defined on high order types"
17
+ end
18
+
19
+ def ==(other)
20
+ super || other.is_a?(HighOrderType) \
21
+ && other.vars == self.vars \
22
+ && other.defn = self.defn
23
+ end
24
+
25
+ def resolve_proxies(system)
26
+ self
27
+ end
28
+
29
+ def instantiate(compilation, sub_types)
30
+ overrides = Hash[vars.zip(sub_types)]
31
+ defn.resolve_proxies(compilation.with_scope(overrides))
32
+ end
33
+
34
+ def unconstrained
35
+ HighOrderType.new(vars, defn.unconstrained, name, metadata)
36
+ end
37
+
38
+ end # class HighOrderType
39
+ end # module Finitio
@@ -30,5 +30,9 @@ module Finitio
30
30
  "{{#{heading.to_name}}}"
31
31
  end
32
32
 
33
+ def suppremum(other)
34
+ super(other, RelationType, MultiRelationType)
35
+ end
36
+
33
37
  end # class MultiRelationType
34
38
  end # module Finitio
@@ -25,5 +25,9 @@ module Finitio
25
25
  "{#{heading.to_name}}"
26
26
  end
27
27
 
28
+ def suppremum(other)
29
+ super(other, TupleType, MultiTupleType)
30
+ end
31
+
28
32
  end # class MultiTupleType
29
33
  end # module Finitio
@@ -11,30 +11,20 @@ module Finitio
11
11
  end
12
12
  attr_reader :target_name, :target
13
13
 
14
- [
15
- :representator,
16
- :name,
17
- :name=,
18
- :default_name,
19
- :dress,
20
- :undress,
21
- :include?,
22
- :==,
23
- :eql?,
24
- :hash,
25
- :to_s
26
- ].each do |meth|
27
- define_method(meth) do |*args, &bl|
28
- raise Error, "No such type `#{@target_name}` (proxy not resolved?)" unless @target
29
- @target.send(meth, *args, &bl)
30
- end
14
+ def default_name
15
+ "_#{target_name}_"
31
16
  end
32
17
 
33
- def resolve(system)
34
- @target = system.fetch(target_name){
35
- raise Error, "No such type `#{target_name}`"
18
+ def resolve_proxies(system)
19
+ system.fetch(target_name){
20
+ raise Error, "No such type `#{target_name}` in #{system}"
36
21
  }
37
22
  end
38
23
 
24
+ def unconstrained
25
+ return @target.unconstrained if @target
26
+ raise Error, "`unconstrained` cannot be call whithout proxies being resolved"
27
+ end
28
+
39
29
  end # class ProxyType
40
30
  end # module Finitio
@@ -36,5 +36,9 @@ module Finitio
36
36
  "{{#{heading.to_name}}}"
37
37
  end
38
38
 
39
+ def suppremum(other)
40
+ super(other, RelationType, MultiRelationType)
41
+ end
42
+
39
43
  end # class RelationType
40
44
  end # module Finitio
@@ -27,7 +27,7 @@ module Finitio
27
27
  include CollectionType
28
28
 
29
29
  def representator
30
- [elmType]
30
+ [elm_type]
31
31
  end
32
32
 
33
33
  def include?(value)
@@ -80,5 +80,13 @@ module Finitio
80
80
  self.class.hash ^ component_types.hash
81
81
  end
82
82
 
83
+ def resolve_proxies(system)
84
+ StructType.new(component_types.map{|t| t.resolve_proxies(system)}, name, metadata)
85
+ end
86
+
87
+ def unconstrained
88
+ StructType.new(component_types.map{|t| t.unconstrained}, name, metadata)
89
+ end
90
+
83
91
  end # class StructType
84
92
  end # module Finitio
@@ -81,6 +81,10 @@ module Finitio
81
81
  uped
82
82
  end
83
83
 
84
+ def unconstrained
85
+ super_type.unconstrained
86
+ end
87
+
84
88
  def ==(other)
85
89
  super || (
86
90
  other.is_a?(SubType) && (other.super_type == super_type) &&
@@ -93,5 +97,9 @@ module Finitio
93
97
  self.class.hash ^ super_type.hash ^ set_hash(constraints)
94
98
  end
95
99
 
100
+ def resolve_proxies(system)
101
+ SubType.new(super_type.resolve_proxies(system), constraints, name, metadata)
102
+ end
103
+
96
104
  end # class SubType
97
105
  end # module Finitio