laser 0.7.0.pre1

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 (319) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +14 -0
  4. data/LICENSE +661 -0
  5. data/README.md +158 -0
  6. data/Rakefile +104 -0
  7. data/VERSION +1 -0
  8. data/bin/laser +7 -0
  9. data/design_docs/goals.md +57 -0
  10. data/design_docs/object_regex.md +426 -0
  11. data/design_docs/type_annotations.md +80 -0
  12. data/ext/laser/BasicBlock.cpp +572 -0
  13. data/ext/laser/BasicBlock.h +118 -0
  14. data/ext/laser/extconf.rb +3 -0
  15. data/features/laser.feature +25 -0
  16. data/features/step_definitions/laser_steps.rb +39 -0
  17. data/features/support/env.rb +14 -0
  18. data/features/support/testdata/1_input +1 -0
  19. data/features/support/testdata/1_output +1 -0
  20. data/features/support/testdata/2_input +4 -0
  21. data/features/support/testdata/2_output +4 -0
  22. data/features/support/testdata/3_input +8 -0
  23. data/features/support/testdata/3_output +11 -0
  24. data/features/support/testdata/4_input +5 -0
  25. data/features/support/testdata/4_output +5 -0
  26. data/features/support/testdata/5_input +13 -0
  27. data/laser.gemspec +382 -0
  28. data/lib/laser.rb +98 -0
  29. data/lib/laser/analysis/annotations.rb +95 -0
  30. data/lib/laser/analysis/annotations/annotation_config.yaml +3 -0
  31. data/lib/laser/analysis/annotations/comment_attachment_annotation.rb +66 -0
  32. data/lib/laser/analysis/annotations/node_pointers_annotation.rb +36 -0
  33. data/lib/laser/analysis/annotations/runtime_annotation.rb +55 -0
  34. data/lib/laser/analysis/argument_expansion.rb +132 -0
  35. data/lib/laser/analysis/arity.rb +34 -0
  36. data/lib/laser/analysis/bindings.rb +144 -0
  37. data/lib/laser/analysis/bootstrap/bootstrap.rb +298 -0
  38. data/lib/laser/analysis/bootstrap/laser_class.rb +106 -0
  39. data/lib/laser/analysis/bootstrap/laser_method.rb +255 -0
  40. data/lib/laser/analysis/bootstrap/laser_module.rb +403 -0
  41. data/lib/laser/analysis/bootstrap/laser_module_copy.rb +74 -0
  42. data/lib/laser/analysis/bootstrap/laser_object.rb +69 -0
  43. data/lib/laser/analysis/bootstrap/laser_proc.rb +150 -0
  44. data/lib/laser/analysis/bootstrap/laser_singleton_class.rb +44 -0
  45. data/lib/laser/analysis/comments.rb +35 -0
  46. data/lib/laser/analysis/control_flow.rb +28 -0
  47. data/lib/laser/analysis/control_flow/alias_analysis.rb +31 -0
  48. data/lib/laser/analysis/control_flow/basic_block.rb +105 -0
  49. data/lib/laser/analysis/control_flow/cfg_builder.rb +2505 -0
  50. data/lib/laser/analysis/control_flow/cfg_instruction.rb +190 -0
  51. data/lib/laser/analysis/control_flow/constant_propagation.rb +742 -0
  52. data/lib/laser/analysis/control_flow/control_flow_graph.rb +370 -0
  53. data/lib/laser/analysis/control_flow/lifetime_analysis.rb +91 -0
  54. data/lib/laser/analysis/control_flow/method_call_search.rb +26 -0
  55. data/lib/laser/analysis/control_flow/raise_properties.rb +25 -0
  56. data/lib/laser/analysis/control_flow/simulation.rb +385 -0
  57. data/lib/laser/analysis/control_flow/static_single_assignment.rb +185 -0
  58. data/lib/laser/analysis/control_flow/unreachability_analysis.rb +57 -0
  59. data/lib/laser/analysis/control_flow/unused_variables.rb +91 -0
  60. data/lib/laser/analysis/control_flow/yield_properties.rb +103 -0
  61. data/lib/laser/analysis/errors.rb +131 -0
  62. data/lib/laser/analysis/laser_utils.rb +18 -0
  63. data/lib/laser/analysis/lexical_analysis.rb +172 -0
  64. data/lib/laser/analysis/method_call.rb +68 -0
  65. data/lib/laser/analysis/protocol_registry.rb +30 -0
  66. data/lib/laser/analysis/scope.rb +118 -0
  67. data/lib/laser/analysis/sexp.rb +159 -0
  68. data/lib/laser/analysis/sexp_analysis.rb +40 -0
  69. data/lib/laser/analysis/sexp_extensions/constant_extraction.rb +115 -0
  70. data/lib/laser/analysis/sexp_extensions/source_location.rb +164 -0
  71. data/lib/laser/analysis/sexp_extensions/type_inference.rb +47 -0
  72. data/lib/laser/analysis/signature.rb +76 -0
  73. data/lib/laser/analysis/special_methods/send.rb +67 -0
  74. data/lib/laser/analysis/unused_methods.rb +21 -0
  75. data/lib/laser/analysis/visitor.rb +141 -0
  76. data/lib/laser/annotation_parser/annotations.treetop +126 -0
  77. data/lib/laser/annotation_parser/annotations_parser.rb +748 -0
  78. data/lib/laser/annotation_parser/class_annotations.treetop +82 -0
  79. data/lib/laser/annotation_parser/class_annotations_parser.rb +654 -0
  80. data/lib/laser/annotation_parser/overload.treetop +24 -0
  81. data/lib/laser/annotation_parser/overload_parser.rb +167 -0
  82. data/lib/laser/annotation_parser/parsers.rb +6 -0
  83. data/lib/laser/annotation_parser/structural.treetop +37 -0
  84. data/lib/laser/annotation_parser/structural_parser.rb +406 -0
  85. data/lib/laser/annotation_parser/useful_parsers.treetop +47 -0
  86. data/lib/laser/annotation_parser/useful_parsers_parser.rb +674 -0
  87. data/lib/laser/rake/task.rb +46 -0
  88. data/lib/laser/runner.rb +189 -0
  89. data/lib/laser/scanner.rb +169 -0
  90. data/lib/laser/standard_library/_thread.rb +110 -0
  91. data/lib/laser/standard_library/abbrev.rb +103 -0
  92. data/lib/laser/standard_library/array.rb +418 -0
  93. data/lib/laser/standard_library/base64.rb +91 -0
  94. data/lib/laser/standard_library/basic_object.rb +55 -0
  95. data/lib/laser/standard_library/benchmark.rb +556 -0
  96. data/lib/laser/standard_library/bignum.rb +185 -0
  97. data/lib/laser/standard_library/cgi.rb +275 -0
  98. data/lib/laser/standard_library/cgi/cookie.rb +147 -0
  99. data/lib/laser/standard_library/cgi/core.rb +791 -0
  100. data/lib/laser/standard_library/cgi/html.rb +1021 -0
  101. data/lib/laser/standard_library/cgi/session.rb +537 -0
  102. data/lib/laser/standard_library/cgi/session/pstore.rb +111 -0
  103. data/lib/laser/standard_library/cgi/util.rb +188 -0
  104. data/lib/laser/standard_library/class_definitions.rb +333 -0
  105. data/lib/laser/standard_library/comparable.rb +125 -0
  106. data/lib/laser/standard_library/complex.rb +162 -0
  107. data/lib/laser/standard_library/enumerable.rb +178 -0
  108. data/lib/laser/standard_library/exceptions.rb +135 -0
  109. data/lib/laser/standard_library/fixnum.rb +188 -0
  110. data/lib/laser/standard_library/float.rb +180 -0
  111. data/lib/laser/standard_library/hash.rb +237 -0
  112. data/lib/laser/standard_library/integer.rb +123 -0
  113. data/lib/laser/standard_library/laser_magic.rb +7 -0
  114. data/lib/laser/standard_library/nil_false_true.rb +113 -0
  115. data/lib/laser/standard_library/numbers.rb +192 -0
  116. data/lib/laser/standard_library/proc.rb +31 -0
  117. data/lib/laser/standard_library/set.rb +1348 -0
  118. data/lib/laser/standard_library/string.rb +666 -0
  119. data/lib/laser/standard_library/stringio.rb +2 -0
  120. data/lib/laser/standard_library/symbol.rb +125 -0
  121. data/lib/laser/standard_library/tsort.rb +242 -0
  122. data/lib/laser/support/acts_as_struct.rb +66 -0
  123. data/lib/laser/support/frequency.rb +55 -0
  124. data/lib/laser/support/inheritable_attributes.rb +145 -0
  125. data/lib/laser/support/module_extensions.rb +94 -0
  126. data/lib/laser/support/placeholder_object.rb +13 -0
  127. data/lib/laser/third_party/rgl/adjacency.rb +221 -0
  128. data/lib/laser/third_party/rgl/base.rb +228 -0
  129. data/lib/laser/third_party/rgl/bidirectional.rb +39 -0
  130. data/lib/laser/third_party/rgl/condensation.rb +47 -0
  131. data/lib/laser/third_party/rgl/connected_components.rb +138 -0
  132. data/lib/laser/third_party/rgl/control_flow.rb +170 -0
  133. data/lib/laser/third_party/rgl/depth_first_spanning_tree.rb +37 -0
  134. data/lib/laser/third_party/rgl/dominators.rb +124 -0
  135. data/lib/laser/third_party/rgl/dot.rb +93 -0
  136. data/lib/laser/third_party/rgl/graphxml.rb +51 -0
  137. data/lib/laser/third_party/rgl/implicit.rb +174 -0
  138. data/lib/laser/third_party/rgl/mutable.rb +117 -0
  139. data/lib/laser/third_party/rgl/rdot.rb +445 -0
  140. data/lib/laser/third_party/rgl/topsort.rb +72 -0
  141. data/lib/laser/third_party/rgl/transitivity.rb +180 -0
  142. data/lib/laser/third_party/rgl/traversal.rb +348 -0
  143. data/lib/laser/types/types.rb +433 -0
  144. data/lib/laser/version.rb +14 -0
  145. data/lib/laser/warning.rb +149 -0
  146. data/lib/laser/warning_sets/default.yml +13 -0
  147. data/lib/laser/warnings/assignment_in_condition.rb +20 -0
  148. data/lib/laser/warnings/comment_spacing.rb +31 -0
  149. data/lib/laser/warnings/extra_blank_lines.rb +30 -0
  150. data/lib/laser/warnings/extra_whitespace.rb +16 -0
  151. data/lib/laser/warnings/hash_symbol_18_warning.rb +63 -0
  152. data/lib/laser/warnings/hash_symbol_19_warning.rb +29 -0
  153. data/lib/laser/warnings/line_length.rb +115 -0
  154. data/lib/laser/warnings/misaligned_unindentation.rb +17 -0
  155. data/lib/laser/warnings/operator_spacing.rb +68 -0
  156. data/lib/laser/warnings/parens_on_declaration.rb +30 -0
  157. data/lib/laser/warnings/rescue_exception.rb +42 -0
  158. data/lib/laser/warnings/semicolon.rb +25 -0
  159. data/lib/laser/warnings/sexp_errors.rb +24 -0
  160. data/lib/laser/warnings/uncalled_method_warning.rb +7 -0
  161. data/lib/laser/warnings/useless_double_quotes.rb +38 -0
  162. data/spec/analysis_specs/annotations_spec.rb +47 -0
  163. data/spec/analysis_specs/annotations_specs/comment_attachment_spec.rb +68 -0
  164. data/spec/analysis_specs/annotations_specs/node_pointers_annotation_spec.rb +90 -0
  165. data/spec/analysis_specs/annotations_specs/runtime_annotation_spec.rb +135 -0
  166. data/spec/analysis_specs/annotations_specs/spec_helper.rb +33 -0
  167. data/spec/analysis_specs/argument_expansion_spec.rb +113 -0
  168. data/spec/analysis_specs/bindings_spec.rb +36 -0
  169. data/spec/analysis_specs/comment_spec.rb +93 -0
  170. data/spec/analysis_specs/control_flow_specs/cfg_instruction_spec.rb +111 -0
  171. data/spec/analysis_specs/control_flow_specs/constant_propagation_spec.rb +560 -0
  172. data/spec/analysis_specs/control_flow_specs/control_flow_graph_spec.rb +5 -0
  173. data/spec/analysis_specs/control_flow_specs/raise_properties_spec.rb +310 -0
  174. data/spec/analysis_specs/control_flow_specs/raise_type_inference_spec.rb +301 -0
  175. data/spec/analysis_specs/control_flow_specs/return_type_inference_spec.rb +431 -0
  176. data/spec/analysis_specs/control_flow_specs/simulation_spec.rb +158 -0
  177. data/spec/analysis_specs/control_flow_specs/spec_helper.rb +110 -0
  178. data/spec/analysis_specs/control_flow_specs/tuple_misuse_inference_spec.rb +125 -0
  179. data/spec/analysis_specs/control_flow_specs/unreachability_analysis_spec.rb +76 -0
  180. data/spec/analysis_specs/control_flow_specs/unused_variable_spec.rb +99 -0
  181. data/spec/analysis_specs/control_flow_specs/yield_properties_spec.rb +372 -0
  182. data/spec/analysis_specs/error_spec.rb +30 -0
  183. data/spec/analysis_specs/laser_class_spec.rb +322 -0
  184. data/spec/analysis_specs/lexical_analysis_spec.rb +184 -0
  185. data/spec/analysis_specs/protocol_registry_spec.rb +63 -0
  186. data/spec/analysis_specs/scope_annotation_spec.rb +1013 -0
  187. data/spec/analysis_specs/scope_spec.rb +126 -0
  188. data/spec/analysis_specs/sexp_analysis_spec.rb +30 -0
  189. data/spec/analysis_specs/sexp_extension_specs/constant_extraction_spec.rb +309 -0
  190. data/spec/analysis_specs/sexp_extension_specs/source_location_spec.rb +231 -0
  191. data/spec/analysis_specs/sexp_extension_specs/spec_helper.rb +1 -0
  192. data/spec/analysis_specs/sexp_extension_specs/type_inference_spec.rb +252 -0
  193. data/spec/analysis_specs/sexp_spec.rb +167 -0
  194. data/spec/analysis_specs/spec_helper.rb +27 -0
  195. data/spec/analysis_specs/unused_methods_spec.rb +65 -0
  196. data/spec/analysis_specs/visitor_spec.rb +64 -0
  197. data/spec/annotation_parser_specs/annotations_parser_spec.rb +89 -0
  198. data/spec/annotation_parser_specs/class_annotation_parser_spec.rb +120 -0
  199. data/spec/annotation_parser_specs/overload_parser_spec.rb +39 -0
  200. data/spec/annotation_parser_specs/parsers_spec.rb +14 -0
  201. data/spec/annotation_parser_specs/spec_helper.rb +1 -0
  202. data/spec/annotation_parser_specs/structural_parser_spec.rb +67 -0
  203. data/spec/laser_spec.rb +14 -0
  204. data/spec/rake_specs/spec_helper.rb +1 -0
  205. data/spec/rake_specs/task_spec.rb +67 -0
  206. data/spec/runner_spec.rb +207 -0
  207. data/spec/scanner_spec.rb +75 -0
  208. data/spec/spec_helper.rb +121 -0
  209. data/spec/standard_library/exceptions_spec.rb +19 -0
  210. data/spec/standard_library/globals_spec.rb +14 -0
  211. data/spec/standard_library/set_spec.rb +31 -0
  212. data/spec/standard_library/spec_helper.rb +1 -0
  213. data/spec/standard_library/standard_library_spec.rb +302 -0
  214. data/spec/support_specs/acts_as_struct_spec.rb +94 -0
  215. data/spec/support_specs/frequency_spec.rb +23 -0
  216. data/spec/support_specs/module_extensions_spec.rb +117 -0
  217. data/spec/support_specs/spec_helper.rb +1 -0
  218. data/spec/type_specs/spec_helper.rb +1 -0
  219. data/spec/type_specs/types_spec.rb +133 -0
  220. data/spec/warning_spec.rb +95 -0
  221. data/spec/warning_specs/assignment_in_condition_spec.rb +68 -0
  222. data/spec/warning_specs/comment_spacing_spec.rb +65 -0
  223. data/spec/warning_specs/extra_blank_lines_spec.rb +70 -0
  224. data/spec/warning_specs/extra_whitespace_spec.rb +33 -0
  225. data/spec/warning_specs/hash_symbol_18_warning_spec.rb +89 -0
  226. data/spec/warning_specs/hash_symbol_19_warning_spec.rb +63 -0
  227. data/spec/warning_specs/line_length_spec.rb +173 -0
  228. data/spec/warning_specs/misaligned_unindentation_spec.rb +35 -0
  229. data/spec/warning_specs/operator_spacing_spec.rb +104 -0
  230. data/spec/warning_specs/parens_on_declaration_spec.rb +57 -0
  231. data/spec/warning_specs/rescue_exception_spec.rb +105 -0
  232. data/spec/warning_specs/semicolon_spec.rb +58 -0
  233. data/spec/warning_specs/spec_helper.rb +1 -0
  234. data/spec/warning_specs/useless_double_quotes_spec.rb +74 -0
  235. data/status_reports/2010/12/2010-12-14.md +163 -0
  236. data/status_reports/2010/12/2010-12-23.md +298 -0
  237. data/status_reports/2010/12/2010-12-24.md +6 -0
  238. data/test/third_party_tests/rgl_tests/TestComponents.rb +65 -0
  239. data/test/third_party_tests/rgl_tests/TestCycles.rb +61 -0
  240. data/test/third_party_tests/rgl_tests/TestDirectedGraph.rb +125 -0
  241. data/test/third_party_tests/rgl_tests/TestDot.rb +18 -0
  242. data/test/third_party_tests/rgl_tests/TestEdge.rb +34 -0
  243. data/test/third_party_tests/rgl_tests/TestGraph.rb +71 -0
  244. data/test/third_party_tests/rgl_tests/TestGraphXML.rb +57 -0
  245. data/test/third_party_tests/rgl_tests/TestImplicit.rb +52 -0
  246. data/test/third_party_tests/rgl_tests/TestRdot.rb +863 -0
  247. data/test/third_party_tests/rgl_tests/TestTransitivity.rb +129 -0
  248. data/test/third_party_tests/rgl_tests/TestTraversal.rb +220 -0
  249. data/test/third_party_tests/rgl_tests/TestUnDirectedGraph.rb +102 -0
  250. data/test/third_party_tests/rgl_tests/examples/north/Graph.log +128 -0
  251. data/test/third_party_tests/rgl_tests/examples/north/g.10.0.graphml +28 -0
  252. data/test/third_party_tests/rgl_tests/examples/north/g.10.1.graphml +28 -0
  253. data/test/third_party_tests/rgl_tests/examples/north/g.10.11.graphml +31 -0
  254. data/test/third_party_tests/rgl_tests/examples/north/g.10.12.graphml +27 -0
  255. data/test/third_party_tests/rgl_tests/examples/north/g.10.13.graphml +27 -0
  256. data/test/third_party_tests/rgl_tests/examples/north/g.10.14.graphml +27 -0
  257. data/test/third_party_tests/rgl_tests/examples/north/g.10.15.graphml +26 -0
  258. data/test/third_party_tests/rgl_tests/examples/north/g.10.16.graphml +26 -0
  259. data/test/third_party_tests/rgl_tests/examples/north/g.10.17.graphml +26 -0
  260. data/test/third_party_tests/rgl_tests/examples/north/g.10.19.graphml +37 -0
  261. data/test/third_party_tests/rgl_tests/examples/north/g.10.2.graphml +28 -0
  262. data/test/third_party_tests/rgl_tests/examples/north/g.10.20.graphml +38 -0
  263. data/test/third_party_tests/rgl_tests/examples/north/g.10.22.graphml +43 -0
  264. data/test/third_party_tests/rgl_tests/examples/north/g.10.24.graphml +30 -0
  265. data/test/third_party_tests/rgl_tests/examples/north/g.10.25.graphml +45 -0
  266. data/test/third_party_tests/rgl_tests/examples/north/g.10.27.graphml +38 -0
  267. data/test/third_party_tests/rgl_tests/examples/north/g.10.28.graphml +30 -0
  268. data/test/third_party_tests/rgl_tests/examples/north/g.10.29.graphml +38 -0
  269. data/test/third_party_tests/rgl_tests/examples/north/g.10.3.graphml +26 -0
  270. data/test/third_party_tests/rgl_tests/examples/north/g.10.30.graphml +34 -0
  271. data/test/third_party_tests/rgl_tests/examples/north/g.10.31.graphml +42 -0
  272. data/test/third_party_tests/rgl_tests/examples/north/g.10.34.graphml +42 -0
  273. data/test/third_party_tests/rgl_tests/examples/north/g.10.37.graphml +28 -0
  274. data/test/third_party_tests/rgl_tests/examples/north/g.10.38.graphml +38 -0
  275. data/test/third_party_tests/rgl_tests/examples/north/g.10.39.graphml +36 -0
  276. data/test/third_party_tests/rgl_tests/examples/north/g.10.4.graphml +26 -0
  277. data/test/third_party_tests/rgl_tests/examples/north/g.10.40.graphml +37 -0
  278. data/test/third_party_tests/rgl_tests/examples/north/g.10.41.graphml +37 -0
  279. data/test/third_party_tests/rgl_tests/examples/north/g.10.42.graphml +26 -0
  280. data/test/third_party_tests/rgl_tests/examples/north/g.10.45.graphml +28 -0
  281. data/test/third_party_tests/rgl_tests/examples/north/g.10.46.graphml +32 -0
  282. data/test/third_party_tests/rgl_tests/examples/north/g.10.5.graphml +31 -0
  283. data/test/third_party_tests/rgl_tests/examples/north/g.10.50.graphml +30 -0
  284. data/test/third_party_tests/rgl_tests/examples/north/g.10.56.graphml +29 -0
  285. data/test/third_party_tests/rgl_tests/examples/north/g.10.57.graphml +32 -0
  286. data/test/third_party_tests/rgl_tests/examples/north/g.10.58.graphml +32 -0
  287. data/test/third_party_tests/rgl_tests/examples/north/g.10.6.graphml +26 -0
  288. data/test/third_party_tests/rgl_tests/examples/north/g.10.60.graphml +32 -0
  289. data/test/third_party_tests/rgl_tests/examples/north/g.10.61.graphml +34 -0
  290. data/test/third_party_tests/rgl_tests/examples/north/g.10.62.graphml +34 -0
  291. data/test/third_party_tests/rgl_tests/examples/north/g.10.68.graphml +30 -0
  292. data/test/third_party_tests/rgl_tests/examples/north/g.10.69.graphml +32 -0
  293. data/test/third_party_tests/rgl_tests/examples/north/g.10.7.graphml +29 -0
  294. data/test/third_party_tests/rgl_tests/examples/north/g.10.70.graphml +26 -0
  295. data/test/third_party_tests/rgl_tests/examples/north/g.10.71.graphml +27 -0
  296. data/test/third_party_tests/rgl_tests/examples/north/g.10.72.graphml +28 -0
  297. data/test/third_party_tests/rgl_tests/examples/north/g.10.74.graphml +29 -0
  298. data/test/third_party_tests/rgl_tests/examples/north/g.10.75.graphml +29 -0
  299. data/test/third_party_tests/rgl_tests/examples/north/g.10.78.graphml +27 -0
  300. data/test/third_party_tests/rgl_tests/examples/north/g.10.79.graphml +34 -0
  301. data/test/third_party_tests/rgl_tests/examples/north/g.10.8.graphml +29 -0
  302. data/test/third_party_tests/rgl_tests/examples/north/g.10.80.graphml +34 -0
  303. data/test/third_party_tests/rgl_tests/examples/north/g.10.82.graphml +35 -0
  304. data/test/third_party_tests/rgl_tests/examples/north/g.10.83.graphml +32 -0
  305. data/test/third_party_tests/rgl_tests/examples/north/g.10.85.graphml +34 -0
  306. data/test/third_party_tests/rgl_tests/examples/north/g.10.86.graphml +34 -0
  307. data/test/third_party_tests/rgl_tests/examples/north/g.10.88.graphml +37 -0
  308. data/test/third_party_tests/rgl_tests/examples/north/g.10.89.graphml +29 -0
  309. data/test/third_party_tests/rgl_tests/examples/north/g.10.9.graphml +26 -0
  310. data/test/third_party_tests/rgl_tests/examples/north/g.10.90.graphml +32 -0
  311. data/test/third_party_tests/rgl_tests/examples/north/g.10.91.graphml +31 -0
  312. data/test/third_party_tests/rgl_tests/examples/north/g.10.92.graphml +26 -0
  313. data/test/third_party_tests/rgl_tests/examples/north/g.10.93.graphml +32 -0
  314. data/test/third_party_tests/rgl_tests/examples/north/g.10.94.graphml +34 -0
  315. data/test/third_party_tests/rgl_tests/examples/north/g.12.8.graphml +40 -0
  316. data/test/third_party_tests/rgl_tests/examples/north/g.14.9.graphml +36 -0
  317. data/test/third_party_tests/rgl_tests/test_helper.rb +7 -0
  318. data/test/third_party_tests/test_inheritable_attributes.rb +187 -0
  319. metadata +470 -0
@@ -0,0 +1,106 @@
1
+ module Laser
2
+ module Analysis
3
+ # Laser representation of a class. I named it LaserClass so it wouldn't
4
+ # clash with regular Class. This links the class to its protocol.
5
+ # It inherits from LaserModule to pull in everything but superclasses.
6
+ class LaserClass < LaserModule
7
+ attr_reader :subclasses
8
+
9
+ def initialize(klass = ClassRegistry['Class'], scope = Scope::GlobalScope,
10
+ full_path=(@name_set = :no; "#{klass.path}:Anonymous:#{object_id.to_s(16)}"))
11
+ @subclasses ||= []
12
+ # bootstrapping exception
13
+ unless ['Class', 'Module', 'Object', 'BasicObject'].include?(full_path)
14
+ @superclass = ClassRegistry['Object']
15
+ end
16
+ super # can yield, so must come last
17
+ end
18
+
19
+ def normal_class
20
+ return ClassRegistry['Class']
21
+ end
22
+
23
+ def singleton_class
24
+ return @singleton_class if @singleton_class
25
+ new_scope = ClosedScope.new(self.scope, nil)
26
+ @singleton_class = LaserSingletonClass.new(
27
+ ClassRegistry['Class'], new_scope, "Class:#{name}", self) do |new_singleton_class|
28
+ if superclass
29
+ new_singleton_class.superclass = superclass.singleton_class
30
+ else
31
+ new_singleton_class.superclass = ClassRegistry['Class']
32
+ end
33
+ end
34
+ @klass = @singleton_class
35
+ end
36
+
37
+ # Adds a subclass.
38
+ def add_subclass!(other)
39
+ subclasses << other
40
+ end
41
+
42
+ # Removes a subclass.
43
+ def remove_subclass!(other)
44
+ subclasses.delete other
45
+ end
46
+
47
+ def parent
48
+ @superclass
49
+ end
50
+
51
+ def superclass
52
+ current = @superclass
53
+ while current
54
+ if LaserModuleCopy === current
55
+ current = current.superclass
56
+ else
57
+ return current
58
+ end
59
+ end
60
+ end
61
+
62
+ # Sets the superclass, which handles registering/unregistering subclass
63
+ # ownership elsewhere in the inheritance tree
64
+ def superclass=(other)
65
+ if LaserModuleCopy === other # || LaserSingletonClass === self
66
+ @superclass = other
67
+ else
68
+ superclass.remove_subclass! self if superclass
69
+ @superclass = other
70
+ superclass.add_subclass! self
71
+ end
72
+ end
73
+
74
+ # The set of all superclasses (including the class itself). Excludes modules.
75
+ def superset
76
+ if superclass.nil?
77
+ then [self]
78
+ else [self] + superclass.superset
79
+ end
80
+ end
81
+
82
+ # The set of all superclasses (excluding the class itself)
83
+ def proper_superset
84
+ superset - [self]
85
+ end
86
+
87
+ # The set of all subclasses (including the class itself)
88
+ def subset
89
+ [self] + subclasses.map(&:subset).flatten
90
+ end
91
+
92
+ # The set of all subclasses (excluding the class itself)
93
+ def proper_subset
94
+ subset - [self]
95
+ end
96
+
97
+ def class_name
98
+ 'Class'
99
+ end
100
+
101
+ def inspect
102
+ "#<LaserClass: #{path} superclass=#{superclass.inspect}>"
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,255 @@
1
+ module Laser
2
+ module Analysis
3
+ # Laser representation of a method. This name is tweaked so it doesn't
4
+ # collide with ::Method.
5
+ class LaserMethod
6
+ extend ModuleExtensions
7
+ cattr_accessor_with_default :default_dispatched, true
8
+ attr_reader :name, :proc, :arglist
9
+ alias arguments arglist
10
+ attr_accessor :owner, :arity
11
+
12
+ def initialize(name, base_proc)
13
+ @name = name
14
+ @type_instantiations = {}
15
+ @proc = base_proc
16
+ @argument_annotations = nil
17
+ @dispatched = LaserMethod.default_dispatched
18
+ if base_proc # always true except some ugly test cases
19
+ @arglist = base_proc.arguments
20
+ @arity = Arity.for_arglist(@arglist)
21
+ else
22
+ @arglist = []
23
+ @arity = nil
24
+ end
25
+ yield self if block_given?
26
+ end
27
+
28
+ ################## Potentially Annotated Properties ######################
29
+
30
+ %w(special pure builtin predictable mutation annotated_return annotated_yield_usage
31
+ overloads annotated_raise_frequency raises).each do |attr|
32
+ define_method(attr) do
33
+ instance_variable_get("@#{attr}") || (self.proc ? self.proc.send(attr) : nil)
34
+ end
35
+ define_method("#{attr}=") do |val|
36
+ instance_variable_set("@#{attr}", val)
37
+ end
38
+ end
39
+
40
+ def overloads
41
+ @overloads || (self.proc ? self.proc.overloads : {})
42
+ end
43
+
44
+ def predictable
45
+ @predictable || (self.proc ? self.proc.predictable : true)
46
+ end
47
+
48
+ # Gets all annotations with the same name as an argument.
49
+ def argument_annotations
50
+ @argument_annotations ||=
51
+ if @proc
52
+ arguments.map do |arg|
53
+ @proc.annotations[arg.name] if @proc.annotations.has_key?(arg.name)
54
+ end.compact
55
+ else
56
+ []
57
+ end
58
+ end
59
+
60
+ def yield_type
61
+ return annotated_yield_usage if annotated_yield_usage
62
+ return @yield_type if @yield_type
63
+ if builtin
64
+ :ignored
65
+ else
66
+ master_cfg.analyze(method: self)
67
+ @yield_type = master_cfg.yield_type
68
+ end
69
+ end
70
+
71
+ def yield_arity
72
+ return @yield_arity if @yield_arity
73
+ master_cfg.analyze(method: self)
74
+ @yield_arity = master_cfg.yield_arity
75
+ end
76
+
77
+ def raise_frequency_for_types(self_type, arg_types = [], block_type = nil)
78
+ block_type ||= Types::NILCLASS
79
+ unless arg_types_unify_with_annotations?(arg_types)
80
+ return Frequency::ALWAYS
81
+ end
82
+ return annotated_raise_frequency if annotated_raise_frequency
83
+ return Frequency::MAYBE if builtin || special
84
+ cfg_for_types(self_type, arg_types, block_type).raise_frequency
85
+ end
86
+
87
+ def raise_type_for_types(self_type, arg_types = [], block_type = nil)
88
+ block_type ||= Types::NILCLASS
89
+ Laser.debug_puts("Calculating raise type for #{owner.name}##{name} with types "+
90
+ "#{self_type.inspect} #{arg_types.inspect} #{block_type.inspect}")
91
+ unless arg_types_unify_with_annotations?(arg_types)
92
+ return ClassRegistry['TypeError'].as_type # needs parameterization later
93
+ end
94
+ if raises
95
+ Laser.debug_puts("Raise type is annotated: #{self.raises.inspect}")
96
+ return self.raises
97
+ end
98
+ if builtin || special
99
+ if annotated_raise_frequency == Frequency::NEVER
100
+ self.raises = Types::EMPTY
101
+ Laser.debug_puts("Raise type is annotated: #{self.raises.inspect}")
102
+ return self.raises
103
+ end
104
+ Laser.debug_puts("Builtin/special: Types::TOP")
105
+ return Types::TOP
106
+ end
107
+ cfg_for_types(self_type, arg_types, block_type).raise_type
108
+ end
109
+
110
+ def return_type_for_types(self_type, arg_types = [], block_type = nil)
111
+ block_type ||= Types::NILCLASS
112
+ return annotated_return if annotated_return
113
+ unless overloads.empty?
114
+ return overload_for_arg_types(arg_types)
115
+ end
116
+ if builtin || special
117
+ return Types::TOP
118
+ end
119
+ result = cfg_for_types(self_type, arg_types, block_type).return_type
120
+ check_return_type_against_expectations(result)
121
+ result
122
+ end
123
+
124
+ def valid_arity?(num_args)
125
+ @arity ? @arity.include?(num_args) : true
126
+ end
127
+
128
+ def overload_for_arg_types(arg_types)
129
+ overloads.each do |overload_args, proc_type|
130
+ # compatible arg count
131
+ if overload_args.size == arg_types.size
132
+ # all types unify?
133
+ if overload_args.zip(arg_types).all? { |spec, concrete| Types.subtype?(concrete, spec) }
134
+ return proc_type.subtypes[1]
135
+ end
136
+ end
137
+ end
138
+ raise TypeError.new("No overload found for #{self.inspect} with arg types #{arg_types.inspect}")
139
+ end
140
+
141
+ # Checks if the given argument types correctly unify with any
142
+ # user-requested restrictions.
143
+ def arg_types_unify_with_annotations?(arg_types)
144
+ if argument_annotations.any?
145
+ # Match actual arguments against formal arguments
146
+ formal_assignments = assign_formals(arg_types)
147
+ # Check annotations for formals against actual types
148
+ argument_annotations.each do |note_list|
149
+ note_list.each do |type_annotation|
150
+ expected = type_annotation.type
151
+ given = formal_assignments[type_annotation.name]
152
+ # no given -> optional arg that's left out.
153
+ return false if given && !Types.subtype?(given, expected)
154
+ end
155
+ end
156
+ end
157
+ true
158
+ end
159
+
160
+ def check_return_type_against_expectations(return_type)
161
+ if (expectation = Types::EXPECTATIONS[self.name]) &&
162
+ !Types.subtype?(return_type, expectation)
163
+ @proc.ast_node.add_error(ImproperOverloadTypeError.new(
164
+ "All methods named #{self.name} should return a subtype of #{expectation.inspect}",
165
+ @proc.ast_node))
166
+ end
167
+ end
168
+
169
+ def dispatched?
170
+ @dispatched
171
+ end
172
+
173
+ def been_used!
174
+ @dispatched = true
175
+ end
176
+
177
+ def master_cfg
178
+ @master_cfg ||= @proc.ssa_cfg.tap do |cfg|
179
+ cfg.bind_self_type(Types::ClassType.new(owner.path, :covariant))
180
+ end
181
+ end
182
+
183
+ def cfg_for_types(self_type, arg_types = [], block_type = nil)
184
+ block_type ||= Types::NILCLASS
185
+ Laser.debug_puts("Calculating CFG(#{owner.name}##{name}, #{self_type.inspect}, #{arg_types.inspect}, #{block_type.inspect})")
186
+ @type_instantiations[[self_type, *arg_types, block_type]] ||= master_cfg.dup.tap do |cfg|
187
+ cfg.bind_self_type(self_type)
188
+ cfg.bind_formal_types(arg_types)
189
+ cfg.bind_block_type(block_type)
190
+ cfg.analyze(method: self)
191
+ end
192
+ end
193
+
194
+ def simulate_with_args(new_self, args, block, opts)
195
+ self_type = Utilities.type_for(new_self)
196
+ formal_types = args.map { |arg| Utilities.type_for(arg) }
197
+ block_type = Utilities.type_for(block)
198
+ cfg_for_types(self_type, formal_types, block_type).dup.simulate(
199
+ args, opts.merge(self: new_self,
200
+ method: self,
201
+ block: block,
202
+ start_block: @proc.start_block))
203
+ end
204
+
205
+ # Maps a sequence of objects (one per actual argument) to
206
+ # the corresponding formal argument.
207
+ def assign_formals(actual_objs)
208
+ args = arguments
209
+ result_array = []
210
+ num_required = args.count { |arg| arg.kind == :positional }
211
+ num_optional = actual_objs.size - num_required
212
+ current_arg = 0
213
+ current_actual = 0
214
+ rest = []
215
+ while num_required > 0 || num_optional > 0
216
+ next_arg = args[current_arg]
217
+ if next_arg.kind == :positional
218
+ result_array << [next_arg.name, actual_objs[current_actual]]
219
+ num_required -= 1
220
+ current_actual += 1
221
+ current_arg += 1
222
+ elsif next_arg.kind == :optional && num_optional > 0
223
+ result_array << [next_arg.name, actual_objs[current_actual]]
224
+ num_optional -= 1
225
+ current_actual += 1
226
+ current_arg += 1
227
+ elsif next_arg.kind == :optional && num_optional == 0
228
+ current_arg += 1
229
+ elsif next_arg.kind == :rest && num_optional > 0
230
+ rest << actual_objs[current_actual]
231
+ current_actual += 1
232
+ num_optional -= 1
233
+ elsif next_arg.kind == :rest
234
+ result_array << [next_arg.name, rest]
235
+ end
236
+ end
237
+ Hash[*result_array.flatten(1)]
238
+ end
239
+
240
+ def dup
241
+ result = LaserMethod.new(name, proc)
242
+ result.owner = self.owner
243
+ result.arity = self.arity
244
+ result
245
+ end
246
+
247
+ def refine_arity(new_arity)
248
+ return new_arity if @arity.nil?
249
+ new_begin = [new_arity.begin, @arity.begin].min
250
+ new_end = [new_arity.end, @arity.end].max
251
+ new_begin..new_end
252
+ end
253
+ end
254
+ end
255
+ end
@@ -0,0 +1,403 @@
1
+ module Laser
2
+ module Analysis
3
+ # Laser representation of a module. Named LaserModule to avoid naming
4
+ # conflicts. It has lists of methods, instance variables, and so on.
5
+ class LaserModule < LaserObject
6
+ attr_reader :binding, :superclass
7
+ attr_accessor :path
8
+ cattr_accessor_with_default :all_modules, []
9
+
10
+ def initialize(klass = ClassRegistry['Module'], scope = Scope::GlobalScope,
11
+ full_path=(@name_set = :no; "#{klass.path}:Anonymous:#{object_id.to_s(16)}"))
12
+ super(klass, scope, full_path.split('::').last)
13
+ full_path = submodule_path(full_path) if scope && scope.parent
14
+ validate_module_path!(full_path) unless LaserSingletonClass === self
15
+
16
+ @name_set = :yes unless @name_set == :no
17
+ @path = full_path
18
+ @instance_methods = {}
19
+ @visibility_table = {}
20
+ @constant_table = {}
21
+ @scope = scope
22
+ @ivar_types = {}
23
+ @superclass ||= nil
24
+ initialize_protocol
25
+ @binding = Bindings::ConstantBinding.new(name, self)
26
+ initialize_scope
27
+ yield self if block_given?
28
+ LaserModule.all_modules << self
29
+ end
30
+
31
+ def <=>(other)
32
+ if self == other
33
+ return 0
34
+ elsif ancestors.include?(other)
35
+ return -1
36
+ elsif other.ancestors.include?(self)
37
+ return 1
38
+ else
39
+ return nil
40
+ end
41
+ end
42
+
43
+ # including Comparable is having issues due to override of include. Do it
44
+ # ourselves.
45
+ %w(< <= >= >).each do |op|
46
+ class_eval %Q{
47
+ def #{op}(other)
48
+ cmp = self <=> other
49
+ cmp && cmp #{op} 0
50
+ end
51
+ }
52
+ end
53
+
54
+ def as_type
55
+ Types::ClassObjectType.new(self)
56
+ end
57
+
58
+ def name_set?
59
+ @name_set == :yes
60
+ end
61
+
62
+ def set_name(new_path)
63
+ @path = new_path
64
+ ProtocolRegistry.add_class(self)
65
+ @name_set = :yes
66
+ end
67
+
68
+ # Returns the canonical path for a (soon-to-be-created) submodule of the given
69
+ # scope. This is computed before creating the module.
70
+ def submodule_path(new_mod_name)
71
+ scope = self.scope.parent
72
+ new_mod_full_path = scope.parent.nil? ? '' : scope.path
73
+ new_mod_full_path += '::' unless new_mod_full_path.empty?
74
+ new_mod_full_path += new_mod_name
75
+ end
76
+
77
+ def validate_module_path!(path)
78
+ path.split('::').each do |component|
79
+ if !component.empty? && component[0,1] !~ /[A-Z]/
80
+ raise ArgumentError.new("Path component #{component} in #{path}" +
81
+ ' does not start with a capital letter, A-Z.')
82
+ end
83
+ end
84
+ end
85
+
86
+ def class_name
87
+ 'Module'
88
+ end
89
+
90
+ # If this is a new, custom module, we can update the constant
91
+ # table and perform module initialization.
92
+ def initialize_scope
93
+ if @scope && !(@scope.parent.nil?)
94
+ @scope.parent.constants[name] = self.binding if @scope.parent
95
+ @scope.locals['self'] = Bindings::LocalVariableBinding.new('self', self)
96
+ end
97
+ end
98
+
99
+ # Initializes the protocol for this LaserClass.
100
+ def initialize_protocol
101
+ if ProtocolRegistry[path].any? && !TESTS_ACTIVATED
102
+ $stderr.puts "Warning: creating new instance of #{class_name} #{path}"
103
+ else
104
+ ProtocolRegistry.add_class(self)
105
+ end
106
+ end
107
+
108
+ def name
109
+ self.path.split('::').last
110
+ end
111
+
112
+ def add_instance_method!(method)
113
+ @instance_methods[method.name.to_sym] = method
114
+ @visibility_table[method.name.to_sym] = :public
115
+ method.owner = self
116
+ end
117
+
118
+ def instance_method(name)
119
+ lookup = name.to_sym
120
+ if @instance_methods.has_key?(lookup)
121
+ then @instance_methods[lookup]
122
+ else @superclass && @superclass.instance_method(lookup)
123
+ end
124
+ end
125
+
126
+ def method_defined?(name)
127
+ instance_method(name) && visibility_for(name) != :private
128
+ end
129
+
130
+ def public_instance_method(name)
131
+ result = instance_method(name)
132
+ visibility_for(name) == :public ? result : nil
133
+ end
134
+
135
+ def __all_instance_methods(include_super = true)
136
+ mine = @instance_methods.keys
137
+ if include_super && @superclass
138
+ then @superclass.instance_methods | mine
139
+ else mine
140
+ end
141
+ end
142
+
143
+ def __instance_methods_with_privacy(include_super, *allowed)
144
+ methods = __all_instance_methods(include_super)
145
+ table = visibility_table
146
+ methods.select { |name| allowed.include?(table[name.to_sym]) }
147
+ end
148
+
149
+ def instance_methods(include_super = true)
150
+ __instance_methods_with_privacy(include_super, :public, :protected)
151
+ end
152
+
153
+ def public_instance_methods(include_super = true)
154
+ __instance_methods_with_privacy(include_super, :public)
155
+ end
156
+
157
+ def protected_instance_methods(include_super = true)
158
+ __instance_methods_with_privacy(include_super, :protected)
159
+ end
160
+
161
+ def protected_method_defined?(name)
162
+ !!__instance_methods_with_privacy(include_super, :protected)
163
+ end
164
+
165
+ def private_instance_methods(include_super = true)
166
+ __instance_methods_with_privacy(include_super, :private)
167
+ end
168
+
169
+ def ivar_type(name)
170
+ @ivar_types[name] || (@superclass && @superclass.ivar_type(name)) || Types::NILCLASS
171
+ end
172
+
173
+ def set_ivar_type(name, type)
174
+ @ivar_types[name] = type
175
+ end
176
+
177
+ def instance_variable(name)
178
+ @instance_variables[name] || (@superclass && @superclass.instance_variable(name))
179
+ end
180
+
181
+ def instance_variables
182
+ if @superclass.nil?
183
+ then @instance_variables
184
+ else @instance_variables.merge(@superclass.instance_variables)
185
+ end
186
+ end
187
+
188
+ def add_instance_variable!(binding)
189
+ @instance_variables[binding.name] = binding
190
+ end
191
+
192
+ def visibility_for(method)
193
+ lookup = method.to_sym
194
+ return @visibility_table[lookup] ||
195
+ (@superclass && @superclass.visibility_for(lookup))
196
+ end
197
+
198
+ def visibility_table
199
+ if @superclass
200
+ then @superclass.visibility_table.merge(@visibility_table)
201
+ else @visibility_table
202
+ end
203
+ end
204
+
205
+ def set_visibility!(method, visibility)
206
+ @visibility_table[method] = visibility
207
+ end
208
+
209
+ def superclass=(new_superclass)
210
+ @superclass = new_superclass
211
+ end
212
+
213
+ # The set of all superclasses (including the class itself)
214
+ def ancestors
215
+ if @superclass.nil?
216
+ then [self]
217
+ else [self] + @superclass.ancestors
218
+ end
219
+ end
220
+
221
+ def subset
222
+ [self]
223
+ end
224
+
225
+ def classes_including
226
+ @classes_including ||= []
227
+ end
228
+
229
+ def included_modules
230
+ ancestors.select { |mod| LaserModuleCopy === mod }
231
+ end
232
+
233
+ # Directly translated from MRI's C implementation in class.c:650
234
+ def include_module(mod)
235
+ if mod.klass == ClassRegistry['Class']
236
+ raise ArgumentError.new("Tried to include #{mod.name}, which should "+
237
+ " be a Module or Module subclass, not a " +
238
+ "#{mod.klass.name}.")
239
+ end
240
+ original_mod = mod
241
+ any_changes = false
242
+ current = self
243
+ while mod
244
+ superclass_seen = false
245
+ should_change = true
246
+ if mod == self
247
+ raise ArgumentError.new("Cyclic module inclusion: #{mod} mixed into #{self}")
248
+ end
249
+ ancestors.each do |parent|
250
+ case parent
251
+ when LaserModuleCopy
252
+ if parent == mod
253
+ current = parent unless superclass_seen
254
+ should_change = false
255
+ break
256
+ end
257
+ when LaserClass
258
+ superclass_seen = true
259
+ end
260
+ end
261
+ if should_change
262
+ new_super = (current.superclass = LaserModuleCopy.new(mod, current.ancestors[1]))
263
+ mod.classes_including << current
264
+ current = new_super
265
+ any_changes = true
266
+ end
267
+ mod = mod.superclass
268
+ end
269
+ unless any_changes
270
+ raise DoubleIncludeError.new("Included #{original_mod.path} into #{self.path}"+
271
+ " but it was already included.", nil)
272
+ end
273
+ end
274
+
275
+ def inspect
276
+ "#<LaserModule: #{path}>"
277
+ end
278
+
279
+ # simulation methods
280
+ def ===(other)
281
+ klass = (LaserObject === other ? other.klass : ClassRegistry[other.class.name])
282
+ klass.ancestors.include?(self)
283
+ end
284
+
285
+ def const_set(string, value)
286
+ @constant_table[string] = value
287
+ if LaserModule === value && !value.name_set?
288
+ if self == ClassRegistry['Object']
289
+ value.set_name(string)
290
+ else
291
+ value.set_name("#{@path}::#{string}")
292
+ end
293
+ end
294
+ end
295
+
296
+ def const_get(constant, inherit=true)
297
+ if inherit && superclass
298
+ @constant_table[constant] || superclass.const_get(constant, true)
299
+ elsif LaserClass === self
300
+ @constant_table[constant] or raise ArgumentError.new("Class #{@path} has no constant #{constant}")
301
+ else
302
+ (@constant_table[constant] || ClassRegistry['Object'].const_get(constant, false)) or
303
+ raise ArgumentError.new("Class #{@path} has no constant #{constant}")
304
+ end
305
+ end
306
+
307
+ # Fuck you, that's why
308
+ def const_defined?(constant, inherit=true)
309
+ !!const_get(constant, inherit)
310
+ rescue
311
+ false
312
+ end
313
+
314
+ def remove_const(sym)
315
+ @constant_table.delete(sym)
316
+ end
317
+
318
+ def define_method(name, proc)
319
+ str_name = name.to_s
320
+ name = name.to_sym
321
+ new_method = LaserMethod.new(str_name, proc)
322
+ new_method.owner = self
323
+ @instance_methods[name] = new_method
324
+ if Bootstrap::VISIBILITY_STACK.value.last == :module_function
325
+ __make_module_function__(name)
326
+ else
327
+ @visibility_table[name] = Bootstrap::VISIBILITY_STACK.value.last
328
+ end
329
+ new_method
330
+ end
331
+
332
+ def define_method_with_annotations(name, proc, opts={})
333
+ method = define_method(name, proc)
334
+ opts.each { |name, value| method.send("#{name}=", value) }
335
+ end
336
+
337
+ def undef_method(symbol)
338
+ sym = symbol.to_sym
339
+ @instance_methods[sym] = nil
340
+ @visibility_table[sym] = :undefined
341
+ end
342
+
343
+ def remove_method(symbol)
344
+ sym = symbol.to_sym
345
+ @instance_methods.delete(sym)
346
+ @visibility_table.delete(sym)
347
+ end
348
+
349
+ def alias_method(new, old)
350
+ newsym = new.to_sym
351
+ oldsym = old.to_sym
352
+ @instance_methods[newsym] = @instance_methods[oldsym]
353
+ @visibility_table[newsym] = @visibility_table[oldsym]
354
+ end
355
+
356
+ def include(*mods)
357
+ mods.reverse.each { |mod| include_module(mod) }
358
+ end
359
+
360
+ def extend(*mods)
361
+ singleton_class.include(*mods)
362
+ end
363
+
364
+ def __visibility_modifier__(args, kind)
365
+ if args.empty?
366
+ Bootstrap::VISIBILITY_STACK.value[-1] = kind
367
+ else
368
+ args.each { |method| set_visibility!(method.to_sym, kind) }
369
+ end
370
+ self
371
+ end
372
+
373
+ def __make_module_function__(method_name)
374
+ set_visibility!(method_name, :private)
375
+ found_method = instance_method(method_name).dup
376
+ singleton_class.add_instance_method!(found_method)
377
+ singleton_class.set_visibility!(method_name, :public)
378
+ end
379
+
380
+ def public(*args)
381
+ __visibility_modifier__(args, :public)
382
+ end
383
+
384
+ def protected(*args)
385
+ __visibility_modifier__(args, :protected)
386
+ end
387
+
388
+ def private(*args)
389
+ __visibility_modifier__(args, :private)
390
+ end
391
+
392
+ def module_function(*args)
393
+ if args.any?
394
+ args.each do |method|
395
+ __make_module_function__(method.to_sym)
396
+ end
397
+ else
398
+ Bootstrap::VISIBILITY_STACK.value[-1] = :module_function
399
+ end
400
+ end
401
+ end
402
+ end
403
+ end