finitio 0.11.2 → 0.11.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/Gemfile.lock +1 -1
- data/lib/finitio/generation/proxy_type.rb +11 -0
- data/lib/finitio/generation.rb +1 -0
- data/lib/finitio/json_schema/hash_based_type.rb +1 -1
- data/lib/finitio/json_schema/proxy_type.rb +4 -1
- data/lib/finitio/support/compilation.rb +0 -4
- data/lib/finitio/support/proxy_resolver.rb +52 -0
- data/lib/finitio/support.rb +1 -0
- data/lib/finitio/syntax.rb +4 -4
- data/lib/finitio/system.rb +5 -16
- data/lib/finitio/type/high_order_type.rb +3 -1
- data/lib/finitio/type/proxy_type.rb +19 -1
- data/lib/finitio/type.rb +4 -2
- data/lib/finitio/version.rb +1 -1
- data/spec/inference/test_inference.rb +1 -1
- data/spec/json_schema/test_recursive_type.rb +38 -0
- data/spec/regression/test_dress_on_recursive_type.rb +53 -0
- data/spec/regression/test_name_of_generic_types.rb +18 -0
- data/spec/syntax/test_compile.rb +19 -1
- metadata +10 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 29fd883abee1e98b436a1c8aa80ee32ffc9740dc
|
|
4
|
+
data.tar.gz: 9aa135c687855dbdfb6a52e245d21c3488ef0128
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0af6653c37bc1fdb2e5aeef7f0d43e70f92d967658219b638c58a8039b975460f64ab80339d7d727aed716175cc722614973e387c5720315868bd6b8a6d1fc7c
|
|
7
|
+
data.tar.gz: ef96c4bd3a7f4910b83acab224940afe7a1885be98eeddf5ce8542c0037d0c702da98e372f55a42638cb7cef3cfbf9394dd8c0d162daace35c6731e86083c061
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
# 0.11.4 - 2023/01/06
|
|
2
|
+
|
|
3
|
+
* The proxy resolution is fixed and clarified. When compiling
|
|
4
|
+
a system, all proxies are actually replaced by their actual
|
|
5
|
+
Type instance. Only recursive types still keep ProxyType
|
|
6
|
+
instances (as sentinels) ; they are bound to their target
|
|
7
|
+
type and delete dress and include? to them.
|
|
8
|
+
|
|
9
|
+
Given that ProxyType is a sentinel on recursive types, calls
|
|
10
|
+
to generate_data and to_json_schema are not delegated to the
|
|
11
|
+
target type, to avoid infinite recursions.
|
|
12
|
+
|
|
13
|
+
* Generated names of instantiated high order types are better
|
|
14
|
+
(e.g. Collection<String>).
|
|
15
|
+
|
|
16
|
+
# 0.11.3 - 2023/01/06
|
|
17
|
+
|
|
18
|
+
* Fix json_schema generation on unresolved ProxyTypes. We use
|
|
19
|
+
"object" by default, waiting for a better support for recursive
|
|
20
|
+
types.
|
|
21
|
+
|
|
1
22
|
# 0.11.2 - 2023/01/06
|
|
2
23
|
|
|
3
24
|
* Fix json_schema generation on builtin_type NilClass. "null"
|
data/Gemfile.lock
CHANGED
data/lib/finitio/generation.rb
CHANGED
|
@@ -7,7 +7,7 @@ module Finitio
|
|
|
7
7
|
}
|
|
8
8
|
unless heading.empty?
|
|
9
9
|
base[:properties] = heading.inject({}){|ps,a|
|
|
10
|
-
|
|
10
|
+
ps.merge(a.name => a.type.to_json_schema(*args, &bl))
|
|
11
11
|
}
|
|
12
12
|
end
|
|
13
13
|
unless (reqs = heading.select{|a| a.required? }).empty?
|
|
@@ -2,7 +2,10 @@ module Finitio
|
|
|
2
2
|
class ProxyType
|
|
3
3
|
|
|
4
4
|
def to_json_schema(*args, &bl)
|
|
5
|
-
|
|
5
|
+
# ProxyType is supposed to be used only for recursive types.
|
|
6
|
+
# We don't have support for references yet, so let just
|
|
7
|
+
# generate an object here in the mean time.
|
|
8
|
+
{ type: "object" }
|
|
6
9
|
end
|
|
7
10
|
|
|
8
11
|
end # module ProxyType
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Finitio
|
|
2
|
+
# Part of the compilation schema, this proxy resolver replaces
|
|
3
|
+
# proxies by their real Type instance.
|
|
4
|
+
#
|
|
5
|
+
# Given that Finitio can support recursive types, we do this in
|
|
6
|
+
# two passes:
|
|
7
|
+
# 1. Replace proxy types by rewrite (see Type#resolve_proxies)
|
|
8
|
+
# in a depth first search.
|
|
9
|
+
# 2. If a loop is found, recreate a late ProxyType, that is then
|
|
10
|
+
# bound later by mutation.
|
|
11
|
+
#
|
|
12
|
+
# So ProxyType may still be present in the type chain, but will
|
|
13
|
+
# only correspond to recursive types.
|
|
14
|
+
class ProxyResolver
|
|
15
|
+
def resolve!(system)
|
|
16
|
+
@system = system
|
|
17
|
+
@built = {}
|
|
18
|
+
@building = {}
|
|
19
|
+
@late_proxies = []
|
|
20
|
+
system.types.each_key do |name|
|
|
21
|
+
fetch(name)
|
|
22
|
+
end
|
|
23
|
+
@late_proxies.each do |proxy|
|
|
24
|
+
proxy.bind!(self)
|
|
25
|
+
end
|
|
26
|
+
system.dup(@built)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def fetch(name, &bl)
|
|
30
|
+
@built[name] || build_it(name) || import_it(name, &bl)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def build_it(name)
|
|
34
|
+
if under_build = @building[name]
|
|
35
|
+
proxy = ProxyType.new(name)
|
|
36
|
+
@late_proxies << proxy
|
|
37
|
+
proxy
|
|
38
|
+
else
|
|
39
|
+
return nil unless type = @system.fetch(name, false){ nil }
|
|
40
|
+
|
|
41
|
+
@building[name] = type
|
|
42
|
+
@built[name] = type.resolve_proxies(self)
|
|
43
|
+
@building[name] = nil
|
|
44
|
+
@built[name]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def import_it(name, &bl)
|
|
49
|
+
@system.fetch_on_imports(name, &bl)
|
|
50
|
+
end
|
|
51
|
+
end # class ProxyResolver
|
|
52
|
+
end # module Finitio
|
data/lib/finitio/support.rb
CHANGED
data/lib/finitio/syntax.rb
CHANGED
|
@@ -21,18 +21,18 @@ module Finitio
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def self.ast(source)
|
|
24
|
-
parse(source, root:
|
|
24
|
+
parse(source, root: 'system').to_ast
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def self.compile(source, cpl = nil)
|
|
28
28
|
cpl = Compilation.coerce(cpl, source)
|
|
29
|
-
parse(source, root:
|
|
30
|
-
cpl.
|
|
29
|
+
parse(source, root: 'system').compile(cpl)
|
|
30
|
+
ProxyResolver.new.resolve!(cpl.system)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def self.compile_type(source, cpl = nil)
|
|
34
34
|
cpl = Compilation.coerce(cpl, source)
|
|
35
|
-
parse(source, root:
|
|
35
|
+
parse(source, root: 'type').compile(cpl)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
end # module Syntax
|
data/lib/finitio/system.rb
CHANGED
|
@@ -50,24 +50,23 @@ module Finitio
|
|
|
50
50
|
def fetch(name, with_imports = true, &bl)
|
|
51
51
|
if with_imports
|
|
52
52
|
@types.fetch(name) do
|
|
53
|
-
|
|
53
|
+
fetch_on_imports(name, &bl)
|
|
54
54
|
end
|
|
55
55
|
else
|
|
56
56
|
@types.fetch(name, &bl)
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
def
|
|
60
|
+
def fetch_on_imports(name, imports = @imports, &bl)
|
|
61
61
|
if imports.empty?
|
|
62
62
|
raise KeyError, %Q{key not found: "#{name}"} unless bl
|
|
63
63
|
bl.call(name)
|
|
64
64
|
else
|
|
65
65
|
imports.first.fetch(name, false) do
|
|
66
|
-
|
|
66
|
+
fetch_on_imports(name, imports[1..-1], &bl)
|
|
67
67
|
end
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
|
-
private :_fetch
|
|
71
70
|
|
|
72
71
|
def factory
|
|
73
72
|
@factory ||= TypeFactory.new
|
|
@@ -89,22 +88,12 @@ module Finitio
|
|
|
89
88
|
Syntax.compile(source, self.dup)
|
|
90
89
|
end
|
|
91
90
|
|
|
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
|
-
|
|
102
91
|
def inspect
|
|
103
92
|
@types.each_pair.map{|k,v| "#{k} = #{v}" }.join("\n")
|
|
104
93
|
end
|
|
105
94
|
|
|
106
|
-
def dup
|
|
107
|
-
System.new(
|
|
95
|
+
def dup(types = @types.dup, imports = @imports.dup)
|
|
96
|
+
System.new(types, imports)
|
|
108
97
|
end
|
|
109
98
|
|
|
110
99
|
def check_and_warn(logger = nil)
|
|
@@ -28,7 +28,9 @@ module Finitio
|
|
|
28
28
|
|
|
29
29
|
def instantiate(compilation, sub_types)
|
|
30
30
|
overrides = Hash[vars.zip(sub_types)]
|
|
31
|
-
defn.resolve_proxies(compilation.with_scope(overrides))
|
|
31
|
+
defn.resolve_proxies(compilation.with_scope(overrides)).dup.tap{|x|
|
|
32
|
+
x.send(:name=, "#{name}<#{overrides.values.join(',')}>", true)
|
|
33
|
+
}
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
def unconstrained
|
|
@@ -15,8 +15,26 @@ module Finitio
|
|
|
15
15
|
"_#{target_name}_"
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
+
def include?(*args, &bl)
|
|
19
|
+
raise Error, "Proxy not resolved: #{target_name}" unless @target
|
|
20
|
+
|
|
21
|
+
@target.include?(*args, &bl)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def dress(*args, &bl)
|
|
25
|
+
raise Error, "Proxy not resolved: #{target_name}" unless @target
|
|
26
|
+
|
|
27
|
+
@target.dress(*args, &bl)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def bind!(system)
|
|
31
|
+
@target = system.fetch(target_name) {
|
|
32
|
+
raise Error, "No such type `#{target_name}` in #{system}"
|
|
33
|
+
}
|
|
34
|
+
end
|
|
35
|
+
|
|
18
36
|
def resolve_proxies(system)
|
|
19
|
-
system.fetch(target_name){
|
|
37
|
+
system.fetch(target_name) {
|
|
20
38
|
raise Error, "No such type `#{target_name}` in #{system}"
|
|
21
39
|
}
|
|
22
40
|
end
|
data/lib/finitio/type.rb
CHANGED
|
@@ -32,8 +32,10 @@ module Finitio
|
|
|
32
32
|
@name || default_name
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
def name=(n)
|
|
36
|
-
|
|
35
|
+
def name=(n, force = false)
|
|
36
|
+
if !@name.nil? && !force
|
|
37
|
+
raise Error, "Name already set to `#{@name}` on #{self.class}"
|
|
38
|
+
end
|
|
37
39
|
@name = n
|
|
38
40
|
end
|
|
39
41
|
|
data/lib/finitio/version.rb
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Finitio
|
|
3
|
+
module JsonSchema
|
|
4
|
+
describe "A recursive type" do
|
|
5
|
+
|
|
6
|
+
let(:system){
|
|
7
|
+
::Finitio.system <<-FIO
|
|
8
|
+
Tree = {
|
|
9
|
+
children : [Tree]
|
|
10
|
+
}
|
|
11
|
+
FIO
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let(:type) {
|
|
15
|
+
system['Tree']
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
it 'works as expected' do
|
|
19
|
+
expect(type.to_json_schema).to eql({
|
|
20
|
+
type: "object",
|
|
21
|
+
properties: {
|
|
22
|
+
children: {
|
|
23
|
+
type: "array",
|
|
24
|
+
items: {
|
|
25
|
+
type: "object"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
required: [
|
|
30
|
+
:children
|
|
31
|
+
],
|
|
32
|
+
additionalProperties: false
|
|
33
|
+
})
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Dress on a recursive type" do
|
|
4
|
+
let(:schema){
|
|
5
|
+
Finitio.system <<~F
|
|
6
|
+
Tree = {
|
|
7
|
+
children: [Tree]
|
|
8
|
+
}
|
|
9
|
+
Tree
|
|
10
|
+
F
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
it 'works on an empty tree' do
|
|
14
|
+
expect(->(){
|
|
15
|
+
schema.dress({children: []})
|
|
16
|
+
}).not_to raise_error
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'works on a non empty tree' do
|
|
20
|
+
expect(->(){
|
|
21
|
+
schema.dress({
|
|
22
|
+
children: [{
|
|
23
|
+
children: [{
|
|
24
|
+
children: [{
|
|
25
|
+
children: []
|
|
26
|
+
}]
|
|
27
|
+
}]
|
|
28
|
+
}]
|
|
29
|
+
})
|
|
30
|
+
}).not_to raise_error
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'detects deep error' do
|
|
34
|
+
expect(->(){
|
|
35
|
+
schema.dress({
|
|
36
|
+
children: [{
|
|
37
|
+
children: [{
|
|
38
|
+
children: [{
|
|
39
|
+
children: [{
|
|
40
|
+
children: [{
|
|
41
|
+
children: [{
|
|
42
|
+
unrecognized: true,
|
|
43
|
+
children: []
|
|
44
|
+
}]
|
|
45
|
+
}]
|
|
46
|
+
}]
|
|
47
|
+
}]
|
|
48
|
+
}]
|
|
49
|
+
}]
|
|
50
|
+
})
|
|
51
|
+
}).to raise_error(Finitio::Error)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "The types of generics definitions" do
|
|
4
|
+
describe "When the extra map to a type" do
|
|
5
|
+
let(:schema){
|
|
6
|
+
Finitio.system <<~F
|
|
7
|
+
Collection<T> = [T]
|
|
8
|
+
|
|
9
|
+
String = .String
|
|
10
|
+
Collection<String>
|
|
11
|
+
F
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
it 'works' do
|
|
15
|
+
expect(schema['Main'].target.name).to eql("Collection<String>")
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/spec/syntax/test_compile.rb
CHANGED
|
@@ -77,6 +77,24 @@ module Finitio
|
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
context 'with AD types' do
|
|
80
|
+
let(:source){
|
|
81
|
+
<<-EOF.strip
|
|
82
|
+
Int = .Integer
|
|
83
|
+
Byte = Int(i | i>0)
|
|
84
|
+
Color = .Color <rgb> { r: Byte, g: Byte, b: Byte }
|
|
85
|
+
Colors = [Color]
|
|
86
|
+
EOF
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
it{ should be_a(System) }
|
|
90
|
+
|
|
91
|
+
it 'should work fine' do
|
|
92
|
+
got = subject['Colors'].dress([{ r: 10, g: 15, b: 20 }])
|
|
93
|
+
expect(got.first).to be_a(Color)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
context 'with AD types that make forward references' do
|
|
80
98
|
let(:source){
|
|
81
99
|
<<-EOF.strip
|
|
82
100
|
Colors = [Color]
|
|
@@ -88,7 +106,7 @@ module Finitio
|
|
|
88
106
|
|
|
89
107
|
it{ should be_a(System) }
|
|
90
108
|
|
|
91
|
-
it 'should work
|
|
109
|
+
it 'should work fine' do
|
|
92
110
|
got = subject['Colors'].dress([{ r: 10, g: 15, b: 20 }])
|
|
93
111
|
expect(got.first).to be_a(Color)
|
|
94
112
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: finitio
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.11.
|
|
4
|
+
version: 0.11.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bernard Lambeau
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-01-
|
|
11
|
+
date: 2023-01-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: citrus
|
|
@@ -163,6 +163,7 @@ files:
|
|
|
163
163
|
- lib/finitio/generation/heuristic.rb
|
|
164
164
|
- lib/finitio/generation/heuristic/constant.rb
|
|
165
165
|
- lib/finitio/generation/heuristic/random.rb
|
|
166
|
+
- lib/finitio/generation/proxy_type.rb
|
|
166
167
|
- lib/finitio/generation/rel_based_type.rb
|
|
167
168
|
- lib/finitio/generation/seq_type.rb
|
|
168
169
|
- lib/finitio/generation/set_type.rb
|
|
@@ -193,6 +194,7 @@ files:
|
|
|
193
194
|
- lib/finitio/support/heading.rb
|
|
194
195
|
- lib/finitio/support/metadata.rb
|
|
195
196
|
- lib/finitio/support/proc_with_code.rb
|
|
197
|
+
- lib/finitio/support/proxy_resolver.rb
|
|
196
198
|
- lib/finitio/support/type_factory.rb
|
|
197
199
|
- lib/finitio/syntax.rb
|
|
198
200
|
- lib/finitio/syntax/definitions.rb
|
|
@@ -309,6 +311,7 @@ files:
|
|
|
309
311
|
- spec/json_schema/test_builtin_type.rb
|
|
310
312
|
- spec/json_schema/test_multi_relation_type.rb
|
|
311
313
|
- spec/json_schema/test_multi_tuple_type.rb
|
|
314
|
+
- spec/json_schema/test_recursive_type.rb
|
|
312
315
|
- spec/json_schema/test_relation_type.rb
|
|
313
316
|
- spec/json_schema/test_seq_type.rb
|
|
314
317
|
- spec/json_schema/test_set_type.rb
|
|
@@ -316,7 +319,9 @@ files:
|
|
|
316
319
|
- spec/json_schema/test_sub_type.rb
|
|
317
320
|
- spec/json_schema/test_tuple_type.rb
|
|
318
321
|
- spec/json_schema/test_union_type.rb
|
|
322
|
+
- spec/regression/test_dress_on_recursive_type.rb
|
|
319
323
|
- spec/regression/test_heading_extra_are_proxy_resolved.rb
|
|
324
|
+
- spec/regression/test_name_of_generic_types.rb
|
|
320
325
|
- spec/spec_helper.rb
|
|
321
326
|
- spec/support/test_compare_attrs.rb
|
|
322
327
|
- spec/support/test_proc_with_code.rb
|
|
@@ -487,6 +492,8 @@ signing_key:
|
|
|
487
492
|
specification_version: 4
|
|
488
493
|
summary: Finitio - in Ruby
|
|
489
494
|
test_files:
|
|
495
|
+
- spec/regression/test_dress_on_recursive_type.rb
|
|
496
|
+
- spec/regression/test_name_of_generic_types.rb
|
|
490
497
|
- spec/regression/test_heading_extra_are_proxy_resolved.rb
|
|
491
498
|
- spec/test_finitio.rb
|
|
492
499
|
- spec/constraint/test_named.rb
|
|
@@ -616,6 +623,7 @@ test_files:
|
|
|
616
623
|
- spec/json_schema/test_ad_type.rb
|
|
617
624
|
- spec/json_schema/test_builtin_type.rb
|
|
618
625
|
- spec/json_schema/test_multi_relation_type.rb
|
|
626
|
+
- spec/json_schema/test_recursive_type.rb
|
|
619
627
|
- spec/json_schema/test_sub_type.rb
|
|
620
628
|
- spec/json_schema/test_any_type.rb
|
|
621
629
|
- spec/json_schema/test_seq_type.rb
|