finitio 0.7.0.pre.rc4 → 0.7.0

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 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