rubybreaker 0.0.1 → 0.0.2

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