rubybreaker 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. data/NEWS +48 -0
  2. data/README.md +56 -20
  3. data/Rakefile +9 -34
  4. data/TODO +10 -10
  5. data/VERSION +1 -0
  6. data/bin/gen_stub_rubylib +35 -36
  7. data/bin/rubybreaker +1 -4
  8. data/lib/rubybreaker/debug.rb +8 -4
  9. data/lib/rubybreaker/rubylib/core.rb +738 -571
  10. data/lib/rubybreaker/runtime/inspector.rb +16 -7
  11. data/lib/rubybreaker/runtime/monitor.rb +14 -18
  12. data/lib/rubybreaker/runtime/object_wrapper.rb +9 -3
  13. data/lib/rubybreaker/runtime/overrides.rb +51 -8
  14. data/lib/rubybreaker/runtime/pluggable.rb +1 -3
  15. data/lib/rubybreaker/runtime/type_placeholder.rb +2 -6
  16. data/lib/rubybreaker/runtime/type_system.rb +53 -17
  17. data/lib/rubybreaker/runtime/typesig_parser.rb +1 -0
  18. data/lib/rubybreaker/runtime/util.rb +18 -0
  19. data/lib/rubybreaker/runtime.rb +42 -15
  20. data/lib/rubybreaker/type/type_comparer.rb +10 -10
  21. data/lib/rubybreaker/type/type_grammar.treetop +30 -21
  22. data/lib/rubybreaker/type/type_unparser.rb +2 -2
  23. data/lib/rubybreaker/typing/subtyping.rb +21 -21
  24. data/lib/rubybreaker/util.rb +11 -1
  25. data/lib/rubybreaker.rb +75 -54
  26. data/test/integrated/tc_class_methods.rb +35 -0
  27. data/test/integrated/tc_inherit_broken.rb +29 -0
  28. data/test/integrated/tc_method_missing.rb +1 -1
  29. data/test/runtime/tc_obj_wrapper.rb +104 -4
  30. data/test/ts_integrated.rb +2 -0
  31. data/test/type/tc_comparer.rb +96 -96
  32. data/test/type/tc_parser.rb +18 -0
  33. data/test/type/tc_unparser.rb +16 -0
  34. data/test/typing/tc_typing.rb +20 -20
  35. data/webpage/footer.html +1 -1
  36. data/webpage/header.html +7 -7
  37. data/webpage/index.html +65 -28
  38. data/webpage/rdoc/RubyBreaker/Breakable.html +280 -0
  39. data/webpage/rdoc/RubyBreaker/Broken/BrokenEigen.html +304 -0
  40. data/webpage/rdoc/RubyBreaker/Broken.html +308 -0
  41. data/webpage/rdoc/RubyBreaker/Context.html +421 -0
  42. data/webpage/rdoc/RubyBreaker/Debug.html +411 -0
  43. data/webpage/rdoc/RubyBreaker/Errors/InternalError.html +263 -0
  44. data/webpage/rdoc/RubyBreaker/Errors/InvalidSubtypeCheck.html +263 -0
  45. data/webpage/rdoc/RubyBreaker/Errors/InvalidTypeConstruction.html +214 -0
  46. data/webpage/rdoc/RubyBreaker/Errors/SubtypeFailure.html +212 -0
  47. data/webpage/rdoc/RubyBreaker/Errors/TypeError.html +212 -0
  48. data/webpage/rdoc/RubyBreaker/Errors/UserError.html +264 -0
  49. data/webpage/rdoc/RubyBreaker/Errors.html +209 -0
  50. data/webpage/rdoc/RubyBreaker/Kernel.html +259 -0
  51. data/webpage/rdoc/RubyBreaker/Main.html +560 -0
  52. data/webpage/rdoc/RubyBreaker/ObjectPosition.html +334 -0
  53. data/webpage/rdoc/RubyBreaker/Position.html +463 -0
  54. data/webpage/rdoc/RubyBreaker/RubyTypeUtils.html +308 -0
  55. data/webpage/rdoc/RubyBreaker/Runtime/Inspector.html +380 -0
  56. data/webpage/rdoc/RubyBreaker/Runtime/MethodInfo.html +324 -0
  57. data/webpage/rdoc/RubyBreaker/Runtime/Monitor.html +354 -0
  58. data/webpage/rdoc/RubyBreaker/Runtime/MonitorInstaller.html +379 -0
  59. data/webpage/rdoc/RubyBreaker/Runtime/MonitorSwitch.html +382 -0
  60. data/webpage/rdoc/RubyBreaker/Runtime/MonitorUtils.html +400 -0
  61. data/webpage/rdoc/RubyBreaker/Runtime/ObjectWrapper.html +411 -0
  62. data/webpage/rdoc/RubyBreaker/Runtime/Pluggable.html +305 -0
  63. data/webpage/rdoc/RubyBreaker/Runtime/TypePlaceholder.html +280 -0
  64. data/webpage/rdoc/RubyBreaker/Runtime/TypeSigParser.html +283 -0
  65. data/webpage/rdoc/RubyBreaker/Runtime/TypeSystem.html +630 -0
  66. data/webpage/rdoc/RubyBreaker/Runtime.html +255 -0
  67. data/webpage/rdoc/RubyBreaker/TestCase.html +332 -0
  68. data/webpage/rdoc/RubyBreaker/TypeComparer.html +304 -0
  69. data/webpage/rdoc/RubyBreaker/TypeDefs/AnyType.html +260 -0
  70. data/webpage/rdoc/RubyBreaker/TypeDefs/BlockType.html +310 -0
  71. data/webpage/rdoc/RubyBreaker/TypeDefs/DuckType.html +320 -0
  72. data/webpage/rdoc/RubyBreaker/TypeDefs/FusionType.html +323 -0
  73. data/webpage/rdoc/RubyBreaker/TypeDefs/MethodListType.html +281 -0
  74. data/webpage/rdoc/RubyBreaker/TypeDefs/MethodType.html +282 -0
  75. data/webpage/rdoc/RubyBreaker/TypeDefs/NilType.html +260 -0
  76. data/webpage/rdoc/RubyBreaker/TypeDefs/NominalType.html +282 -0
  77. data/webpage/rdoc/RubyBreaker/TypeDefs/OptionalType.html +281 -0
  78. data/webpage/rdoc/RubyBreaker/TypeDefs/OrType.html +281 -0
  79. data/webpage/rdoc/RubyBreaker/TypeDefs/SelfType.html +329 -0
  80. data/webpage/rdoc/RubyBreaker/TypeDefs/Type.html +409 -0
  81. data/webpage/rdoc/RubyBreaker/TypeDefs/VarLengthType.html +282 -0
  82. data/webpage/rdoc/RubyBreaker/TypeDefs.html +212 -0
  83. data/webpage/rdoc/RubyBreaker/TypeUnparser.html +273 -0
  84. data/webpage/rdoc/RubyBreaker/Typing.html +305 -0
  85. data/webpage/rdoc/RubyBreaker/Utilities.html +294 -0
  86. data/webpage/rdoc/RubyBreaker.html +337 -0
  87. data/webpage/rdoc/created.rid +26 -0
  88. data/webpage/rdoc/images/add.png +0 -0
  89. data/webpage/rdoc/images/brick.png +0 -0
  90. data/webpage/rdoc/images/brick_link.png +0 -0
  91. data/webpage/rdoc/images/bug.png +0 -0
  92. data/webpage/rdoc/images/bullet_black.png +0 -0
  93. data/webpage/rdoc/images/bullet_toggle_minus.png +0 -0
  94. data/webpage/rdoc/images/bullet_toggle_plus.png +0 -0
  95. data/webpage/rdoc/images/date.png +0 -0
  96. data/webpage/rdoc/images/delete.png +0 -0
  97. data/webpage/rdoc/images/find.png +0 -0
  98. data/webpage/rdoc/images/loadingAnimation.gif +0 -0
  99. data/webpage/rdoc/images/macFFBgHack.png +0 -0
  100. data/webpage/rdoc/images/package.png +0 -0
  101. data/webpage/rdoc/images/page_green.png +0 -0
  102. data/webpage/rdoc/images/page_white_text.png +0 -0
  103. data/webpage/rdoc/images/page_white_width.png +0 -0
  104. data/webpage/rdoc/images/plugin.png +0 -0
  105. data/webpage/rdoc/images/ruby.png +0 -0
  106. data/webpage/rdoc/images/tag_blue.png +0 -0
  107. data/webpage/rdoc/images/tag_green.png +0 -0
  108. data/webpage/rdoc/images/transparent.png +0 -0
  109. data/webpage/rdoc/images/wrench.png +0 -0
  110. data/webpage/rdoc/images/wrench_orange.png +0 -0
  111. data/webpage/rdoc/images/zoom.png +0 -0
  112. data/webpage/rdoc/index.html +165 -0
  113. data/webpage/rdoc/js/darkfish.js +153 -0
  114. data/webpage/rdoc/js/jquery.js +18 -0
  115. data/webpage/rdoc/js/navigation.js +142 -0
  116. data/webpage/rdoc/js/search.js +94 -0
  117. data/webpage/rdoc/js/search_index.js +1 -0
  118. data/webpage/rdoc/js/searcher.js +228 -0
  119. data/webpage/rdoc/rdoc.css +543 -0
  120. data/webpage/rdoc/table_of_contents.html +376 -0
  121. data/webpage/rubybreaker.css +31 -31
  122. metadata +93 -6
@@ -63,13 +63,13 @@ class ComparerTest < Test::Unit::TestCase
63
63
  assert(!t7.eql?(t11), msg(t7, t11, true))
64
64
  end
65
65
 
66
- def test_self
67
- t1 = SelfType.new()
68
- t2 = SelfType.new()
69
- t3 = NominalType.new(Fixnum)
70
- assert(t1.eql?(t2), msg(t1, t2))
71
- assert(!t1.eql?(t3), msg(t1, t3, true))
72
- end
66
+ def test_self
67
+ t1 = SelfType.new()
68
+ t2 = SelfType.new()
69
+ t3 = NominalType.new(Fixnum)
70
+ assert(t1.eql?(t2), msg(t1, t2))
71
+ assert(!t1.eql?(t3), msg(t1, t3, true))
72
+ end
73
73
 
74
74
  def test_duck
75
75
  t1 = DuckType.new([:foo, :bar])
@@ -84,45 +84,45 @@ class ComparerTest < Test::Unit::TestCase
84
84
  def test_fusion
85
85
  t1 = FusionType.new(NominalType.new(Fixnum), [:to_s, :to_f])
86
86
  t2 = FusionType.new(NominalType.new(Fixnum), [:to_f, :to_s])
87
- t3 = FusionType.new(NominalType.new(String), [:to_s, :to_f])
88
- t4 = DuckType.new([:to_s, :to_f])
89
- t5 = NominalType.new(Fixnum)
90
- assert(t1.eql?(t2), msg(t1, t2))
91
- assert(!t1.eql?(t3), msg(t1, t3, true))
92
- assert(!t1.eql?(t4), msg(t1, t4, true))
93
- assert(!t1.eql?(t5), msg(t1, t5, true))
87
+ t3 = FusionType.new(NominalType.new(String), [:to_s, :to_f])
88
+ t4 = DuckType.new([:to_s, :to_f])
89
+ t5 = NominalType.new(Fixnum)
90
+ assert(t1.eql?(t2), msg(t1, t2))
91
+ assert(!t1.eql?(t3), msg(t1, t3, true))
92
+ assert(!t1.eql?(t4), msg(t1, t4, true))
93
+ assert(!t1.eql?(t5), msg(t1, t5, true))
94
94
  end
95
95
 
96
- def test_block_no_arg
97
- t1 = NominalType.new(String)
98
- t2 = NominalType.new(String)
99
- t3 = NominalType.new(Fixnum)
100
- t4 = BlockType.new([],nil,t1)
101
- t5 = BlockType.new([],nil,t2)
102
- t6 = BlockType.new([],nil,t3)
103
- assert(t4.eql?(t5), msg(t4, t5))
104
- assert(!t4.eql?(t6), msg(t4, t6, true))
105
- end
96
+ def test_block_no_arg
97
+ t1 = NominalType.new(String)
98
+ t2 = NominalType.new(String)
99
+ t3 = NominalType.new(Fixnum)
100
+ t4 = BlockType.new([],nil,t1)
101
+ t5 = BlockType.new([],nil,t2)
102
+ t6 = BlockType.new([],nil,t3)
103
+ assert(t4.eql?(t5), msg(t4, t5))
104
+ assert(!t4.eql?(t6), msg(t4, t6, true))
105
+ end
106
106
 
107
- def test_block_one_arg
108
- t1 = NominalType.new(String)
109
- t2 = NominalType.new(String)
110
- t3 = NominalType.new(Fixnum)
111
- t4 = BlockType.new([t1],nil,t3)
112
- t5 = BlockType.new([t2],nil,t3)
113
- t6 = BlockType.new([],nil,t3)
114
- assert(t4.eql?(t5), msg(t4, t5))
115
- assert(!t4.eql?(t6), msg(t4, t6, true))
116
- end
117
-
118
- def test_block_more_args
119
- t1 = NominalType.new(String)
120
- t2 = NominalType.new(String)
121
- t3 = NominalType.new(Fixnum)
122
- t4 = OptionalType.new(NominalType.new(Object))
123
- t5 = VarLengthType.new(NominalType.new(String))
124
- t6 = NominalType.new(BasicObject)
125
- t7 = BlockType.new([t1,t4,t5],nil,t3)
107
+ def test_block_one_arg
108
+ t1 = NominalType.new(String)
109
+ t2 = NominalType.new(String)
110
+ t3 = NominalType.new(Fixnum)
111
+ t4 = BlockType.new([t1],nil,t3)
112
+ t5 = BlockType.new([t2],nil,t3)
113
+ t6 = BlockType.new([],nil,t3)
114
+ assert(t4.eql?(t5), msg(t4, t5))
115
+ assert(!t4.eql?(t6), msg(t4, t6, true))
116
+ end
117
+
118
+ def test_block_more_args
119
+ t1 = NominalType.new(String)
120
+ t2 = NominalType.new(String)
121
+ t3 = NominalType.new(Fixnum)
122
+ t4 = OptionalType.new(NominalType.new(Object))
123
+ t5 = VarLengthType.new(NominalType.new(String))
124
+ t6 = NominalType.new(BasicObject)
125
+ t7 = BlockType.new([t1,t4,t5],nil,t3)
126
126
  t8 = BlockType.new([t2,t4,t5],nil,t3)
127
127
  t9 = BlockType.new([t1,t5,t4],nil,t3)
128
128
  t10 = BlockType.new([t1,t4],nil,t3)
@@ -133,56 +133,56 @@ class ComparerTest < Test::Unit::TestCase
133
133
  assert(!t7.eql?(t10), msg(t7, t10, true))
134
134
  assert(!t7.eql?(t11), msg(t7, t11, true))
135
135
  assert(!t7.eql?(t12), msg(t7, t12, true))
136
- end
137
-
138
- def test_method_no_arg
139
- t1 = NominalType.new(String)
140
- t2 = NominalType.new(String)
141
- t3 = NominalType.new(Fixnum)
142
- t4 = MethodType.new(:foo,[],nil,t1)
143
- t5 = MethodType.new(:foo,[],nil,t2)
144
- t6 = MethodType.new(:bar,[],nil,t2)
145
- t7 = MethodType.new(:foo,[],nil,t3)
146
- assert(t4.eql?(t5), msg(t4, t5))
147
- assert(!t4.eql?(t6), msg(t4, t6, true))
148
- assert(!t4.eql?(t7), msg(t4, t7, true))
149
- end
136
+ end
137
+
138
+ def test_method_no_arg
139
+ t1 = NominalType.new(String)
140
+ t2 = NominalType.new(String)
141
+ t3 = NominalType.new(Fixnum)
142
+ t4 = MethodType.new(:foo,[],nil,t1)
143
+ t5 = MethodType.new(:foo,[],nil,t2)
144
+ t6 = MethodType.new(:bar,[],nil,t2)
145
+ t7 = MethodType.new(:foo,[],nil,t3)
146
+ assert(t4.eql?(t5), msg(t4, t5))
147
+ assert(!t4.eql?(t6), msg(t4, t6, true))
148
+ assert(!t4.eql?(t7), msg(t4, t7, true))
149
+ end
150
150
 
151
- def test_method_one_arg
152
- t1 = NominalType.new(String)
153
- t2 = NominalType.new(String)
154
- t3 = NominalType.new(Fixnum)
155
- t4 = MethodType.new(:foo, [t1],nil,t3)
156
- t5 = MethodType.new(:foo, [t2],nil,t3)
157
- t6 = MethodType.new(:foo, [],nil,t3)
158
- assert(t4.eql?(t5), msg(t4, t5))
159
- assert(!t4.eql?(t6), msg(t4, t6, true))
160
- end
161
-
162
- def test_method_one_arg_with_blk
163
- t1 = NominalType.new(String)
164
- t2 = NominalType.new(String)
165
- t3 = NominalType.new(Fixnum)
166
- t4 = BlockType.new([t1],nil,t3)
167
- t5 = BlockType.new([t2],nil,t3)
168
- t6 = BlockType.new([],nil,t3)
151
+ def test_method_one_arg
152
+ t1 = NominalType.new(String)
153
+ t2 = NominalType.new(String)
154
+ t3 = NominalType.new(Fixnum)
155
+ t4 = MethodType.new(:foo, [t1],nil,t3)
156
+ t5 = MethodType.new(:foo, [t2],nil,t3)
157
+ t6 = MethodType.new(:foo, [],nil,t3)
158
+ assert(t4.eql?(t5), msg(t4, t5))
159
+ assert(!t4.eql?(t6), msg(t4, t6, true))
160
+ end
161
+
162
+ def test_method_one_arg_with_blk
163
+ t1 = NominalType.new(String)
164
+ t2 = NominalType.new(String)
165
+ t3 = NominalType.new(Fixnum)
166
+ t4 = BlockType.new([t1],nil,t3)
167
+ t5 = BlockType.new([t2],nil,t3)
168
+ t6 = BlockType.new([],nil,t3)
169
169
  t7 = MethodType.new(:foo, [t1], t4, t3)
170
170
  t8 = MethodType.new(:foo, [t2], t5, t3)
171
171
  t9 = MethodType.new(:bar, [t1], t4, t3)
172
172
  t10 = MethodType.new(:foo, [t1], t6, t3)
173
- assert(t7.eql?(t8), msg(t7, t8))
174
- assert(!t7.eql?(t9), msg(t7, t9, true))
175
- assert(!t7.eql?(t10), msg(t7, t10, true))
176
- end
177
-
178
- def test_method_more_args
179
- t1 = NominalType.new(String)
180
- t2 = NominalType.new(String)
181
- t3 = NominalType.new(Fixnum)
182
- t4 = OptionalType.new(NominalType.new(Object))
183
- t5 = VarLengthType.new(NominalType.new(String))
184
- t6 = NominalType.new(BasicObject)
185
- t7 = MethodType.new(:foo, [t1,t4,t5],nil,t3)
173
+ assert(t7.eql?(t8), msg(t7, t8))
174
+ assert(!t7.eql?(t9), msg(t7, t9, true))
175
+ assert(!t7.eql?(t10), msg(t7, t10, true))
176
+ end
177
+
178
+ def test_method_more_args
179
+ t1 = NominalType.new(String)
180
+ t2 = NominalType.new(String)
181
+ t3 = NominalType.new(Fixnum)
182
+ t4 = OptionalType.new(NominalType.new(Object))
183
+ t5 = VarLengthType.new(NominalType.new(String))
184
+ t6 = NominalType.new(BasicObject)
185
+ t7 = MethodType.new(:foo, [t1,t4,t5],nil,t3)
186
186
  t8 = MethodType.new(:foo, [t2,t4,t5],nil,t3)
187
187
  t9 = MethodType.new(:foo, [t1,t5,t4],nil,t3)
188
188
  t10 = MethodType.new(:foo, [t1,t4],nil,t3)
@@ -193,16 +193,16 @@ class ComparerTest < Test::Unit::TestCase
193
193
  assert(!t7.eql?(t10), msg(t7, t10, true))
194
194
  assert(!t7.eql?(t11), msg(t7, t11, true))
195
195
  assert(!t7.eql?(t12), msg(t7, t12, true))
196
- end
196
+ end
197
197
 
198
198
  def test_method_lists
199
- t1 = NominalType.new(String)
200
- t2 = NominalType.new(String)
201
- t3 = NominalType.new(Fixnum)
202
- t4 = MethodType.new(:foo,[],nil,t1)
203
- t5 = MethodType.new(:foo,[],nil,t2)
204
- t6 = MethodType.new(:bar,[],nil,t2)
205
- t7 = MethodType.new(:foo,[],nil,t3)
199
+ t1 = NominalType.new(String)
200
+ t2 = NominalType.new(String)
201
+ t3 = NominalType.new(Fixnum)
202
+ t4 = MethodType.new(:foo,[],nil,t1)
203
+ t5 = MethodType.new(:foo,[],nil,t2)
204
+ t6 = MethodType.new(:bar,[],nil,t2)
205
+ t7 = MethodType.new(:foo,[],nil,t3)
206
206
  t8 = MethodListType.new([t4,t6])
207
207
  t9 = MethodListType.new([t5,t7])
208
208
  assert(!t8.eql?(t9), msg(t8, t9, true))
@@ -211,6 +211,24 @@ class GrammarTest < Test::Unit::TestCase
211
211
  assert_equal("foo() -> nil", str)
212
212
  end
213
213
 
214
+ def test_multi_line_1
215
+ type = @parser.parse("foo(fixnum[to_s,to_i]) ->
216
+ fixnum").value
217
+ str = TypeUnparser.unparse(type)
218
+ #puts str
219
+ assert_equal("foo(fixnum[to_i, to_s]) -> fixnum",str)
220
+ end
221
+
222
+ def test_multi_line_2
223
+ type = @parser.parse("foo(fixnum[to_s,
224
+ to_i])
225
+ ->
226
+ fixnum").value
227
+ str = TypeUnparser.unparse(type)
228
+ #puts str
229
+ assert_equal("foo(fixnum[to_i, to_s]) -> fixnum",str)
230
+ end
231
+
214
232
  def test_parse_fail_no_methname
215
233
  type = @parser.parse("() -> nil")
216
234
  assert_equal(nil, type, "Type signature without a method name")
@@ -68,6 +68,22 @@ class UnparserTest < Test::Unit::TestCase
68
68
  assert_equal("a*",str2)
69
69
  end
70
70
 
71
+ def test_star_duck_type()
72
+ t1 = DuckType.new([:foo, :bar])
73
+ t2 = VarLengthType.new(t1)
74
+ str2 = TypeUnparser.unparse(t2)
75
+ # puts str1
76
+ assert_equal("[bar, foo]*",str2)
77
+ end
78
+
79
+ def test_star_fusion_type()
80
+ t1 = FusionType.new(NominalType.new(A), [:foo, :bar])
81
+ t2 = VarLengthType.new(t1)
82
+ str2 = TypeUnparser.unparse(t2)
83
+ # puts str1
84
+ assert_equal("a[bar, foo]*",str2)
85
+ end
86
+
71
87
  def test_star_or_type()
72
88
  t1 = NominalType.new(A)
73
89
  t2 = NominalType.new(B)
@@ -59,26 +59,26 @@ class TypingTest < Test::Unit::TestCase
59
59
  assert(!t4.subtype_of?(t1), msg(t4,t1,true))
60
60
  end
61
61
 
62
- def test_self()
63
- SelfType.set_self(Fixnum)
64
- t1 = SelfType.new()
65
- t2 = SelfType.new()
66
- SelfType.set_self(String)
67
- t3 = SelfType.new()
68
- t4 = NominalType.new(Numeric)
69
- t5 = NominalType.new(String)
70
- t6 = DuckType.new([:to_s])
71
- assert(t1.subtype_of?(t2), msg(t1,t2))
72
- assert(t2.subtype_of?(t1), msg(t2,t1))
73
- assert(t1.subtype_of?(t3), msg(t1, t3))
74
- assert(t3.subtype_of?(t1), msg(t3, t1))
75
- assert(t1.subtype_of?(t4), msg(t1, t4))
76
- assert(!t4.subtype_of?(t1), msg(t4, t1, true))
77
- assert(!t1.subtype_of?(t5), msg(t1, t5, true))
78
- assert(!t5.subtype_of?(t1), msg(t5, t1, true))
79
- assert(t1.subtype_of?(t6), msg(t1, t5))
80
- assert(!t6.subtype_of?(t1), msg(t5, t1, true))
81
- end
62
+ def test_self()
63
+ SelfType.set_self(Fixnum)
64
+ t1 = SelfType.new()
65
+ t2 = SelfType.new()
66
+ SelfType.set_self(String)
67
+ t3 = SelfType.new()
68
+ t4 = NominalType.new(Numeric)
69
+ t5 = NominalType.new(String)
70
+ t6 = DuckType.new([:to_s])
71
+ assert(t1.subtype_of?(t2), msg(t1,t2))
72
+ assert(t2.subtype_of?(t1), msg(t2,t1))
73
+ assert(t1.subtype_of?(t3), msg(t1, t3))
74
+ assert(t3.subtype_of?(t1), msg(t3, t1))
75
+ assert(t1.subtype_of?(t4), msg(t1, t4))
76
+ assert(!t4.subtype_of?(t1), msg(t4, t1, true))
77
+ assert(!t1.subtype_of?(t5), msg(t1, t5, true))
78
+ assert(!t5.subtype_of?(t1), msg(t5, t1, true))
79
+ assert(t1.subtype_of?(t6), msg(t1, t5))
80
+ assert(!t6.subtype_of?(t1), msg(t5, t1, true))
81
+ end
82
82
 
83
83
  def test_duck_types_id()
84
84
  t1 = DuckType.new([:foo,:baz])
data/webpage/footer.html CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- </div>
2
+ </div>
3
3
  </center>
4
4
  </body>
5
5
  </html>
data/webpage/header.html CHANGED
@@ -2,13 +2,13 @@
2
2
  <head>
3
3
  <title>RubyBreaker</title>
4
4
  <LINK REL=StyleSheet HREF="rubybreaker.css" TYPE="text/css">
5
- <script type="text/javascript" src="generated_toc.js"> </script>
5
+ <script type="text/javascript" src="generated_toc.js"> </script>
6
6
  </head>
7
7
  <body onLoad="createTOC()">
8
8
  <center>
9
- <div id="content">
10
- <div id="logo">
11
- <img src="images/logo.png" border="0">
12
- </div>
13
- <hr />
14
- <div id="generated-toc"></div>
9
+ <div id="content">
10
+ <div id="logo">
11
+ <img src="images/logo.png" border="0">
12
+ </div>
13
+ <hr />
14
+ <div id="generated-toc"></div>
data/webpage/index.html CHANGED
@@ -2,16 +2,16 @@
2
2
  <head>
3
3
  <title>RubyBreaker</title>
4
4
  <LINK REL=StyleSheet HREF="rubybreaker.css" TYPE="text/css">
5
- <script type="text/javascript" src="generated_toc.js"> </script>
5
+ <script type="text/javascript" src="generated_toc.js"> </script>
6
6
  </head>
7
7
  <body onLoad="createTOC()">
8
8
  <center>
9
- <div id="content">
10
- <div id="logo">
11
- <img src="images/logo.png" border="0">
12
- </div>
13
- <hr />
14
- <div id="generated-toc"></div>
9
+ <div id="content">
10
+ <div id="logo">
11
+ <img src="images/logo.png" border="0">
12
+ </div>
13
+ <hr />
14
+ <div id="generated-toc"></div>
15
15
  <hr />
16
16
 
17
17
  <h1>Introduction</h1>
@@ -32,6 +32,11 @@ document their code more rigorously and effectively. Currently, manual
32
32
  modification of the user program is required to run RubyBreaker, but this is
33
33
  kept minimal.</p>
34
34
 
35
+ <p>To contribute to the project, visit RubyBreaker's
36
+ <a href="http://github.com/rockalizer/rubybreaker">GitHub page</a> and
37
+ <a href="http://rubygems.org/gems/rubybreaker">RubyGems page</a>. RubyBreaker RDoc can
38
+ be found in <a href="rdoc/index.html">here</a>.</p>
39
+
35
40
  <h2>Limitations</h2>
36
41
 
37
42
  <ul>
@@ -192,11 +197,34 @@ signature <code>bar(fixnum[to_s]) -&gt; string</code>, which means it takes an o
192
197
  has <code>Fixnum</code>'s <code>to_s</code> method and returns a string. More detail on the type
193
198
  annotation language will be explained in later section.</p>
194
199
 
195
- <p>Currently, both <code>Breakable</code> and <code>Broken</code> only support instance methods.
196
- Furthermore, class and module methods can neither be monitored nor used for
197
- analysis. It is important to keep in mind that <code>Broken</code> module always wins.
198
- In other words, if a module is declared as both <code>Broken</code> and <code>Breakable</code>, it
199
- is treated as <code>Broken</code>.</p>
200
+ <p>It is possible to include either <code>Breakable</code> or <code>Broken</code> in an eigen-class
201
+ to document class methods. To make this easier, RubyBreaker will
202
+ automatically support auto-documentation and manual documentation of class
203
+ methods if the original module is declared as <code>Breakable</code> or <code>Broken</code>,
204
+ respectively--that is, up to immediate eigen class level of a "nominal"
205
+ module. The following example shows how class methods can be
206
+ auto-documented and manually documented, respectively.</p>
207
+
208
+ <pre><code>require "rubybreaker"
209
+ class A
210
+ include RubyBreaker::Breakable
211
+ class &lt;&lt; self
212
+ def foo(x); x.to_s end
213
+ end
214
+ end
215
+ class B
216
+ include RubyBreaker::Broken
217
+ class &lt;&lt; self
218
+ typesig("foo(fixnum[to_s]) -&gt; string")
219
+ def foo(x); x.to_s end
220
+ end
221
+ end
222
+ </code></pre>
223
+
224
+ <p>Keep in mind that <code>Broken</code> module always wins against <code>Breakable</code>. In other
225
+ words, if a module is declared as both <code>Broken</code> and <code>Breakable</code>, it is
226
+ treated as <code>Broken</code>. Future versions of RubyBreaker will support a hybrid of
227
+ the two modules, but it remains as a limitation in the current version.</p>
200
228
 
201
229
  <h3>Program Entry Point</h3>
202
230
 
@@ -325,7 +353,7 @@ it should be only used for an object that requires an arbitrary yet most
325
353
  specific type--that is, <code>?</code> is a subtype of any other type, but any
326
354
  other type is not a subtype of <code>?</code>. This becomes a bit complicated for
327
355
  method or block argument types because of their contra-variance
328
- characteristic. Please kefer to the section <em>Subtyping</em>.</p>
356
+ characteristic. Please refer to the section <em>Subtyping</em>.</p>
329
357
 
330
358
  <h3>Block Type</h3>
331
359
 
@@ -399,25 +427,34 @@ subsequent "promotions").</p>
399
427
 
400
428
  <h2>Type System</h2>
401
429
 
402
- <p>RubyBreaker comes with its own type system that is used to document type
403
- information. This section describes how RubyBreaker determines which type(s)
404
- to document. <em>More documentation coming soon...</em></p>
405
-
406
- <h3>Subtyping</h3>
407
-
408
- <p><em>Documentation coming soon...</em></p>
409
-
410
- <h3>Subtyping vs. Subclassing</h3>
411
-
412
- <p><em>Documentation coming soon...</em></p>
430
+ <p>RubyBreaker comes with its own type system to auto-document the type
431
+ information. Each method in a <code>Breakable</code> module is dynamically instrumented
432
+ to be monitored during runtime. This monitoring code observes the types of
433
+ the arguments, block, and return value of each method. Once this information
434
+ is gathered, RubyBreaker will compare it to the information gathered so far.
435
+ If these two types are "compatiable", RubyBreaker will choose more general
436
+ type of the two. Otherwise, RubyBreaker will use the method list type to
437
+ accommodate two "incompatible" types.</p>
438
+
439
+ <h3>Subtyping and Subclassing</h3>
440
+
441
+ <p>RubyBreaker uses subtyping to choose one from the two "compatible" types.
442
+ Two types are "compatible" if one is subtype of another. This means that the
443
+ <em>subtype</em> can be represented using the <em>supertype</em> instead. This is why
444
+ RubyBrekaer chooses the latter to document both types. RubyBreaker relies on
445
+ subclassing of Ruby to determine a subtyping relationship between two types.
446
+ For example, <code>Fixnum</code> is considered to be subtype of <code>Numeric</code> since the
447
+ former is subclass of the latter. (Strictly speaking, <code>Fixnum</code> is not really
448
+ subtype of <code>Numeric</code> because some methods are overriden in <code>Fixnum</code> with
449
+ method types that are not subtype of the counterparts in <code>Numeric</code>. But,
450
+ RubyBreaker is lenient and considers them compatible--that is, <code>Numeric</code> can
451
+ represent any <code>Fixnum</code>.</p>
413
452
 
414
453
  <h3>Pluggable Type System (Advanced)</h3>
415
454
 
416
455
  <p>Yes, RubyBreaker was designed with the replaceable type system in mind. In
417
456
  other words, anyone can write his own type system and plug it into
418
- RubyBreaker.</p>
419
-
420
- <p><em>Documentation coming soon...</em></p>
457
+ RubyBreaker. <em>Technical documentation coming soon...</em></p>
421
458
 
422
459
  <hr />
423
460
 
@@ -433,7 +470,7 @@ respect to a nominal type.</p>
433
470
 
434
471
  <p>Copyright (c) 2012 Jong-hoon (David) An. All Rights Reserved.</p>
435
472
 
436
- </div>
473
+ </div>
437
474
  </center>
438
475
  </body>
439
476
  </html>