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,167 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe Sexp do
4
+ before do
5
+ @sexp = Sexp.new([:if, [:abc, 2, 3], [:def, 4, 5], nil])
6
+ end
7
+
8
+ describe '#type' do
9
+ it 'returns the type of the sexp' do
10
+ @sexp.type.should == :if
11
+ @sexp[1].type.should == :abc
12
+ @sexp[2].type.should == :def
13
+ end
14
+ end
15
+
16
+ describe '#children' do
17
+ it 'returns the children of a normal sexp' do
18
+ @sexp.children.should == [[:abc, 2, 3], [:def, 4, 5], nil]
19
+ @sexp[1].children.should == [2, 3]
20
+ @sexp[2].children.should == [4, 5]
21
+ end
22
+
23
+ it 'returns everything in an array if a whole-array sexp' do
24
+ Sexp.new([[:abc], 2, 3, [:def, 3, 4]]).children.should == [[:abc], 2, 3, [:def, 3, 4]]
25
+ end
26
+ end
27
+
28
+ describe '#all_errors' do
29
+ it 'should return all errors in the tree, in DFS order' do
30
+ sexp = Sexp.new([[:abc], [:d, 2, [:e, 1]], [:def, [:a], [:b]]])
31
+ sexp.errors = ['hi']
32
+ sexp[0].errors = []
33
+ sexp[1].errors = ['world']
34
+ sexp[1][2].errors = ['another']
35
+ sexp[2].errors = [2]
36
+ sexp[2][1].errors = [3, 4]
37
+ sexp[2][2].errors = [5, 6, 7]
38
+ sexp.all_errors.should == ['hi', 'world', 'another', 2, 3, 4, 5, 6, 7]
39
+ end
40
+ end
41
+
42
+ describe 'performing DFS operations' do
43
+ before do
44
+ @hard_sexp = Sexp.new([:program,
45
+ [[:class,
46
+ [:const_ref, [:@const, "A", [1, 6]]],
47
+ [:var_ref, [:@const, "String", [1, 10]]],
48
+ [:bodystmt,
49
+ [[:defs,
50
+ [:var_ref, [:@kw, "self", [1, 22]]],
51
+ [:@period, ".", [1, 26]],
52
+ [:@ident, "silly", [1, 27]],
53
+ [:paren,
54
+ [:params,
55
+ [[:@ident, "x", [1, 33]]], nil,
56
+ [:rest_param, [:@ident, "y", [1, 37]]], nil, nil]],
57
+ [:bodystmt,
58
+ [[:void_stmt],
59
+ [:massign,
60
+ [:mlhs_paren, [[:@ident, "x", [1, 42]], [:@ident, "y", [1, 45]]]],
61
+ [:mrhs_add_star, [], [:var_ref, [:@ident, "y", [1, 51]]]]]],
62
+ nil, nil, nil]]],
63
+ nil, nil, nil]]]])
64
+ # While I had to manually figure this out, a simple look at the indices used
65
+ # shows that it is a proper DFS order.
66
+ @correct_order = [@hard_sexp,
67
+ @hard_sexp[1][0],
68
+ @hard_sexp[1][0][1],
69
+ @hard_sexp[1][0][1][1],
70
+ @hard_sexp[1][0][2],
71
+ @hard_sexp[1][0][2][1],
72
+ @hard_sexp[1][0][3],
73
+ @hard_sexp[1][0][3][1][0],
74
+ @hard_sexp[1][0][3][1][0][1],
75
+ @hard_sexp[1][0][3][1][0][1][1],
76
+ @hard_sexp[1][0][3][1][0][2],
77
+ @hard_sexp[1][0][3][1][0][3],
78
+ @hard_sexp[1][0][3][1][0][4],
79
+ @hard_sexp[1][0][3][1][0][4][1],
80
+ @hard_sexp[1][0][3][1][0][4][1][1][0],
81
+ @hard_sexp[1][0][3][1][0][4][1][3],
82
+ @hard_sexp[1][0][3][1][0][4][1][3][1],
83
+ @hard_sexp[1][0][3][1][0][5],
84
+ @hard_sexp[1][0][3][1][0][5][1][0],
85
+ @hard_sexp[1][0][3][1][0][5][1][1],
86
+ @hard_sexp[1][0][3][1][0][5][1][1][1],
87
+ @hard_sexp[1][0][3][1][0][5][1][1][1][1][0],
88
+ @hard_sexp[1][0][3][1][0][5][1][1][1][1][1],
89
+ @hard_sexp[1][0][3][1][0][5][1][1][2],
90
+ @hard_sexp[1][0][3][1][0][5][1][1][2][2],
91
+ @hard_sexp[1][0][3][1][0][5][1][1][2][2][1]]
92
+ end
93
+ describe '#dfs' do
94
+ # this test sucked to write.
95
+ it 'yields the nodes of the tree in DFS order' do
96
+ result = []
97
+ @hard_sexp.dfs { |node| result << node }
98
+ result.should == @correct_order
99
+ end
100
+ end
101
+
102
+ describe '#dfs_enumerator' do
103
+ it 'should enumerate every element in DFS order' do
104
+ enumerator = @hard_sexp.dfs_enumerator
105
+ enumerator.entries.should == @correct_order
106
+ end
107
+ end
108
+ end
109
+
110
+ describe '#expanded_identifier' do
111
+ ['abc', '@abc', 'ABC', '@@abc', '$abc'].each do |id|
112
+ tree = Sexp.new(Ripper.sexp(id))
113
+ actual_ident = tree[1][0][1]
114
+ it "discovers expanded identifiers for simple identifiers of type #{actual_ident[0]}" do
115
+ actual_ident.expanded_identifier.should == id
116
+ end
117
+ end
118
+
119
+ # [:program,
120
+ # [[:assign,
121
+ # [:var_field, [:@ident, "abc", [1, 0]]],
122
+ # [:var_ref, [:@const, "ABC", [1, 6]]]]]]
123
+ it 'handles var_ref and var_field nodes' do
124
+ input = 'abc = ABC'
125
+ tree = Sexp.new(Ripper.sexp(input))
126
+ assign = tree[1][0]
127
+ assign[1].expanded_identifier.should == 'abc'
128
+ assign[2].expanded_identifier.should == 'ABC'
129
+ end
130
+
131
+ # [:program,
132
+ # [[:assign,
133
+ # [:top_const_field, [:@const, "ABC", [1, 2]]],
134
+ # [:top_const_ref, [:@const, "DEF", [1, 10]]]]]]
135
+ it 'handles top_const_ref and top_const_field nodes' do
136
+ input = '::ABC = ::DEF'
137
+ tree = Sexp.new(Ripper.sexp(input))
138
+ assign = tree[1][0]
139
+ assign[1].expanded_identifier.should == '::ABC'
140
+ assign[2].expanded_identifier.should == '::DEF'
141
+ end
142
+
143
+ # [:program,
144
+ # [[:class,
145
+ # [:const_ref, [:@const, "ABC", [1, 6]]],
146
+ # nil,
147
+ # [:bodystmt, [[:void_stmt]], nil, nil, nil]]]]
148
+ it 'handles const_ref nodes (found in module/class declarations)' do
149
+ input = 'class ABC; end'
150
+ tree = Sexp.new(Ripper.sexp(input))
151
+ klass = tree[1][0]
152
+ klass[1].expanded_identifier.should == 'ABC'
153
+ end
154
+
155
+ # [:program,
156
+ # [[:assign,
157
+ # [:top_const_field, [:@const, "ABC", [1, 2]]],
158
+ # [:top_const_ref, [:@const, "DEF", [1, 10]]]]]]
159
+ it 'handles top_const_ref and top_const_field nodes' do
160
+ input = '::ABC::DEF = ::DEF::XYZ'
161
+ tree = Sexp.new(Ripper.sexp(input))
162
+ assign = tree[1][0]
163
+ assign[1].expanded_identifier.should == '::ABC::DEF'
164
+ assign[2].expanded_identifier.should == '::DEF::XYZ'
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,27 @@
1
+ require_relative '../spec_helper'
2
+ include Analysis
3
+
4
+ module AnalysisHelpers
5
+ def clean_registry
6
+ before do
7
+ @backup_map = ProtocolRegistry.class_protocols.dup
8
+ end
9
+
10
+ after do
11
+ ProtocolRegistry.class_protocols.replace @backup_map
12
+ end
13
+ end
14
+ end
15
+ shared_examples_for 'an annotator' do
16
+ it 'should be in the global annotation list' do
17
+ expect do
18
+ Annotations.global_annotations.any? do |annotation|
19
+ annotation.is_a?(described_class)
20
+ end
21
+ end.to be_true
22
+ end
23
+ end
24
+
25
+ def annotate_all(body)
26
+ Annotations.annotate_inputs([['(stdin)', body]]).first[1]
27
+ end
@@ -0,0 +1,65 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe UnusedMethodDetection do
4
+ before(:all) do
5
+ Laser::Analysis::LaserMethod.default_dispatched = false
6
+ end
7
+
8
+ # We don't want unused methods flowing into the next test, so
9
+ # mark each unused method as used afterward.
10
+ after(:each) do
11
+ @methods.each do |method|
12
+ method.been_used!
13
+ end
14
+ end
15
+
16
+ after(:all) do
17
+ Laser::Analysis::LaserMethod.default_dispatched = true
18
+ end
19
+
20
+ it 'can discover a simple case of an unused method' do
21
+ cfg <<-EOF
22
+ class UnusedMethod1
23
+ def foo(x)
24
+ bar(x)
25
+ end
26
+ def bar(x, y=x)
27
+ end
28
+ def baz
29
+ end
30
+ end
31
+ UnusedMethod1.new.foo(gets)
32
+ EOF
33
+ @methods = UnusedMethodDetection.unused_methods
34
+ @methods.should == [ClassRegistry['UnusedMethod1'].instance_method(:baz)]
35
+ end
36
+
37
+ it 'discovers method use through super' do
38
+ cfg <<-EOF
39
+ class UnusedMethod2
40
+ def foo(x)
41
+ x
42
+ end
43
+ def bar(x, y=x)
44
+ end
45
+ end
46
+ class UnusedMethod3 < UnusedMethod2
47
+ def foo(x)
48
+ bar(x)
49
+ end
50
+ def bar(x, y=x)
51
+ super
52
+ y
53
+ end
54
+ def baz
55
+ end
56
+ end
57
+ UnusedMethod3.new.foo(gets)
58
+ EOF
59
+ @methods = UnusedMethodDetection.unused_methods
60
+
61
+ Set.new(@methods).should ==
62
+ Set[ClassRegistry['UnusedMethod2'].instance_method(:foo),
63
+ ClassRegistry['UnusedMethod3'].instance_method(:baz)]
64
+ end
65
+ end
@@ -0,0 +1,64 @@
1
+ require_relative 'spec_helper'
2
+ require 'ostruct'
3
+
4
+ describe Visitor do
5
+ before do
6
+ @class = Class.new do
7
+ include Visitor
8
+ add :foo do |node|
9
+ node.visited = node[1]
10
+ end
11
+ add :bar do |node|
12
+ node.product = node[1] * node[2]
13
+ end
14
+ add(proc {|node| node.children.any? && node[1] == 5 }) do |node|
15
+ node.lotto_winner = true
16
+ end
17
+ end
18
+ end
19
+
20
+ describe '#visit' do
21
+ it 'runs the matching method when one is defined' do
22
+ a = Sexp.new([:foo, true])
23
+ a.should_receive(:visited=).with(true)
24
+ @class.new.visit(a)
25
+ end
26
+ it 'matches symbol-based filters as a shortcut for node type matching' do
27
+ b = Sexp.new([:bar, 3, 2])
28
+ b.should_receive(:product=).with(6)
29
+ @class.new.visit(b)
30
+ end
31
+ it 'uses arbitrary procs to match nodes' do
32
+ c = Sexp.new([:lotto_entry, 5])
33
+ c.should_receive(:lotto_winner=).with(true)
34
+ @class.new.visit(c)
35
+ end
36
+
37
+ it 'automatically DFSs the tree to visit nodes when they are not handled' do
38
+ a = Sexp.new([:a, [:b, [:foo, false], 2, 3], [:c, [:bar, 19, 22], [:bar, 23, 2]]])
39
+ a[1][1].should_receive(:visited=).with(false)
40
+ a[2][1].should_receive(:product=).with(19 * 22)
41
+ a[2][2].should_receive(:product=).with(46)
42
+ @class.new.visit(a)
43
+ end
44
+
45
+ it 'calls #default_visit when it encounters an unknown AST node' do
46
+ klass = Class.new do
47
+ include Visitor
48
+ def default_visit(node)
49
+ node.count = (@count ||= 1)
50
+ @count += 1
51
+ node.children.select {|x| Sexp === x}.each {|x| visit(x)}
52
+ end
53
+ add :bar do |node|
54
+ end
55
+ end
56
+ a = Sexp.new([:a, [:b, [:foo, false], 2, 3], [:c, [:bar, 19, 22], [:bar, 23, 2]]])
57
+ a.should_receive(:count=).with(1)
58
+ a[1].should_receive(:count=).with(2)
59
+ a[1][1].should_receive(:count=).with(3)
60
+ a[2].should_receive(:count=).with(4)
61
+ klass.new.visit(a)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,89 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe Parsers::AnnotationParser do
4
+ before do
5
+ @parser = Parsers::AnnotationParser.new
6
+ end
7
+
8
+ describe 'a self type' do
9
+ it 'should parse as a single self type constraint' do
10
+ 'self'.should parse_to(Types::SelfType.new)
11
+ end
12
+ end
13
+
14
+ describe 'the top type' do
15
+ it 'should have no constraints' do
16
+ 'Top'.should parse_to([])
17
+ end
18
+ end
19
+
20
+ describe 'union types' do
21
+ it 'should parse to a Types::UnionType instance' do
22
+ 'TrueClass= | FalseClass= | NilClass='.should parse_to(
23
+ Types::UnionType.new([
24
+ Types::ClassType.new('TrueClass', :invariant),
25
+ Types::ClassType.new('FalseClass', :invariant),
26
+ Types::ClassType.new('NilClass', :invariant)
27
+ ])
28
+ )
29
+ end
30
+
31
+ it 'should handle more complicated types' do
32
+ 'TrueClass= | #write(#to_s -> String, Integer) -> Boolean'.should parse_to(
33
+ Types::UnionType.new([
34
+ Types::ClassType.new('TrueClass', :invariant),
35
+ Types::StructuralType.new('write', [
36
+ Types::StructuralType.new('to_s', [], Types::ClassType.new('String', :covariant)),
37
+ Types::ClassType.new('Integer', :covariant)
38
+ ], Types::BOOLEAN)
39
+ ])
40
+ )
41
+ end
42
+ end
43
+
44
+ describe 'named type annotations' do
45
+ it 'should provide a name string' do
46
+ result = @parser.parse('foo: Symbol => Integer')
47
+ result.name.should == 'foo'
48
+ end
49
+
50
+ it 'should parse the type' do
51
+ result = @parser.parse('foo: Symbol => Integer')
52
+ result.type.should == Types::GenericType.new(Types::ClassType.new('Hash', :covariant),
53
+ [Types::ClassType.new('Symbol', :covariant),
54
+ Types::ClassType.new('Integer', :covariant)])
55
+ end
56
+
57
+ it 'should return false for #literal?' do
58
+ result = @parser.parse('foo: Symbol => Integer')
59
+ result.should_not be_literal
60
+ end
61
+
62
+ it 'should return true for #type?' do
63
+ result = @parser.parse('foo: Symbol => Integer')
64
+ result.should be_type
65
+ end
66
+ end
67
+
68
+ describe 'named literal annotations' do
69
+ it 'should provide a name string' do
70
+ result = @parser.parse('foo: nil')
71
+ result.name.should == 'foo'
72
+ end
73
+
74
+ it 'should parse the literal' do
75
+ result = @parser.parse('foo: nil')
76
+ result.literal.should == nil
77
+ end
78
+
79
+ it 'should return true for #literal?' do
80
+ result = @parser.parse('foo: nil')
81
+ result.should be_literal
82
+ end
83
+
84
+ it 'should return false for #type?' do
85
+ result = @parser.parse('foo: nil')
86
+ result.should_not be_type
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,120 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe Parsers::ClassParser do
4
+ before do
5
+ @parser = Parsers::AnnotationParser.new
6
+ end
7
+
8
+ describe 'a simple class name' do
9
+ it 'is parsed into a single covariant constraint' do
10
+ 'Hello'.should parse_to(Types::ClassType.new('Hello', :covariant))
11
+ 'Hello'.should_not parse_to(Types::ClassType.new('Hello', :contravariant))
12
+ end
13
+ end
14
+
15
+ describe 'the Boolean shorthand' do
16
+ it 'is parsed as the union of TrueClass and FalseClass' do
17
+ 'Boolean'.should parse_to(Types::UnionType.new([Types::TRUECLASS, Types::FALSECLASS]))
18
+ end
19
+ end
20
+
21
+ describe "a complex class path" do
22
+ it "is parsed into a single covariant constraint" do
23
+ '::Hello::World::Is::Here'.should parse_to(
24
+ Types::ClassType.new('::Hello::World::Is::Here', :covariant))
25
+ end
26
+ end
27
+
28
+ describe 'a class name followed by -' do
29
+ it "is parsed into a contravariant class constraint" do
30
+ 'World::Is::Here-'.should parse_to(
31
+ Types::ClassType.new('World::Is::Here', :contravariant))
32
+ end
33
+ end
34
+
35
+ describe 'a class name followed by =' do
36
+ it "is parsed into a contravariant class constraint" do
37
+ 'World::Is::Here='.should parse_to(
38
+ Types::ClassType.new('World::Is::Here', :invariant))
39
+ end
40
+ end
41
+
42
+ describe 'two constraints separated by =>' do
43
+ it 'is parsed as a Hash<C1, C2>' do
44
+ ['Symbol => String', 'Symbol=>String', 'Symbol => String'].each do |input|
45
+ input.should parse_to(
46
+ Types::GenericType.new(Types::ClassType.new('Hash', :covariant),
47
+ [Types::ClassType.new('Symbol', :covariant),
48
+ Types::ClassType.new('String', :covariant)]))
49
+ end
50
+ end
51
+
52
+ it 'allows variance constraints on the key and value types' do
53
+ '::Hello::World==>Some::Constant-'.should parse_to(
54
+ Types::GenericType.new(Types::ClassType.new('Hash', :covariant),
55
+ [Types::ClassType.new('::Hello::World', :invariant),
56
+ Types::ClassType.new('Some::Constant', :contravariant)]))
57
+ end
58
+ end
59
+
60
+ describe 'a generic Array definition' do
61
+ it 'is parsed as a GenericType' do
62
+ 'Array<String>'.should parse_to(
63
+ Types::GenericType.new(Types::ClassType.new('Array', :covariant),
64
+ [Types::ClassType.new('String', :covariant)]))
65
+ end
66
+ end
67
+
68
+ describe 'a generic Hash definition' do
69
+ it 'is parsed as a GenericType' do
70
+ 'Hash- < Symbol=, String >'.should parse_to(
71
+ Types::GenericType.new(Types::ClassType.new('Hash', :contravariant),
72
+ [Types::ClassType.new('Symbol', :invariant),
73
+ Types::ClassType.new('String', :covariant)]))
74
+ end
75
+ end
76
+
77
+ describe 'a nested generic definition' do
78
+ it 'should parse correctly as nested GenericType' do
79
+ 'Array<Hash<Symbol, String>>'.should parse_to(
80
+ Types::GenericType.new(Types::ClassType.new('Array', :covariant),
81
+ [Types::GenericType.new(Types::ClassType.new('Hash', :covariant),
82
+ [Types::ClassType.new('Symbol', :covariant),
83
+ Types::ClassType.new('String', :covariant)])]))
84
+ end
85
+ end
86
+
87
+ describe 'an array generic shorthand' do
88
+ it 'should parse as a covariant generic array constraint' do
89
+ '[ String= ]'.should parse_to(
90
+ Types::GenericType.new(Types::ClassType.new('Array', :covariant),
91
+ [Types::ClassType.new('String', :invariant)]))
92
+ end
93
+ end
94
+
95
+ describe 'a dont-care shorthand' do
96
+ it 'should parse as a covariant Object constraint, which matches any object' do
97
+ '_'.should parse_to(Types::ClassType.new('Object', :covariant))
98
+ end
99
+ end
100
+
101
+ describe 'tuples' do
102
+ describe 'a simple tuple type' do
103
+ it 'should parse to a TupleType' do
104
+ '(String- , _ , Symbol= => Fixnum)'.should parse_to(
105
+ Types::TupleType.new(
106
+ [Types::ClassType.new('String', :contravariant),
107
+ Types::ClassType.new('Object', :covariant),
108
+ Types::GenericType.new(Types::ClassType.new('Hash', :covariant),
109
+ [Types::ClassType.new('Symbol', :invariant),
110
+ Types::ClassType.new('Fixnum', :covariant)])]))
111
+ end
112
+ end
113
+
114
+ describe 'an empty tuple type' do
115
+ it 'should parse to a (relatively useless) TupleType' do
116
+ '( )'.should parse_to(Types::TupleType.new([]))
117
+ end
118
+ end
119
+ end
120
+ end