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,370 @@
1
+ require 'laser/third_party/rgl/adjacency'
2
+ require 'laser/third_party/rgl/transitivity'
3
+ require 'laser/third_party/rgl/dominators'
4
+ module Laser
5
+ module Analysis
6
+ module ControlFlow
7
+ class ControlFlowGraph < RGL::ControlFlowGraph
8
+ include ConstantPropagation
9
+ include LifetimeAnalysis
10
+ include StaticSingleAssignment
11
+ include UnusedVariables
12
+ include UnreachabilityAnalysis
13
+ include AliasAnalysis
14
+ include YieldProperties
15
+ include MethodCallSearch
16
+ include RaiseProperties
17
+ include Simulation
18
+
19
+ RETURN_POSTDOMINATOR_NAME = 'Return'
20
+ YIELD_POSTDOMINATOR_NAME = 'YieldWithoutBlock'
21
+ EXCEPTION_POSTDOMINATOR_NAME = 'UncaughtException'
22
+ FAILURE_POSTDOMINATOR_NAME = 'Failure'
23
+
24
+ attr_accessor :root, :block_register, :final_exception, :final_return
25
+ attr_reader :formals, :uses, :definition, :constants, :live, :globals
26
+ attr_reader :yield_type, :raise_frequency, :in_ssa, :yield_arity
27
+ attr_reader :self_type, :formal_types, :block_type
28
+ attr_reader :all_cached_variables
29
+ # postdominator blocks for: all non-failed-yield exceptions, yield-failing
30
+ # exceptions, and all failure types.
31
+
32
+ # Initializes the control flow graph, potentially with a list of argument
33
+ # bindings. Those bindings will almost always be extracted from parsing
34
+ # an argument list of a method or block.
35
+ #
36
+ # formal_arguments: [ArgumentBinding]
37
+ def initialize(formal_arguments = [])
38
+ @in_ssa = false
39
+ @self_type = nil
40
+ @formal_types = nil
41
+ @block_type = nil
42
+ @block_register = nil
43
+ @all_cached_variables = Set.new
44
+ @live = Hash.new { |hash, temp| hash[temp] = Set.new }
45
+ @constants = {}
46
+ @globals = Set.new
47
+ @name_stack = Hash.new { |hash, temp| hash[temp] = [] }
48
+ @name_count = Hash.new { |hash, temp| hash[temp] = 0 }
49
+ @formals = formal_arguments
50
+ @yield_type = nil
51
+ @yield_arity = nil#Set.new([Arity::ANY])
52
+ @raise_frequency = Frequency::MAYBE
53
+ super()
54
+ end
55
+
56
+ def dup
57
+ copy = self.class.new
58
+ copy.initialize_dup(self)
59
+ copy
60
+ end
61
+
62
+ def initialize_dup(source)
63
+ @root = source.root
64
+ @in_ssa = source.in_ssa
65
+ @self_type = source.self_type
66
+ @formal_types = source.formal_types
67
+ @block_type = source.block_type
68
+ # we'll be duplicating temporaries, and since we need to know how
69
+ # our source data about temps (defs, uses, constants...) corresponds
70
+ # the duplicated temps, we'll need a hash to look them up.
71
+ temp_lookup = { Bootstrap::VISIBILITY_STACK => Bootstrap::VISIBILITY_STACK }
72
+ block_lookup = { source.enter => @enter, source.exit => @exit }
73
+ insn_lookup = Hash.new
74
+ # copy all vars defined in the body
75
+ source.all_cached_variables.each do |k|
76
+ copy = k.deep_dup
77
+ temp_lookup[k] = copy
78
+ @all_cached_variables << copy
79
+ end
80
+ self.block_register = temp_lookup[source.block_register]
81
+ self.final_exception = temp_lookup[source.final_exception]
82
+ self.final_return = temp_lookup[source.final_return]
83
+ # copy all formals and their mapping to initial bindings
84
+ @formals = source.formals.map do |formal|
85
+ temp_lookup[formal] = formal.deep_dup
86
+ end
87
+
88
+ new_blocks = source.vertices.reject { |v| TerminalBasicBlock === v }
89
+ new_blocks.map! do |block|
90
+ copy = block.duplicate_for_graph_copy(temp_lookup, insn_lookup)
91
+ block_lookup[block] = copy
92
+ copy
93
+ end
94
+
95
+ new_blocks.each do |new_block|
96
+ add_vertex new_block
97
+ end
98
+ source.each_edge do |u, v|
99
+ add_edge(block_lookup[u], block_lookup[v], u.get_flags(v))
100
+ end
101
+
102
+ # computed stuff we shouldn't lose:
103
+ # @globals
104
+ # @constants
105
+ # @live
106
+ # @formal_map
107
+ temp_lookup.each do |old, new|
108
+ new.definition = insn_lookup[old.definition]
109
+ new.uses = Set.new(old.uses.map { |insn| insn_lookup[insn] })
110
+ end
111
+ source.globals.each do |global|
112
+ @globals.add temp_lookup[global]
113
+ end
114
+ source.constants.each do |temp, value|
115
+ # no need to dup value, as these constants *MUST NOT* be mutated.
116
+ @constants[temp_lookup[temp]] = value
117
+ end
118
+ source.live.each do |temp, blocks|
119
+ @live[temp_lookup[temp]] = Set.new(blocks.map { |block| block_lookup[block] })
120
+ end
121
+ # Tiny hope this speeds anything up
122
+ temp_lookup.clear
123
+ block_lookup.clear
124
+ insn_lookup.clear
125
+ self
126
+ end
127
+
128
+ # Compares the graphs for equality. Relies on the basic blocks having unique
129
+ # names to simplify isomorphism comparisons. Unfortunately this means
130
+ # tests will have to know block names. Oh well.
131
+ def ==(other)
132
+ pairs = self.vertices.sort_by(&:name).zip(other.vertices.sort_by(&:name))
133
+ (pairs.all? do |v1, v2|
134
+ v1.name == v2.name && v1.instructions == v2.instructions
135
+ end) && (self.edges.sort == other.edges.sort)
136
+ end
137
+
138
+ def inspect
139
+ "<ControlFlowGraph num_verts=#{vertices.size}>"
140
+ end
141
+
142
+ def clear_analyses
143
+ all_variables.each do |temp|
144
+ temp.bind! UNDEFINED
145
+ temp.inferred_type = nil
146
+ end
147
+ vertices.each do |block|
148
+ block.successors.each do |succ|
149
+ block.remove_flag(succ, ControlFlowGraph::EDGE_EXECUTABLE)
150
+ end
151
+ end
152
+ end
153
+
154
+ def save_pretty_picture(fmt='png', dotfile='graph', params = {'shape' => 'box'})
155
+ write_to_graphic_file(fmt, dotfile, params)
156
+ end
157
+
158
+ def dotty(params = {'shape' => 'box'})
159
+ super
160
+ end
161
+
162
+ def raise_type
163
+ if !all_failure_postdominator || all_failure_postdominator.real_predecessors.empty?
164
+ Types::EMPTY
165
+ else
166
+ @final_exception.expr_type
167
+ end
168
+ end
169
+
170
+ def return_type
171
+ if (@exit.normal_predecessors & @exit.real_predecessors).empty?
172
+ Types::EMPTY
173
+ else
174
+ @final_return.expr_type
175
+ end
176
+ end
177
+
178
+ def real_self_type
179
+ @self_type || Types::TOP
180
+ end
181
+
182
+ def bind_self_type(new_self_type)
183
+ @self_type = new_self_type
184
+ end
185
+
186
+ def bound_argument_types?
187
+ !!@formal_types
188
+ end
189
+
190
+ def bound_arity
191
+ @formal_types.size
192
+ end
193
+
194
+ def real_formal_type(idx)
195
+ (@formal_types && @formal_types[idx]) || Types::TOP
196
+ end
197
+
198
+ def bind_formal_types(new_formal_types)
199
+ @formal_types = new_formal_types
200
+ end
201
+
202
+ def real_block_type
203
+ @block_type || Types::BLOCK
204
+ end
205
+
206
+ def bind_block_type(new_block_type)
207
+ @block_type = new_block_type
208
+ end
209
+
210
+ DEFAULT_ANALYSIS_OPTS = {optimize: true, simulate: true}
211
+ # Runs full analysis on the CFG. Puts it in SSA then searches for warnings.
212
+ def analyze(opts={})
213
+ opts = DEFAULT_ANALYSIS_OPTS.merge(opts)
214
+ # kill obvious dead code now.
215
+ perform_dead_code_discovery(true)
216
+ Laser.debug_puts('>>> Starting SSA Transformation <<<')
217
+ static_single_assignment_form unless @in_ssa
218
+ Laser.debug_puts('>>> Finished SSA Transformation <<<')
219
+ if @root.type == :program
220
+ Laser.debug_puts('>>> Starting Simulation <<<')
221
+ begin
222
+ simulate([], :mutation => true) if opts[:simulate]
223
+ rescue Simulation::NonDeterminismHappened => err
224
+ Laser.debug_puts('Note: Simulation was nondeterministic.')
225
+ rescue Simulation::SimulationNonterminationError => err
226
+ Laser.debug_puts('Note: Simulation was potentially nonterminating.')
227
+ end
228
+ Laser.debug_puts('>>> Finished Simulation <<<')
229
+ else
230
+ Laser.debug_puts('>>> Starting CP <<<')
231
+ perform_constant_propagation(opts)
232
+ Laser.debug_puts('>>> Finished CP <<<')
233
+ if opts[:optimize]
234
+ Laser.debug_puts('>>> Killing Unexecuted Edges <<<')
235
+ kill_unexecuted_edges
236
+ Laser.debug_puts('>>> Finished Killing Unexecuted Edges <<<')
237
+ Laser.debug_puts('>>> Pruning Totally Useless Blocks <<<')
238
+ prune_totally_useless_blocks
239
+ Laser.debug_puts('>>> Finished Pruning Totally Useless Blocks <<<')
240
+ Laser.debug_puts('>>> Dead Code Discovery <<<')
241
+ perform_dead_code_discovery
242
+ Laser.debug_puts('>>> Finished Dead Code Discovery <<<')
243
+ Laser.debug_puts('>>> Adding Unused Variable Warnings <<<')
244
+ add_unused_variable_warnings
245
+ Laser.debug_puts('>>> Finished Adding Unused Variable Warnings <<<')
246
+
247
+ if @root.type != :program
248
+ Laser.debug_puts('>>> Determining Yield Properties <<<')
249
+ find_yield_properties(opts)
250
+ Laser.debug_puts('>>> Finished Determining Yield Properties <<<')
251
+ end
252
+ Laser.debug_puts('>>> Determining Raise Properties <<<')
253
+ find_raise_properties
254
+ Laser.debug_puts('>>> Finished Determining Raise Properties <<<')
255
+ end
256
+ end
257
+ end
258
+
259
+ def debug_dotty
260
+ Laser.debug_dotty(self)
261
+ end
262
+
263
+ def all_errors
264
+ self.root.all_errors
265
+ end
266
+
267
+ # Returns the names of all variables in the graph
268
+ def all_variables
269
+ return @all_cached_variables unless @all_cached_variables.empty?
270
+ return @all_variables if @all_variables
271
+ result = Set.new
272
+ vertices.each do |vert|
273
+ vert.variables.each do |var|
274
+ result << var
275
+ end
276
+ end
277
+ @all_variables = result
278
+ end
279
+
280
+ def var_named(name)
281
+ all_variables.find { |x| x.name.start_with?(name) }
282
+ end
283
+
284
+ def return_postdominator
285
+ vertex_with_name(RETURN_POSTDOMINATOR_NAME)
286
+ end
287
+
288
+ def yield_fail_postdominator
289
+ vertex_with_name(YIELD_POSTDOMINATOR_NAME)
290
+ end
291
+
292
+ def exception_postdominator
293
+ vertex_with_name(EXCEPTION_POSTDOMINATOR_NAME)
294
+ end
295
+
296
+ def all_failure_postdominator
297
+ vertex_with_name(FAILURE_POSTDOMINATOR_NAME)
298
+ end
299
+
300
+ # Yields reachable vertices via depth-first-search on real edges
301
+ def reachable_vertices
302
+ vertices = Set[]
303
+ worklist = Set[self.enter]
304
+ while worklist.any?
305
+ block = worklist.pop
306
+ yield block if block_given?
307
+ block.real_successors.each do |succ|
308
+ worklist.add(succ) if vertices.add?(succ)
309
+ end
310
+ end
311
+ vertices
312
+ end
313
+
314
+ # Computes the variables reachable by DFSing the start node.
315
+ # This excludes variables defined in dead code.
316
+ def reachable_variables(block = @enter, visited = Set.new)
317
+ visited << block
318
+ block.real_successors.inject(block.variables) do |cur, succ|
319
+ if visited.include?(succ)
320
+ cur
321
+ else
322
+ cur | reachable_variables(succ, visited)
323
+ end
324
+ end
325
+ end
326
+
327
+ # Removes blocks that are not reachable and which go nowhere: they
328
+ # have no effect on the program.
329
+ def prune_totally_useless_blocks
330
+ vertices = self.to_a
331
+ vertices.each do |vertex|
332
+ if degree(vertex).zero?
333
+ remove_vertex(vertex)
334
+ end
335
+ end
336
+ end
337
+
338
+ def prune_unexecuted_blocks
339
+ kill_unexecuted_edges(true) # be ruthless
340
+ unreachable_vertices.each do |block|
341
+ block.instructions.each do |insn|
342
+ insn.operands.each { |op| op.uses -= ::Set[insn] }
343
+ end
344
+ remove_vertex block
345
+ end
346
+ end
347
+
348
+ # Marks all edges that are not executable as fake edges. That way, the
349
+ # postdominance of Exit is preserved, but dead code analysis will ignore
350
+ # them.
351
+ def kill_unexecuted_edges(remove=false)
352
+ killable = Set.new
353
+ each_edge do |u, v|
354
+ if !(is_executable?(u, v) || is_fake?(u, v))
355
+ killable << [u, v]
356
+ end
357
+ end
358
+ killable.each do |u, v|
359
+ if remove
360
+ remove_edge(u, v)
361
+ else
362
+ u.add_flag(v, EDGE_FAKE)
363
+ end
364
+ end
365
+ end
366
+
367
+ end
368
+ end
369
+ end
370
+ end
@@ -0,0 +1,91 @@
1
+ module Laser
2
+ module Analysis
3
+ module ControlFlow
4
+ # Methods for computing the lifetime of the variables in
5
+ # the control flow graph.
6
+ module LifetimeAnalysis
7
+ # Calculates Live for all global temps. Also calculates LiveOut.
8
+ # p.136 Morgan
9
+ def calculate_live
10
+ setup_lifetime
11
+ visit = Set.new
12
+ @live_out = Hash.new { |hash, key| hash[key] = Set.new }
13
+ @live.clear
14
+ @globals.each do |temp|
15
+ @live[temp] = live_worklist(temp)
16
+ visit.clear
17
+ @definition_blocks[temp].each do |eval_block|
18
+ find_live_visited(eval_block, visit, @live[temp])
19
+ end
20
+
21
+ @live[temp] &= visit
22
+ @live[temp].each do |block|
23
+ block.real_predecessors.each do |pred|
24
+ if visit.include?(pred)
25
+ @live_out[pred] << temp
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ # Computes LiveIn(T) forall Temps, Globals, and LiveKill(B) forall Blocks
35
+ # p.134, Morgan
36
+ def setup_lifetime
37
+ @globals = Set.new
38
+ exposed = Set.new
39
+ @live_in = Hash.new { |hash, key| hash[key] = Set.new }
40
+ @live_kill = Hash.new { |hash, key| hash[key] = Set.new }
41
+ @definition_blocks = Hash.new { |hash, key| hash[key] = Set.new }
42
+
43
+ vertices.each do |block|
44
+ exposed.clear
45
+ block.instructions.reverse_each do |ins|
46
+ targets = ins.explicit_targets
47
+ targets.each { |target| @definition_blocks[target] << block }
48
+ @live_kill[block] |= targets
49
+ exposed = (exposed - targets) | ins.operands
50
+ exposed << ins.block_operand if ins.block_operand
51
+ end
52
+ @globals |= exposed
53
+ exposed.each do |temp|
54
+ @live_in[temp] << block
55
+ end
56
+ end
57
+ end
58
+
59
+ # Computes the set of blocks in which the given temporary is alive at
60
+ # the beginning of the block. Uses setup_lifetime.
61
+ # p.134, Morgan
62
+ def live_worklist(temp)
63
+ worklist = Set.new(@live_in[temp])
64
+ result_live = Set.new(@live_in[temp])
65
+ until worklist.empty?
66
+ block = worklist.pop
67
+ block.real_predecessors.each do |pred|
68
+ if !@live_kill[pred].include?(temp) and !result_live.include?(pred)
69
+ result_live << pred
70
+ worklist << pred
71
+ end
72
+ end
73
+ end
74
+ result_live
75
+ end
76
+
77
+ # DFSes but ignores non-live blocks. Adds each block that is walked
78
+ # to the visit set. Used by calculate_live.
79
+ def find_live_visited(current, visit, live)
80
+ visit << current
81
+ current.real_successors.each do |block|
82
+ if live.include?(block) && !visit.include?(block)
83
+ find_live_visited(block, visit, live)
84
+ end
85
+ end
86
+ end
87
+
88
+ end # module LifetimeAnalysis
89
+ end # module ControlFlow
90
+ end # module Analysis
91
+ end # module Laser