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,34 @@
1
+ module Laser
2
+ module Analysis
3
+ # The arity of a method is an instance of Arity. It's basically a range
4
+ # with some helper methods.
5
+ class Arity < Range
6
+ # arguments: [Binding::Base]
7
+ def self.for_arglist(arguments)
8
+ min, max = 0, 0
9
+ arguments.each do |arg|
10
+ case arg.kind
11
+ when :positional
12
+ min += 1
13
+ max += 1
14
+ when :optional
15
+ max += 1
16
+ when :rest
17
+ max = Float::INFINITY
18
+ end
19
+ end
20
+ min..max
21
+ end
22
+
23
+ def initialize(range)
24
+ super(range.begin, range.end, range.exclude_end?)
25
+ end
26
+
27
+ def compatible?(other)
28
+ self.first <= other.last && other.first <= self.last
29
+ end
30
+ EMPTY = Arity.new(0..0)
31
+ ANY = Arity.new(0..Float::INFINITY)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,144 @@
1
+ module Laser
2
+ module Analysis
3
+ module Bindings
4
+ # This class represents a Base in Ruby. It may have a known type,
5
+ # class, value (if constant!), and a variety of other details.
6
+ class Base
7
+ include Comparable
8
+ attr_accessor :name, :annotated_type, :inferred_type, :ast_node, :uses
9
+ attr_accessor :definition, :self_owner
10
+ attr_reader :value
11
+
12
+ def initialize(name, value)
13
+ @name = name
14
+ @uses = Set.new
15
+ @definition = @self_owner = nil
16
+ @value = :uninitialized
17
+ bind!(value)
18
+ end
19
+
20
+ def deep_dup
21
+ result = self.class.new(@name, @value)
22
+ result.initialize_dup_deep(self)
23
+ result
24
+ end
25
+
26
+ # like initialize_dup, but manually called and deep copy.
27
+ def initialize_dup_deep(other)
28
+ @annotated_type = other.annotated_type.dup if other.annotated_type
29
+ @inferred_type = other.inferred_type.dup if other.inferred_type
30
+ @ast_node = other.ast_node # immutable
31
+ self
32
+ end
33
+
34
+ def expr_type
35
+ annotated_type || inferred_type || Types::ClassType.new(
36
+ (LaserObject === @value ? @value.klass.path : @value.class.name), :invariant)
37
+ end
38
+
39
+ def bind!(value)
40
+ if respond_to?(:validate_value)
41
+ validate_value(value)
42
+ end
43
+ @value = value
44
+ end
45
+
46
+ def <=>(other)
47
+ self.name <=> other.name
48
+ end
49
+
50
+ def scope
51
+ value.scope
52
+ end
53
+
54
+ def class_used
55
+ value.klass
56
+ end
57
+
58
+ def to_s
59
+ inspect
60
+ end
61
+
62
+ def inspect
63
+ "#<#{self.class.name.split('::').last}: #{name}>"
64
+ end
65
+ end
66
+
67
+ class BlockBinding < Base
68
+ attr_reader :argument_bindings, :ast_body
69
+ def initialize(name, value)
70
+ super(name, value)
71
+ end
72
+
73
+ def expr_type
74
+ Types::ClassObjectType.new('Proc')
75
+ end
76
+ end
77
+
78
+ class KeywordBinding < Base
79
+ private :bind!
80
+ end
81
+
82
+ # Constants have slightly different properties in their bindings: They shouldn't
83
+ # be rebound. However.... Ruby allows it. It prints a warning when the rebinding
84
+ # happens, but we should be able to detect this statically. Oh, and they can't be
85
+ # bound inside a method. That too is easily detected statically.
86
+ class ConstantBinding < Base
87
+ # Require an additional force parameter to rebind a Constant. That way, the user
88
+ # can configure whether rebinding counts as a warning or an error.
89
+ def bind!(val, force=false)
90
+ if @value != :uninitialized && !force
91
+ raise TypeError.new('Cannot rebind a constant binding without const_set')
92
+ end
93
+ super(val)
94
+ end
95
+ end
96
+
97
+ # We may want to track # of assignments/reads from local vars, so we should subclass
98
+ # Base for it.
99
+ class LocalVariableBinding < Base
100
+ end
101
+
102
+ class TemporaryBinding < Base
103
+ def non_ssa_name
104
+ name.rpartition('#').first
105
+ end
106
+ end
107
+
108
+ class InstanceVariableBinding < Base
109
+ end
110
+
111
+ # Possible extension ideas:
112
+ # - Initial definition point?
113
+ class GlobalVariableBinding < Base
114
+ end
115
+
116
+ class ArgumentBinding < Base
117
+ attr_reader :kind, :default_value_sexp
118
+ def initialize(name, value, kind, default_value = nil)
119
+ super(name, value)
120
+ @kind = kind
121
+ @default_value_sexp = default_value
122
+ end
123
+
124
+ def deep_dup
125
+ result = self.class.new(@name, @value, @kind, @default_value_sexp)
126
+ result.initialize_dup_deep(self)
127
+ end
128
+
129
+ def is_positional?
130
+ :positional == @kind
131
+ end
132
+ def is_optional?
133
+ :optional == @kind
134
+ end
135
+ def is_rest?
136
+ :rest == @kind
137
+ end
138
+ def is_block?
139
+ :block == @kind
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,298 @@
1
+ module Laser
2
+ module Analysis
3
+ UNDEFINED = PlaceholderObject.new('UNDEFINED')
4
+ VARYING = PlaceholderObject.new('VARYING')
5
+
6
+ # This module contains bootstrapping code. This initializes the first classes
7
+ # and modules that build up the meta-model (Class, Module, Object).
8
+ module Bootstrap
9
+ extend Analysis
10
+ VISIBILITY_STACK_NAME = '$#visibility_stack'
11
+ VISIBILITY_STACK = Bindings::GlobalVariableBinding.new(VISIBILITY_STACK_NAME, [:private])
12
+ EXCEPTION_STACK_NAME = '$#exception_stack'
13
+ EXCEPTION_STACK = Bindings::GlobalVariableBinding.new(EXCEPTION_STACK_NAME, [])
14
+ class BootstrappingError < StandardError; end
15
+ def self.bootstrap
16
+ object_class = LaserClass.new(nil, nil, 'Object')
17
+ ProtocolRegistry.add_class(object_class)
18
+ class_class = LaserClass.new(nil, nil, 'Class')
19
+ ProtocolRegistry.add_class(class_class)
20
+ module_class = LaserClass.new(nil, nil, 'Module')
21
+ ProtocolRegistry.add_class(module_class)
22
+ basic_object_class = LaserClass.new(nil, nil, 'BasicObject')
23
+ ProtocolRegistry.add_class(basic_object_class)
24
+ class_scope = ClosedScope.new(nil, class_class)
25
+ module_scope = ClosedScope.new(nil, module_class)
26
+ object_scope = ClosedScope.new(nil, object_class)
27
+ basic_object_scope = ClosedScope.new(nil, basic_object_class)
28
+ object_class.superclass = basic_object_class
29
+ module_class.superclass = object_class
30
+ class_class.superclass = module_class
31
+ main_object = LaserObject.new(object_class, nil, 'main')
32
+ global = ClosedScope.new(nil, main_object,
33
+ {'Object' => Bindings::ConstantBinding.new('Object', object_class),
34
+ 'Module' => Bindings::ConstantBinding.new('Module', module_class),
35
+ 'Class' => Bindings::ConstantBinding.new('Class', class_class),
36
+ 'BasicObject' => Bindings::ConstantBinding.new('BasicObject', basic_object_class) },
37
+ {'self' => main_object})
38
+ if Scope.const_defined?("GlobalScope")
39
+ raise BootstrappingError.new('GlobalScope has already been initialized')
40
+ else
41
+ global.lexical_target = object_class.binding
42
+ Scope.const_set("GlobalScope", global)
43
+ end
44
+ class_scope.parent = Scope::GlobalScope
45
+ module_scope.parent = Scope::GlobalScope
46
+ object_scope.parent = Scope::GlobalScope
47
+ basic_object_scope.parent = Scope::GlobalScope
48
+ basic_object_class.instance_eval { @scope = basic_object_scope }
49
+ object_class.instance_eval { @scope = object_scope }
50
+ module_class.instance_eval { @scope = module_scope }
51
+ class_class.instance_eval { @scope = class_scope }
52
+ object_class.const_set('BasicObject', basic_object_class)
53
+ object_class.const_set('Object', object_class)
54
+ object_class.const_set('Module', module_class)
55
+ object_class.const_set('Class', class_class)
56
+ basic_object_class.instance_eval { @klass = class_class }
57
+ object_class.instance_eval { @klass = class_class }
58
+ module_class.instance_eval { @klass = class_class }
59
+ class_class.instance_eval { @klass = class_class }
60
+
61
+ # Bootstrap order: core classes, then methods
62
+ bootstrap_literals
63
+ stub_core_methods
64
+ rescue StandardError => err
65
+ new_exception = BootstrappingError.new("Bootstrapping failed: #{err.message}")
66
+ new_exception.set_backtrace(err.backtrace)
67
+ raise new_exception
68
+ end
69
+
70
+ def self.bootstrap_magic
71
+ class_class = ClassRegistry['Class']
72
+ magic_class = LaserClass.new(
73
+ class_class, Scope::GlobalScope, 'Laser#Magic')
74
+ ClassRegistry['Object'].const_set('Laser#Magic', magic_class)
75
+ stub_method(magic_class.singleton_class, 'current_block', special: true, annotated_raise_frequency: Frequency::NEVER)
76
+ stub_method(magic_class.singleton_class, 'current_arity', special: true, annotated_raise_frequency: Frequency::NEVER)
77
+ stub_method(magic_class.singleton_class, 'current_argument', special: true, annotated_raise_frequency: Frequency::NEVER)
78
+ stub_method(magic_class.singleton_class, 'current_argument_range', special: true, annotated_raise_frequency: Frequency::NEVER)
79
+ stub_method(magic_class.singleton_class, 'current_exception', special: true, annotated_raise_frequency: Frequency::NEVER)
80
+ stub_method(magic_class.singleton_class, 'get_just_raised_exception', special: true, annotated_raise_frequency: Frequency::NEVER)
81
+ stub_method(magic_class.singleton_class, 'push_exception', special: true, mutation: true, annotated_return: Types::EMPTY, annotated_raise_frequency: Frequency::NEVER)
82
+ stub_method(magic_class.singleton_class, 'pop_exception', special: true, mutation: true, annotated_return: Types::EMPTY, annotated_raise_frequency: Frequency::NEVER)
83
+ stub_method(magic_class.singleton_class, 'current_self', special: true, annotated_raise_frequency: Frequency::NEVER)
84
+ stub_method(magic_class.singleton_class, 'get_global', special: true, annotated_raise_frequency: Frequency::NEVER)
85
+ stub_method(magic_class.singleton_class, 'set_global', special: true, mutation: true, annotated_raise_frequency: Frequency::NEVER)
86
+ stub_method(magic_class.singleton_class, 'responds?', special: true, annotated_raise_frequency: Frequency::NEVER)
87
+
88
+ ClassRegistry['Module'].instance_method(:const_defined?).annotated_return = Types::BOOLEAN
89
+ ClassRegistry['Module'].instance_method(:===).annotated_return = Types::BOOLEAN
90
+ ClassRegistry['Kernel'].instance_method(:eql?).annotated_return = Types::BOOLEAN
91
+ ClassRegistry['Kernel'].instance_method(:equal?).annotated_return = Types::BOOLEAN
92
+ ClassRegistry['Kernel'].instance_method(:raise).annotated_return = Types::EMPTY
93
+ ClassRegistry['Proc'].instance_method(:lexical_self=).annotated_return = Types::EMPTY
94
+
95
+ stub_global_vars
96
+ end
97
+
98
+ # Before we analyze any code, we need to create classes for all the
99
+ # literals that are in Ruby. Otherwise, when we see those literals,
100
+ # if we haven't yet created the class they are an instance of, shit
101
+ # will blow up.
102
+ def self.bootstrap_literals
103
+ global = Scope::GlobalScope
104
+ class_class = ClassRegistry['Class']
105
+ object_class = ClassRegistry['Object']
106
+ true_class = LaserSingletonClass.new(class_class, ClosedScope.new(Scope::GlobalScope, nil), 'TrueClass', 'true') do |klass|
107
+ klass.superclass = object_class
108
+ end
109
+ false_class = LaserSingletonClass.new(class_class, ClosedScope.new(Scope::GlobalScope, nil), 'FalseClass', 'false') do |klass|
110
+ klass.superclass = object_class
111
+ end
112
+ nil_class = LaserSingletonClass.new(class_class, ClosedScope.new(Scope::GlobalScope, nil), 'NilClass', 'nil') do |klass|
113
+ klass.superclass = object_class
114
+ end
115
+ object_class.const_set('TrueClass', true_class)
116
+ object_class.const_set('FalseClass', false_class)
117
+ object_class.const_set('NilClass', nil_class)
118
+
119
+ global.add_binding!(
120
+ Bindings::KeywordBinding.new('true', true_class.get_instance))
121
+ global.add_binding!(
122
+ Bindings::KeywordBinding.new('false', false_class.get_instance))
123
+ global.add_binding!(
124
+ Bindings::KeywordBinding.new('nil', nil_class.get_instance))
125
+
126
+ kernel_module = stub_toplevel_module('Kernel')
127
+ object_class.include(kernel_module)
128
+ stub_toplevel_class 'Proc'
129
+ stub_toplevel_class 'Array'
130
+ stub_toplevel_class 'String'
131
+ stub_toplevel_class 'Hash'
132
+ stub_toplevel_class 'Regexp'
133
+ stub_toplevel_class 'Range'
134
+ stub_toplevel_class 'Symbol'
135
+ stub_toplevel_class 'Numeric'
136
+ stub_toplevel_class 'Float', 'Numeric'
137
+ stub_toplevel_class 'Integer', 'Numeric'
138
+ stub_toplevel_class 'Fixnum', 'Integer'
139
+ stub_toplevel_class 'Bignum', 'Integer'
140
+ stub_toplevel_class 'Exception'
141
+ stub_toplevel_class 'StandardError', 'Exception'
142
+ stub_toplevel_class 'TypeError', 'StandardError'
143
+ # My specific tweaks
144
+ stub_toplevel_class 'LaserTypeErrorWrapper', 'TypeError'
145
+ stub_toplevel_class 'LaserReopenedClassAsModuleError', 'LaserTypeErrorWrapper'
146
+ stub_toplevel_class 'LaserReopenedModuleAsClassError', 'LaserTypeErrorWrapper'
147
+ stub_toplevel_class 'LaserSuperclassMismatchError', 'LaserTypeErrorWrapper'
148
+
149
+ stub_toplevel_class 'IO' # TODO(adgar): includes File::Constants and Enumerable...
150
+ end
151
+
152
+ def self.stub_core_methods
153
+ class_class = ClassRegistry['Class']
154
+ module_class = ClassRegistry['Module']
155
+ kernel_module = ClassRegistry['Kernel']
156
+ array_class = ClassRegistry['Array']
157
+ hash_class = ClassRegistry['Hash']
158
+ range_class = ClassRegistry['Range']
159
+ regexp_class = ClassRegistry['Regexp']
160
+ proc_class = ClassRegistry['Proc']
161
+ def hash_class.[](*args)
162
+ ::Hash[*args]
163
+ end
164
+ def array_class.[](*args)
165
+ ::Array[*args]
166
+ end
167
+ def array_class.new(*args)
168
+ ::Array.new(*args)
169
+ end
170
+ def range_class.new(*args)
171
+ ::Range.new(*args)
172
+ end
173
+ def regexp_class.new(*args)
174
+ ::Regexp.new(*args)
175
+ end
176
+ string_class = ClassRegistry['String']
177
+ stub_method(class_class.singleton_class, 'new', builtin: true, pure: true)
178
+ stub_method(class_class, 'superclass', builtin: true, pure: true, annotated_raise_frequency: Frequency::NEVER)
179
+ stub_method(class_class, 'new')
180
+ allocate_method = stub_method(class_class, 'allocate', special: true, pure: true, annotated_raise_frequency: Frequency::NEVER)
181
+ def allocate_method.return_type_for_types(self_type, arg_types, block_type)
182
+ unless arg_types.empty? && block_type == Types::NILCLASS
183
+ raise TypeError.new("Class#allocate takes no arguments and no block")
184
+ end
185
+ Types::ClassObjectType.new(self_type.possible_classes.first.get_instance)
186
+ end
187
+ stub_method(module_class, 'define_method', builtin: true, pure: true, mutation: true)
188
+ stub_method(module_class, 'define_method_with_annotations', builtin: true, pure: true, mutation: true)
189
+ stub_method(module_class.singleton_class, 'new', builtin: true, pure: true)
190
+ stub_method(module_class, 'const_defined?', builtin: true, annotated_raise_frequency: Frequency::NEVER)
191
+ stub_method(module_class, 'const_set', builtin: true, mutation: true)
192
+ stub_method(module_class, 'const_get', builtin: true)
193
+ stub_method(module_class, '===', builtin: true, pure: true, annotated_raise_frequency: Frequency::NEVER)
194
+ stub_method(kernel_module, 'eql?', builtin: true, pure: true,
195
+ annotated_raise_frequency: Frequency::NEVER)
196
+ stub_method(kernel_module, 'equal?', builtin: true, pure: true,
197
+ annotated_raise_frequency: Frequency::NEVER)
198
+ stub_method(kernel_module, 'singleton_class', builtin: true, pure: true,
199
+ annotated_raise_frequency: Frequency::NEVER)
200
+ stub_custom_method(kernel_module, SpecialMethods::SendMethod, 'send', :any, special: true)
201
+ stub_custom_method(kernel_module, SpecialMethods::SendMethod, 'public_send', :public, special: true)
202
+
203
+ raise_method = stub_method(kernel_module, 'raise', builtin: true, pure: true,
204
+ annotated_raise_frequency: Frequency::ALWAYS)
205
+ def raise_method.raise_type_for_types(self_type, arg_types, block_type)
206
+ Types::UnionType.new(arg_types[0].possible_classes.map do |arg_class|
207
+ if arg_class <= ClassRegistry['String']
208
+ ClassRegistry['RuntimeError'].as_type
209
+ elsif LaserSingletonClass === arg_class && arg_class < ClassRegistry['Class']
210
+ arg_class.get_instance.as_type
211
+ elsif arg_class <= ClassRegistry['Exception']
212
+ arg_class.as_type
213
+ elsif arg_class.instance_method_defined?('exception')
214
+ arg_class.instance_method(:exception).return_type_for_types(arg_class.as_type)
215
+ end
216
+ end)
217
+ end
218
+ stub_method(array_class, 'push', builtin: true, mutation: true, annotated_raise_frequency: Frequency::NEVER)
219
+ stub_method(array_class, 'pop', builtin: true, mutation: true, annotated_raise_frequency: Frequency::NEVER)
220
+ stub_method(array_class.singleton_class, '[]', builtin: true, pure: true, annotated_raise_frequency: Frequency::NEVER)
221
+ stub_method(hash_class.singleton_class, '[]', builtin: true, pure: true)
222
+ stub_method(string_class, '+', builtin: true, pure: true)
223
+ stub_method(proc_class, 'lexical_self=', builtin: true, mutation: true, annotated_raise_frequency: Frequency::NEVER)
224
+ end
225
+
226
+ def self.stub_global_vars
227
+ Scope::GlobalScope.add_binding!(Bindings::GlobalVariableBinding.new('$:',
228
+ ['.', File.expand_path(File.join(Laser::ROOT, 'laser', 'standard_library'))]))
229
+ Scope::GlobalScope.add_binding!(Bindings::GlobalVariableBinding.new('$"', []))
230
+ Scope::GlobalScope.add_binding!(VISIBILITY_STACK)
231
+
232
+ stub_global_type('$0', Types::STRING)
233
+ stub_global_type('$*', Types::ARRAY)
234
+ stub_global_type('$$', Types::FIXNUM) # I hope pids fit in a fixnum
235
+ stub_global_type('$.', Types::FIXNUM)
236
+ stub_global_type('$&', Types.optional(Types::STRING))
237
+ stub_global_type('$`', Types.optional(Types::STRING))
238
+ stub_global_type("$'", Types.optional(Types::STRING))
239
+ end
240
+
241
+ def self.load_standard_library
242
+ LaserMethod.default_dispatched = true
243
+ %w(class_definitions.rb).map do |file|
244
+ path = File.join(Laser::ROOT, 'laser', 'standard_library', file)
245
+ [path, File.read(path)]
246
+ end.tap do |tuples|
247
+ begin
248
+ trees = Annotations.annotate_inputs(tuples, optimize: false)
249
+ trees.each do |filename, tree|
250
+ if tree.all_errors != []
251
+ $stderr.puts "Default file #{filename} had these errors:"
252
+ PP.pp(tree.all_errors, $stderr)
253
+ exit 1
254
+ end
255
+ end
256
+ rescue StandardError => err
257
+ puts "Loading class definitions failed:"
258
+ p err.message
259
+ pp err
260
+ pp err.backtrace
261
+ end
262
+ end
263
+ # All methods from here on out will need to be used, or a warning will be issued.
264
+ LaserMethod.default_dispatched = false
265
+ end
266
+
267
+ def self.stub_method(klass, name, opts={})
268
+ stub_custom_method(klass, LaserMethod, name, nil, opts)
269
+ end
270
+
271
+ def self.stub_custom_method(klass, custom_class, *init_args, opts)
272
+ method = custom_class.new(*init_args)
273
+ opts.each { |k, v| method.send("#{k}=", v) }
274
+ klass.add_instance_method!(method)
275
+ method
276
+ end
277
+
278
+ def self.stub_toplevel_class(name, superclass_name='Object')
279
+ klass = LaserClass.new(ClassRegistry['Class'], ClosedScope.new(Scope::GlobalScope, nil), name) do |klass|
280
+ klass.superclass = ClassRegistry[superclass_name]
281
+ end
282
+ ClassRegistry['Object'].const_set(name, klass)
283
+ klass
284
+ end
285
+
286
+ def self.stub_toplevel_module(name)
287
+ # i say "module" like "mojule" anyway, so i'll use that as the misspelling
288
+ mojule = LaserModule.new
289
+ ClassRegistry['Object'].const_set(name, mojule)
290
+ mojule
291
+ end
292
+
293
+ def self.stub_global_type(name, type)
294
+ Scope::GlobalScope.lookup(name).inferred_type = type
295
+ end
296
+ end
297
+ end
298
+ end