finitio 0.7.0.pre.rc4 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e41db73ab84b38134f0f19c0340c0863ff2d134b
4
- data.tar.gz: db5f29aa5ce74764ffa96124d5982b3734491790
3
+ metadata.gz: 1be4c866c9b4cc67fddb28b39ef618897013cd29
4
+ data.tar.gz: 51d2f530a4be64de2a3f9a075e5ff536775454ac
5
5
  SHA512:
6
- metadata.gz: 7a48bf413dab63621f2c246fe4997ea8b0a1b9a04e3ac66ff14db4e697156cc20a56bd4ec2fee9493facbdc9466433d1f96d0e7d3a47162126402bf38e39ac88
7
- data.tar.gz: 9def829a4ad8936700eba39ae1aaefebd0526def79a9c289cbfc06c2abf0b2be54771826b97c739d2cda39455223e0b60dd4f6d7e45a96bc39884338bd2312e9
6
+ metadata.gz: 9024a94cb06ec0df550904d8b1b2029b0e54956a48d54a95ada3ca9a679fd6314278c2ae6bd524ae6ff171a71f6ec6928cb5bfda0a54cda40ddac07168770308
7
+ data.tar.gz: 3d2eee7016ee732383c1deb0ec202c8c2346eb5a3c2610dd1788d2dc6361c30e46a6438f96144822ff991e883cfdb0c03eb50bd7e8e6777724be91345cc6063b
@@ -1,3 +1,16 @@
1
+ # 0.7.0 / 2019-02-28
2
+
3
+ * Implement (basic) @import feature, working with relative paths
4
+ and a standard library. The standard library systems are memoized
5
+ to avoid unnecessary parsing and compilation.
6
+
7
+ * `System#check_and_warn` allows discovering warnings, infos and
8
+ errors in system definitions, such as duplicate type definitions
9
+ and import overrides.
10
+
11
+ * WARN: Finitio::DEFAULT_SYSTEM is deprecated. Use @import
12
+ finitio/data instead.
13
+
1
14
  # 0.6.1 / 2018-03-23
2
15
 
3
16
  * Fix support for typed extra attributes, a KeyError was raised when
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- finitio (0.7.0.pre.rc4)
4
+ finitio (0.7.0)
5
5
  citrus (>= 2.4, < 4.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -19,7 +19,9 @@ require 'finitio'
19
19
  require 'json'
20
20
 
21
21
  # Let load a schema
22
- schema = Finitio::DEFAULT_SYSTEM.parse <<-FIO
22
+ schema = Finitio.system <<-FIO
23
+ @import finitio/data
24
+
23
25
  {
24
26
  name: String( s | s.strip.size > 0 ),
25
27
  at: DateTime
@@ -98,6 +100,91 @@ module RgbContract
98
100
  end
99
101
  ```
100
102
 
103
+ ## Decompose complex system with imports
104
+
105
+ It is useful to decompose complex systems in many files using the import
106
+ feature. The latter works with relative file paths like this:
107
+
108
+ ```
109
+ # child.fio
110
+
111
+ Posint = .Integer(i | i >= 0)
112
+ ```
113
+
114
+ ```
115
+ # parent.fio
116
+ @import ./child.fio
117
+
118
+ # Child's types are available inside the system, but not outside it, that
119
+ # is, imported types are not themselves exported
120
+ Byte = Posint(i | i <= 255 )
121
+ ```
122
+
123
+ ```
124
+ @import ./parent.fio
125
+
126
+ # This will work
127
+ HalfByte = Byte(i | i <= 128)
128
+
129
+ # But this will not: Posint is not defined
130
+ Posint(i | i <= 128)
131
+ ```
132
+
133
+ See the next section about the standard library if you need to share types
134
+ without relying on relative paths.
135
+
136
+ ## Standard library
137
+
138
+ Usual type definitions are already defined for simple data types, forming
139
+ Finitio's default system:
140
+
141
+ * Most ruby native (data) classes are already aliased to avoid explicit use of
142
+ builtins. In particular, `Integer`, `String`, etc.
143
+
144
+ * A `Boolean` union type also hides the TrueClass and FalseClass distinction.
145
+
146
+ * Date, Time and DateTime ADTs are also provided that perform common
147
+ conversions from JSON strings, through iso8601.
148
+
149
+ This system is best used through Finitio's so-called "standard library", e.g.
150
+
151
+ ```
152
+ @import finitio/data
153
+
154
+ # String, Integer, Boolean, etc. are now available in this system
155
+ ```
156
+
157
+ See `lib/finitio/stdlib/*.fio` for the precise definition of the standard library.
158
+
159
+ ### Contributing to the standard library
160
+
161
+ Ruby gems may contribute to the standard library by specifying resolve paths.
162
+ We suggest the following system file structure inside your gem source code:
163
+
164
+ ```
165
+ lib
166
+ myrubygem
167
+ myrubygem.rb
168
+ finitio
169
+ myrubygem
170
+ base.fio
171
+ advanced.fio
172
+ ```
173
+
174
+ Registering the standard library path can then be done as follows:
175
+
176
+ ```
177
+ # inside myrubygem.rb
178
+ Finitio.stdlib_path(File.expand_path('../../finitio', __FILE__))
179
+ ```
180
+
181
+ Then, a Finitio schema will have access to the types defined in your extension:
182
+
183
+ ```
184
+ @import myrubygem/base
185
+ @import myrubygem/advanced
186
+ ```
187
+
101
188
  ## About representations
102
189
 
103
190
  The `Rep` representation function mapping *Finitio* types to ruby classes is
@@ -135,14 +222,3 @@ Rep({{Ai => Ti}}) = Set<Hash<Symbol => Rep(Ti)>>
135
222
  # specified. ADTs behave as Union types if no class is bound.
136
223
  Rep(.Builtin <rep> ...) = Builtin
137
224
  ```
138
-
139
- ## About the default system
140
-
141
- See `lib/finitio/Finitio/default.fio` for the precise definition of the default
142
- system. In summary,
143
-
144
- * Most ruby native (data) classes are already aliased to avoid explicit use of
145
- builtins. In particular, `Integer`, `String`, etc.
146
- * A `Boolean` union type also hides the TrueClass and FalseClass distinction.
147
- * Date, Time and DateTime ADTs are also provided that perform common
148
- conversions from JSON strings, through iso8601.
@@ -16,16 +16,18 @@ module Finitio
16
16
 
17
17
  ANY_TYPE = AnyType.new
18
18
 
19
+ LOCK = Mutex.new
20
+
19
21
  STDLIB_PATHS = [
20
22
  File.expand_path('../finitio/stdlib', __FILE__)
21
23
  ]
22
24
 
23
25
  MEMOIZED_SYSTEMS = {}
24
26
 
25
- MEMOIZATION_SEMAPHORE = Mutex.new
26
-
27
27
  def stdlib_path(path)
28
- STDLIB_PATHS << path
28
+ LOCK.synchronize {
29
+ STDLIB_PATHS << path
30
+ }
29
31
  end
30
32
 
31
33
  def parse(source)
@@ -33,7 +35,7 @@ module Finitio
33
35
  end
34
36
 
35
37
  def system(source)
36
- MEMOIZATION_SEMAPHORE.synchronize {
38
+ LOCK.synchronize {
37
39
  _system(source)
38
40
  }
39
41
  end
@@ -48,7 +50,7 @@ module Finitio
48
50
  private :_system
49
51
 
50
52
  def clear_saved_systems!
51
- MEMOIZATION_SEMAPHORE.synchronize {
53
+ LOCK.synchronize {
52
54
  MEMOIZED_SYSTEMS.clear
53
55
  }
54
56
  end
@@ -30,7 +30,7 @@ module Finitio
30
30
  end
31
31
 
32
32
  def hash
33
- [infotype, dresser, undresser].hash
33
+ infotype.hash ^ dresser.hash ^ undresser.hash
34
34
  end
35
35
 
36
36
  def ==(other)
@@ -38,7 +38,7 @@ module Finitio
38
38
  other.is_a?(Contract) &&
39
39
  name == other.name &&
40
40
  infotype == other.infotype &&
41
- dresser == other.dresser &&
41
+ dresser == other.dresser &&
42
42
  undresser == other.undresser
43
43
  )
44
44
  end
@@ -97,16 +97,20 @@ module Finitio
97
97
  System.new(@types.dup, @imports.dup)
98
98
  end
99
99
 
100
- def check_and_warn(io = STDERR)
100
+ def check_and_warn(logger = nil)
101
+ logger ||= begin
102
+ require 'logger'
103
+ Logger.new(STDERR)
104
+ end
101
105
  each_type do |t|
102
106
  next unless t.named?
103
107
  each_import do |i|
104
108
  next unless found = i.get_type(t.name)
105
109
  if found == t
106
- STDERR.puts "WARN: duplicate type def `#{t.name}`"
110
+ logger.info "Duplicate type def `#{t.name}`"
107
111
  break
108
112
  else
109
- STDERR.puts "NOTICE: Type erasure `#{t.name}`"
113
+ logger.warn "Type erasure `#{t.name}`"
110
114
  break
111
115
  end
112
116
  end
@@ -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)
@@ -3,7 +3,7 @@ module Finitio
3
3
 
4
4
  MAJOR = 0
5
5
  MINOR = 7
6
- TINY = "0-rc4"
6
+ TINY = 0
7
7
 
8
8
  def self.to_s
9
9
  [ MAJOR, MINOR, TINY ].join('.')
@@ -29,15 +29,4 @@ describe Finitio, "system" do
29
29
  end
30
30
  end
31
31
 
32
- context "feedback about duplicate types" do
33
- before {
34
- Finitio.stdlib_path(Path.dir.parent)
35
- }
36
- subject{
37
- Finitio.system(Path.dir/"with-duplicates.fio").check_and_warn
38
- }
39
-
40
- it{ should be_a(Finitio::System) }
41
- end
42
-
43
32
  end
@@ -0,0 +1,2 @@
1
+ Posint = .Integer( i | i >= 0 )
2
+ Negint = .Integer( i | i < 0 )
@@ -1,5 +1,6 @@
1
1
  @import finitio/data
2
- @import finitio/system
2
+ @import ./system
3
3
 
4
4
  NilClass = .NilClass
5
5
  Posint = .Integer( i | i >= 0 )
6
+ Negint = .Integer( i | i <= 0 )
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+ module Finitio
3
+ describe System, "check_and_warn" do
4
+
5
+ before {
6
+ Finitio.stdlib_path(Path.dir)
7
+ }
8
+
9
+ subject{
10
+ Finitio.system(Path.dir/"fixtures/with-duplicates.fio").check_and_warn(logger)
11
+ }
12
+
13
+ let(:logger){
14
+ TestLogger.new
15
+ }
16
+
17
+ it {
18
+ should be_a(Finitio::System)
19
+ }
20
+
21
+ it 'detects duplicate types as expected' do
22
+ subject
23
+ expect(logger.infos).to eql([
24
+ "Duplicate type def `NilClass`",
25
+ "Duplicate type def `Posint`"
26
+ ])
27
+ end
28
+
29
+ it 'detects type erasures as expected' do
30
+ subject
31
+ expect(logger.warns).to eql([
32
+ "Type erasure `Negint`",
33
+ ])
34
+ end
35
+
36
+ class TestLogger
37
+
38
+ def initialize
39
+ @warns = []
40
+ @infos = []
41
+ end
42
+ attr_reader :warns, :infos
43
+
44
+ def warn(msg)
45
+ @warns << msg
46
+ end
47
+
48
+ def info(msg)
49
+ @infos << msg
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+ 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.7.0.pre.rc4
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernard Lambeau
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-27 00:00:00.000000000 Z
11
+ date: 2019-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: citrus
@@ -154,7 +154,6 @@ files:
154
154
  - spec/finitio/test_parse.rb
155
155
  - spec/finitio/test_stdlib_memoization.rb
156
156
  - spec/finitio/test_system.rb
157
- - spec/finitio/with-duplicates.fio
158
157
  - spec/heading/test_allow_extra.rb
159
158
  - spec/heading/test_each.rb
160
159
  - spec/heading/test_equality.rb
@@ -196,7 +195,10 @@ files:
196
195
  - spec/syntax/nodes/test_unnamed_constraint.rb
197
196
  - spec/syntax/test_compile.rb
198
197
  - spec/syntax/test_compile_type.rb
198
+ - spec/system/fixtures/system.fio
199
+ - spec/system/fixtures/with-duplicates.fio
199
200
  - spec/system/test_add_type.rb
201
+ - spec/system/test_check_and_warn.rb
200
202
  - spec/system/test_dsl.rb
201
203
  - spec/system/test_dup.rb
202
204
  - spec/system/test_fetch.rb
@@ -315,9 +317,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
315
317
  version: '0'
316
318
  required_rubygems_version: !ruby/object:Gem::Requirement
317
319
  requirements:
318
- - - ">"
320
+ - - ">="
319
321
  - !ruby/object:Gem::Version
320
- version: 1.3.1
322
+ version: '0'
321
323
  requirements: []
322
324
  rubyforge_project:
323
325
  rubygems_version: 2.5.2
@@ -363,7 +365,6 @@ test_files:
363
365
  - spec/heading/test_each.rb
364
366
  - spec/test_finitio.rb
365
367
  - spec/finitio/test_ast.rb
366
- - spec/finitio/with-duplicates.fio
367
368
  - spec/finitio/system.fio
368
369
  - spec/finitio/test_system.rb
369
370
  - spec/finitio/test_parse.rb
@@ -374,6 +375,9 @@ test_files:
374
375
  - spec/system/test_dup.rb
375
376
  - spec/system/test_add_type.rb
376
377
  - spec/system/test_dsl.rb
378
+ - spec/system/fixtures/with-duplicates.fio
379
+ - spec/system/fixtures/system.fio
380
+ - spec/system/test_check_and_warn.rb
377
381
  - spec/type/multi_relation_type/test_name.rb
378
382
  - spec/type/multi_relation_type/test_initialize.rb
379
383
  - spec/type/multi_relation_type/test_equality.rb