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,164 @@
1
+ module Laser::Analysis
2
+ module SexpExtensions
3
+ module SourceLocation
4
+
5
+ def line_number
6
+ source_begin && source_begin[0]
7
+ end
8
+
9
+ # Calculates, with some lossiness, the start position of the current node
10
+ # in the original text. This will sometimes fail, as the AST does not include
11
+ # sufficient information in many cases to determine where a node lies. We
12
+ # have to figure it out based on nearby identifiers and keywords.
13
+ def source_begin
14
+ return @source_begin if @source_begin
15
+ default_result = children.select { |child| Sexp === child }.
16
+ map(&:source_begin).compact.first
17
+ @source_begin =
18
+ case type
19
+ when :@ident, :@int, :@kw, :@float, :@tstring_content, :@regexp_end,
20
+ :@ivar, :@cvar, :@gvar, :@const, :@label, :@CHAR, :@op
21
+ children[1]
22
+ when :regexp_literal
23
+ result = default_result.dup
24
+ if backtrack_expecting!(result, -1, '/') || backtrack_expecting!(result, -3, '%r')
25
+ result
26
+ end
27
+ when :string_literal
28
+ if default_result
29
+ result = default_result.dup # make a copy we can mutate
30
+ if backtrack_expecting!(result, -1, "'") ||
31
+ backtrack_expecting!(result, -1, '"') ||
32
+ backtrack_expecting!(result, -3, '%q') ||
33
+ backtrack_expecting!(result, -3, '%Q')
34
+ result
35
+ end
36
+ end
37
+ when :string_embexpr
38
+ if default_result
39
+ result = default_result.dup
40
+ result[1] -= 2
41
+ result
42
+ end
43
+ when :dyna_symbol
44
+ if default_result
45
+ result = default_result.dup
46
+ result[1] -= 2
47
+ result
48
+ end
49
+ when :symbol_literal
50
+ result = default_result.dup
51
+ result[1] -= 1
52
+ result
53
+ when :hash
54
+ backtrack_searching(default_result, '{') if default_result
55
+ when :array
56
+ backtrack_searching(default_result, '[') if default_result
57
+ when :def, :defs
58
+ backtrack_searching(default_result, 'def')
59
+ when :class, :sclass
60
+ backtrack_searching(default_result, 'class')
61
+ when :module
62
+ backtrack_searching(default_result, 'module')
63
+ else
64
+ default_result
65
+ end
66
+ end
67
+
68
+ # Calculates, with some lossiness, the end position of the current node
69
+ # in the original text. This will sometimes fail, as the AST does not include
70
+ # sufficient information in many cases to determine where a node ends. We
71
+ # have to figure it out based on nearby identifiers, keywords, and literals.
72
+ def source_end
73
+ default_result = children.select { |child| Sexp === child }.
74
+ map(&:source_end).compact.last
75
+ case type
76
+ when :@ident, :@int, :@kw, :@float, :@tstring_content, :@regexp_end,
77
+ :@ivar, :@cvar, :@gvar, :@const, :@label, :@CHAR, :@op
78
+ text, location = children
79
+ source_end = location.dup
80
+ source_end[1] += text.size
81
+ source_end
82
+ when :string_literal
83
+ if source_begin
84
+ result = default_result.dup
85
+ result[1] += 1
86
+ result
87
+ end
88
+ when :string_embexpr, :dyna_symbol
89
+ if default_result
90
+ result = default_result.dup
91
+ result[1] += 1
92
+ result
93
+ end
94
+ when :hash
95
+ forwardtrack_searching(default_result, '}') if default_result
96
+ when :array
97
+ forwardtrack_searching(default_result, ']') if default_result
98
+ else
99
+ default_result
100
+ end
101
+ end
102
+
103
+ # Searches for the given text starting at the given location, going backwards.
104
+ # Modifies the location to match the discovered expected text on success.
105
+ #
106
+ # complexity: O(N) wrt input source
107
+ # location: [Fixnum, Fixnum]
108
+ # expectation: String
109
+ # returns: Boolean
110
+ def backtrack_searching(location, expectation)
111
+ result = location.dup
112
+ line = lines[result[0] - 1]
113
+ begin
114
+ if (expectation_location = line.rindex(expectation, result[1]))
115
+ result[1] = expectation_location
116
+ return result
117
+ end
118
+ result[0] -= 1
119
+ line = lines[result[0] - 1]
120
+ result[1] = line.size
121
+ end while result[0] >= 0
122
+ location
123
+ end
124
+
125
+ # Searches for the given text starting at the given location, going backwards.
126
+ # Modifies the location to match the discovered expected text on success.
127
+ #
128
+ # complexity: O(N) wrt input source
129
+ # location: [Fixnum, Fixnum]
130
+ # expectation: String
131
+ # returns: Boolean
132
+ def forwardtrack_searching(location, expectation)
133
+ result = location.dup
134
+ line = lines[result[0] - 1]
135
+ begin
136
+ if (expectation_location = line.index(expectation, result[1]))
137
+ result[1] = expectation_location + expectation.size
138
+ return result
139
+ end
140
+ result[0] += 1
141
+ result[1] = 0
142
+ line = lines[result[0] - 1]
143
+ end while result[0] <= lines.size
144
+ location
145
+ end
146
+
147
+ # Attempts to backtrack for the given string from the given location.
148
+ # Returns true if successful.
149
+ def backtrack_expecting!(location, offset, expectation)
150
+ if text_at(location, offset, expectation.length) == expectation
151
+ location[1] += offset
152
+ true
153
+ end
154
+ end
155
+
156
+ # Determines the text at the given location tuple, with some offset,
157
+ # and a given length.
158
+ def text_at(location, offset, length)
159
+ line = lines[location[0] - 1]
160
+ line[location[1] + offset, length]
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,47 @@
1
+ module Laser::Analysis
2
+ module SexpExtensions
3
+ module TypeInference
4
+ # Finds the type of the AST node. This depends on the node's scope sometimes,
5
+ # and always upon its node type.
6
+ def expr_type
7
+ case self.type
8
+ when :string_literal, :@CHAR, :@tstring_content, :string_embexpr, :string_content,
9
+ :xstring_literal
10
+ Types::ClassObjectType.new('String')
11
+ when :@int
12
+ Types::ClassType.new('Integer', :covariant)
13
+ when :@float
14
+ Types::ClassObjectType.new('Float')
15
+ when :regexp_literal
16
+ @expr_type ||= Types::ClassObjectType.new('Regexp')
17
+ when :hash, :bare_assoc_hash
18
+ @expr_type ||= Types::ClassObjectType.new('Hash')
19
+ when :symbol_literal, :dyna_symbol, :@label
20
+ Types::ClassObjectType.new('Symbol')
21
+ when :array
22
+ Types::ClassObjectType.new('Array')
23
+ when :dot2, :dot3
24
+ Types::ClassObjectType.new('Range')
25
+ when :lambda
26
+ Types::ClassObjectType.new('Proc')
27
+ when :var_ref
28
+ ref = self[1]
29
+ if ref.type == :@kw && ref.expanded_identifier != 'self'
30
+ case ref[1]
31
+ when 'nil' then Types::ClassObjectType.new('NilClass')
32
+ when 'true' then Types::ClassObjectType.new('TrueClass')
33
+ when 'false' then Types::ClassObjectType.new('FalseClass')
34
+ when '__FILE__' then Types::ClassObjectType.new('String')
35
+ when '__LINE__' then Types::ClassObjectType.new('Fixnum')
36
+ when '__ENCODING__' then Types::ClassObjectType.new('Encoding')
37
+ end
38
+ else
39
+ self.scope.lookup(expanded_identifier).expr_type rescue Types::TOP
40
+ end
41
+ else
42
+ Laser::Types::TOP
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,76 @@
1
+ module Laser
2
+ module Analysis
3
+ module ArgumentListHandling
4
+ # Returns the hash representing the arguments in a signature, based on an
5
+ # argument list (:params) from the parser.
6
+ #
7
+ # @param Sexp arglist
8
+ # @return Symbol => Argument
9
+ def arg_list_for_arglist(arglist)
10
+ arglist = arglist.deep_find { |node| node.type == :params }
11
+ positional_1, optionals, rest_arg, positional_2, block_arg = arglist.children
12
+ arg_list = []
13
+
14
+ arg_list.concat parse_positionals(positional_1) if positional_1
15
+ arg_list.concat parse_optionals(optionals) if optionals
16
+ arg_list << parse_rest_arg(rest_arg) if rest_arg
17
+ arg_list.concat parse_positionals(positional_2) if positional_2
18
+ arg_list << parse_block_arg(block_arg) if block_arg
19
+ arg_list
20
+ end
21
+
22
+ # Adds the positional arguments to the argument hash/list.
23
+ #
24
+ # current_arg_hash: (Symbol => Argument)
25
+ # positional_list: Array<Sexp>
26
+ # return: Array<Bindings::ArgumentBinding>
27
+ def parse_positionals(positional_list)
28
+ positional_list.map do |node|
29
+ tag, name, lex = node
30
+ result = Bindings::ArgumentBinding.new(name, LaserObject.new(ClassRegistry['BasicObject']), :positional)
31
+ result.ast_node = node
32
+ result
33
+ end
34
+ end
35
+
36
+ # Parses a list of optional arguments in Sexp form and adds them
37
+ # to the argument hash.
38
+ #
39
+ # current_arg_hash: (Symbol => Argument)
40
+ # optionals: Array<Sexp>
41
+ def parse_optionals(optionals)
42
+ optionals.map do |node|
43
+ id, default_value = node
44
+ result = Bindings::ArgumentBinding.new(id.children.first, LaserObject.new(ClassRegistry['BasicObject']), :optional, default_value)
45
+ result.ast_node = node
46
+ result
47
+ end
48
+ end
49
+
50
+ # Parses the rest argument of an argument list Sexp and adds it to
51
+ # the argument hash.
52
+ #
53
+ # rest_arg: Sexp
54
+ def parse_rest_arg(rest_arg)
55
+ result = Bindings::ArgumentBinding.new(rest_arg[1][1], LaserObject.new(ClassRegistry['Array']), :rest)
56
+ result.ast_node = rest_arg
57
+ result
58
+ end
59
+
60
+ # Parses the block argument of an argument list Sexp and adds it to
61
+ # the argument hash.
62
+ #
63
+ # block_arg: Sexp
64
+ def parse_block_arg(block_arg)
65
+ result = Bindings::ArgumentBinding.new(block_arg[1][1], LaserObject.new(ClassRegistry['Proc']), :block)
66
+ result.ast_node = block_arg
67
+ result
68
+ end
69
+ end
70
+
71
+ module Signature
72
+ include Comparable
73
+ extend ArgumentListHandling
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,67 @@
1
+ module Laser
2
+ module Analysis
3
+ module SpecialMethods
4
+ # Provides precise analysis of send methods. This is necessary for the
5
+ # analyzer to be able to tell where to look for semantic information when
6
+ # it encounters a call like this:
7
+ #
8
+ # method = unprovable_condition ? :foo : :bar
9
+ # send(method, 1, 2, 3)
10
+ #
11
+ # In this case, send() will return the union of whatever foo or bar return,
12
+ # and so on.
13
+ #
14
+ # This method supports both Kernel#send and Kernel#public_send.
15
+ class SendMethod < LaserMethod
16
+ def initialize(name, privacy)
17
+ super(name, nil)
18
+ @privacy = privacy
19
+ end
20
+
21
+ def each_target_method(self_type, arg_type)
22
+ arg_type.possible_classes.each do |target_klass|
23
+ if LaserSingletonClass === target_klass
24
+ target_method_name = target_klass.get_instance.to_s
25
+ self_type.possible_classes.each do |self_class|
26
+ if passes_visibility?(self_class, target_method_name)
27
+ method = self_class.instance_method(target_method_name)
28
+ method.been_used!
29
+ yield(method)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ def passes_visibility?(klass, name)
37
+ return true if @privacy == :any
38
+ klass.visibility_for(name) == @privacy
39
+ end
40
+
41
+ def collect_type_from_targets(to_call, self_type, arg_types, block_type)
42
+ result_type = Types::UnionType.new([])
43
+ each_target_method(self_type, arg_types[0]) do |method|
44
+ result_type |= method.send(to_call, self_type, arg_types[1..-1], block_type)
45
+ end
46
+ result_type
47
+ end
48
+
49
+ def return_type_for_types(self_type, arg_types, block_type)
50
+ collect_type_from_targets(:return_type_for_types, self_type, arg_types, block_type)
51
+ end
52
+
53
+ def raise_type_for_types(self_type, arg_types, block_type)
54
+ collect_type_from_targets(:raise_type_for_types, self_type, arg_types, block_type)
55
+ end
56
+
57
+ def raise_frequency_for_types(self_type, arg_types, block_type)
58
+ all_frequencies = []
59
+ each_target_method(self_type, arg_types[0]) do |method|
60
+ all_frequencies << method.raise_frequency_for_types(self_type, arg_types[1..-1], block_type)
61
+ end
62
+ Frequency.combine_samples(all_frequencies)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,21 @@
1
+ module Laser
2
+ module Analysis
3
+ module UnusedMethodDetection
4
+ def self.unused_methods
5
+ methods = []
6
+ classes = Set[]
7
+ Analysis::ProtocolRegistry.class_protocols.each do |key, klass|
8
+ next if Analysis::LaserSingletonClass === klass || classes.include?(klass)
9
+ klass.__all_instance_methods(false).each do |name|
10
+ method = klass.instance_method(name)
11
+ unless method.dispatched? || method.builtin || method.special
12
+ methods << method
13
+ end
14
+ end
15
+ classes << klass
16
+ end
17
+ methods
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,141 @@
1
+ module Laser
2
+ module Analysis
3
+ # Visitor: a set of methods for visiting an AST. The
4
+ # default implementations visit each child and do no
5
+ # other processing. By including this module, and
6
+ # implementing certain methods, you can do your own
7
+ # processing on, say, every instance of a :rescue AST node.
8
+ # The default implementation will go arbitrarily deep in the AST
9
+ # tree until it hits a method you define.
10
+ module Visitor
11
+ extend ModuleExtensions
12
+ def self.included(klass)
13
+ klass.__send__(:extend, ClassMethods)
14
+ klass.__send__(:extend, ModuleExtensions)
15
+ class << klass
16
+ attr_writer :filters
17
+ def filters
18
+ @filters ||= []
19
+ end
20
+ end
21
+ end
22
+ module ClassMethods
23
+ extend ModuleExtensions
24
+ # A filter is a general-purpose functor run on a subset of the nodes in
25
+ # an AST. It includes a set of possible ways to match a node, including
26
+ # node types and general procs, and it includes a block to run in order
27
+ # to do some interesting manipulation of the matching node.
28
+ Filter = Struct.new(:args, :blk) do
29
+ def matches?(node)
30
+ args.any? do |filter|
31
+ case filter
32
+ when ::Symbol then node.type == filter
33
+ when Proc then filter.call(node, *node.children)
34
+ end
35
+ end
36
+ end
37
+
38
+ def inspect
39
+ args.inspect
40
+ end
41
+
42
+ # Runs the filter on the given node, with the visitor object as the
43
+ # 'self'. That way we create the illusion of methods using the #add
44
+ # syntax.
45
+ #
46
+ # If any analysis-specific errors are raised and not caught, they are
47
+ # simply attached to the node's errors list. If the filter would like
48
+ # to continue operating after an error is raised, it must catch it
49
+ # and attach the error itself.
50
+ def run(node, visitor)
51
+ begin
52
+ visitor.instance_exec(node, *node.children, &blk)
53
+ rescue Error => err
54
+ err.ast_node = node
55
+ node.errors << err
56
+ rescue StandardError => err
57
+ err.message.replace(err.message + " (Visitor #{self.inspect} Occurred at node #{node.inspect})")
58
+ raise err
59
+ end
60
+ end
61
+ end
62
+ # Adds a new filter with the given matching strategies and a block to run
63
+ # upon matching a node.
64
+ def add(*args, &blk)
65
+ (self.filters ||= []) << Filter.new(args, blk)
66
+ end
67
+ end
68
+
69
+ attr_reader :text
70
+ # Annotates the given node +root+, assuming the tree represents the source contained in
71
+ # +text+. This is useful for text-based discovery that has to happen, often to capture
72
+ # lexing information lost by the Ripper parser.
73
+ #
74
+ # root: Sexp
75
+ # text: String
76
+ def annotate_with_text(root, text)
77
+ @text = text
78
+ @lines = nil
79
+ annotate! root
80
+ end
81
+
82
+ # Entry point for annotation. Should be called on the root of the tree we
83
+ # are interested in annotating.
84
+ #
85
+ # root: Sexp
86
+ def annotate!(root)
87
+ visit root
88
+ end
89
+
90
+ # Visits a given node. Will be automatically called by the visitor and can (and often
91
+ # should) be called manually.
92
+ #
93
+ # node: Sexp
94
+ def visit(node)
95
+ case node
96
+ when Sexp
97
+ case node[0]
98
+ when ::Symbol
99
+ try_filters node or default_visit node
100
+ when Array
101
+ default_visit(node)
102
+ end
103
+ end
104
+ end
105
+
106
+ # Visits the children of the node, by calling #visit on every child of
107
+ # node that is a Sexp.
108
+ #
109
+ # node: Sexp
110
+ def visit_children(node)
111
+ node.children.select {|x| Sexp === x}.each {|x| visit(x) }
112
+ end
113
+ # By default, we should visit every child, trying to find something the visitor
114
+ # subclass has overridden.
115
+ alias_method :default_visit, :visit_children
116
+
117
+ # Tries all known filters on the given node, and if the filter matches, then
118
+ # the filter is run on the node. Returns whether or not any filters matched.
119
+ #
120
+ # node: Sexp
121
+ # return: Boolean
122
+ def try_filters(node)
123
+ any_ran = false
124
+ self.class.filters.each do |filter|
125
+ if filter.matches?(node)
126
+ filter.run(node, self)
127
+ any_ran = true
128
+ end
129
+ end
130
+ any_ran
131
+ end
132
+
133
+ ################## Source text manipulation methods ###############
134
+
135
+ def lines
136
+ @lines ||= text.lines.to_a
137
+ end
138
+
139
+ end
140
+ end
141
+ end