laser 0.7.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
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,30 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe Error do
4
+ it 'is a StandardError subclass' do
5
+ Error.ancestors.should include(StandardError)
6
+ end
7
+
8
+ describe '#initialize' do
9
+ it 'assigns a message, an AST node, and a severity' do
10
+ result = Error.new('msg here', [:lol], 3)
11
+ result.message.should == 'msg here'
12
+ result.ast_node.should == [:lol]
13
+ result.severity.should == 3
14
+ end
15
+ end
16
+
17
+ context 'when subclassed' do
18
+ before do
19
+ @temp_class = Class.new(Error) do
20
+ severity 3
21
+ end
22
+ end
23
+ it 'has a class-level severity method for specifying a constant severity' do
24
+ result = @temp_class.new('a', [:hi])
25
+ result.message.should == 'a'
26
+ result.ast_node.should == [:hi]
27
+ result.severity.should == 3
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,322 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe LaserObject do
4
+ before do
5
+ @instance = LaserObject.new(ClassRegistry['Array'])
6
+ end
7
+
8
+ it 'defaults to the global scope' do
9
+ @instance.scope.should == Scope::GlobalScope
10
+ end
11
+
12
+ describe '#add_instance_method!' do
13
+ it 'should add the method to its singleton class' do
14
+ @instance.add_instance_method!(LaserMethod.new('abcdef', nil))
15
+ end
16
+ end
17
+
18
+ describe '#singleton_class' do
19
+ it "should return a singleton class with the object's class as its superclass" do
20
+ @instance.singleton_class.superclass == ClassRegistry['Array']
21
+ end
22
+ end
23
+ end
24
+
25
+ shared_examples_for 'a Ruby module' do
26
+ extend AnalysisHelpers
27
+ clean_registry
28
+
29
+ before do
30
+ @name = if described_class == LaserModule then 'Module'
31
+ elsif described_class == LaserClass then 'Class'
32
+ end
33
+ @a = described_class.new(ClassRegistry[@name], Scope::GlobalScope, 'A')
34
+ @b = described_class.new(ClassRegistry[@name], Scope::GlobalScope, 'B') do |b|
35
+ b.add_instance_method!(LaserMethod.new('foo', nil) do |method|
36
+ end)
37
+ b.add_instance_method!(LaserMethod.new('bar', nil) do |method|
38
+ end)
39
+ end
40
+ end
41
+
42
+ describe '#initialize' do
43
+ it 'should raise if the path contains a component that does not start with a capital' do
44
+ expect { described_class.new(ClassRegistry[@name], Scope::GlobalScope, '::A::b::C') }.to raise_error(ArgumentError)
45
+ end
46
+
47
+ it 'should raise if the path has one component that does not start with a capital' do
48
+ expect { described_class.new(ClassRegistry[@name], Scope::GlobalScope, 'acd') }.to raise_error(ArgumentError)
49
+ end
50
+ end
51
+
52
+ describe '#name' do
53
+ it 'extracts the name from the full path' do
54
+ x = described_class.new(ClassRegistry[@name], Scope::GlobalScope, '::A::B::C::D::EverybodysFavoriteClass')
55
+ x.name.should == 'EverybodysFavoriteClass'
56
+ end
57
+ end
58
+ end
59
+
60
+ describe LaserModule do
61
+ it_should_behave_like 'a Ruby module'
62
+ extend AnalysisHelpers
63
+ clean_registry
64
+
65
+ describe '#singleton_class' do
66
+ it 'should return a class with Module as its superclass' do
67
+ LaserModule.new.singleton_class.superclass.should == ClassRegistry['Module']
68
+ end
69
+ end
70
+
71
+ describe '#include_module' do
72
+ before do
73
+ @a = LaserModule.new
74
+ @b = LaserModule.new
75
+ @c = LaserModule.new
76
+ @d = LaserModule.new
77
+ end
78
+
79
+ it "inserts the included module into the receiving module's hierarchy when not already there" do
80
+ @b.superclass.should be nil
81
+ @b.include_module(@a)
82
+ @b.ancestors.should == [@b, @a]
83
+ end
84
+
85
+ it "does nothing when the included module is already in the receiving module's hierarchy" do
86
+ # setup
87
+ @b.include_module(@a)
88
+ @c.include_module(@b)
89
+ @b.ancestors.should == [@b, @a]
90
+ @c.ancestors.should == [@c, @b, @a]
91
+ # verification
92
+ expect { @b.include_module(@a) }.to raise_error(DoubleIncludeError)
93
+ @b.ancestors.should == [@b, @a]
94
+ expect { @c.include_module(@a) }.to raise_error(DoubleIncludeError)
95
+ @c.ancestors.should == [@c, @b, @a]
96
+ end
97
+
98
+ it "only inserts the necessary modules, handling diamond inheritance" do
99
+ # A has two inherited modules, B and C
100
+ @b.include_module(@a)
101
+ @c.include_module(@a)
102
+ @b.ancestors.should == [@b, @a]
103
+ @c.ancestors.should == [@c, @a]
104
+ # D includes B, then, C, in that order.
105
+ @d.include_module(@b)
106
+ @d.include_module(@c)
107
+ @d.ancestors.should == [@d, @c, @b, @a]
108
+ end
109
+
110
+ it 'raises on an obvious cyclic include' do
111
+ expect { @a.include_module(@a) }.to raise_error(ArgumentError)
112
+ end
113
+
114
+ it 'raises on a less-obvious cyclic include' do
115
+ @b.include_module(@a)
116
+ @c.include_module(@b)
117
+ @d.include_module(@c)
118
+ expect { @a.include_module(@d) }.to raise_error(ArgumentError)
119
+ end
120
+
121
+ it 'raises when including a class' do
122
+ klass = LaserClass.new(ClassRegistry['Class'], Scope::GlobalScope, 'X')
123
+ expect { @a.include_module(klass) }.to raise_error(ArgumentError)
124
+ end
125
+
126
+ it 'does not raise when including an instance of a Module subclass' do
127
+ silly_mod_subclass = LaserClass.new(ClassRegistry['Class'], Scope::GlobalScope, 'SillyModSubclass') do |klass|
128
+ klass.superclass = ClassRegistry['Module']
129
+ end
130
+ instance = LaserModule.new(silly_mod_subclass)
131
+ @a.include_module(instance)
132
+ @a.ancestors.should == [@a, instance]
133
+ end
134
+ end
135
+ end
136
+
137
+ describe LaserClass do
138
+ it_should_behave_like 'a Ruby module'
139
+ extend AnalysisHelpers
140
+ clean_registry
141
+
142
+ before do
143
+ @a = LaserClass.new(ClassRegistry['Class'], Scope::GlobalScope, 'A')
144
+ @b = LaserClass.new(ClassRegistry['Class'], Scope::GlobalScope, 'B') do |b|
145
+ b.superclass = @a
146
+ end
147
+ end
148
+
149
+ describe '#singleton_class' do
150
+ it "should have a superclass that is the superclass's singleton class" do
151
+ @b.singleton_class.superclass.should == @a.singleton_class
152
+ @a.singleton_class.superclass.should == ClassRegistry['Object'].singleton_class
153
+ end
154
+ end
155
+
156
+ describe '#superclass' do
157
+ it 'returns the superclass specified on the LaserClass' do
158
+ @b.superclass.should == @a
159
+ end
160
+ end
161
+
162
+ describe '#subclasses' do
163
+ it 'returns the set of direct subclasses of the LaserClass' do
164
+ @a.subclasses.should include(@b)
165
+ end
166
+ end
167
+
168
+ describe '#remove_subclass' do
169
+ it 'allows the removal of direct subclasses (just in case we need to)' do
170
+ @a.remove_subclass!(@b)
171
+ @a.subclasses.should_not include(@b)
172
+ end
173
+ end
174
+
175
+ describe '#include_module' do
176
+ before do
177
+ @a = LaserModule.new
178
+ @b = LaserModule.new
179
+ @c = LaserModule.new
180
+ @d = LaserModule.new
181
+ @x = LaserClass.new(ClassRegistry['Class'], Scope::GlobalScope, 'X')
182
+ @y = LaserClass.new(ClassRegistry['Class'], Scope::GlobalScope, 'Y') { |klass| klass.superclass = @x }
183
+ @z = LaserClass.new(ClassRegistry['Class'], Scope::GlobalScope, 'Z') { |klass| klass.superclass = @y }
184
+ end
185
+
186
+ it "inserts the included module into the receiving module's hierarchy when not already there" do
187
+ @x.include_module(@a)
188
+ @x.ancestors.should == [@x, @a, ClassRegistry['Object'],
189
+ ClassRegistry['Kernel'], ClassRegistry['BasicObject']]
190
+ @y.include_module(@b)
191
+ @y.ancestors.should == [@y, @b, @x, @a, ClassRegistry['Object'],
192
+ ClassRegistry['Kernel'], ClassRegistry['BasicObject']]
193
+ @z.include_module(@c)
194
+ @z.ancestors.should == [@z, @c, @y, @b, @x, @a, ClassRegistry['Object'],
195
+ ClassRegistry['Kernel'], ClassRegistry['BasicObject']]
196
+ end
197
+
198
+ it 'mixes multiple modules into one class' do
199
+ @x.include_module(@a)
200
+ @x.include_module(@b)
201
+ @x.include_module(@c)
202
+ @x.ancestors.should == [@x, @c, @b, @a, ClassRegistry['Object'],
203
+ ClassRegistry['Kernel'], ClassRegistry['BasicObject']]
204
+ end
205
+
206
+ it "does nothing when the included module is already in the receiving module's hierarchy" do
207
+ # setup
208
+ @b.include_module(@a)
209
+ @x.include_module(@b)
210
+ @x.ancestors.should == [@x, @b, @a, ClassRegistry['Object'],
211
+ ClassRegistry['Kernel'], ClassRegistry['BasicObject']]
212
+ # verification
213
+ @y.ancestors.should == [@y, @x, @b, @a, ClassRegistry['Object'],
214
+ ClassRegistry['Kernel'], ClassRegistry['BasicObject']]
215
+ expect { @y.include_module(@b) }.to raise_error(DoubleIncludeError)
216
+ @y.ancestors.should == [@y, @x, @b, @a, ClassRegistry['Object'],
217
+ ClassRegistry['Kernel'], ClassRegistry['BasicObject']]
218
+ end
219
+
220
+ it 'only inserts the necessary modules, handling diamond inheritance' do
221
+ # Odd order of operations is intentional here
222
+ @b.include_module(@a)
223
+ @d.include_module(@c)
224
+ @c.include_module(@b)
225
+
226
+ @x.include_module(@a)
227
+ @y.include_module(@c)
228
+ @z.include_module(@d)
229
+
230
+ @x.ancestors.should == [@x, @a, ClassRegistry['Object'], ClassRegistry['Kernel'],
231
+ ClassRegistry['BasicObject']]
232
+ @y.ancestors.should == [@y, @c, @b, @x, @a, ClassRegistry['Object'],
233
+ ClassRegistry['Kernel'], ClassRegistry['BasicObject']]
234
+ @z.ancestors.should == [@z, @d, @y, @c, @b, @x, @a, ClassRegistry['Object'],
235
+ ClassRegistry['Kernel'], ClassRegistry['BasicObject']]
236
+ end
237
+ end
238
+ end
239
+
240
+ describe 'hierarchy methods' do
241
+ extend AnalysisHelpers
242
+ clean_registry
243
+
244
+ before do
245
+ @y = LaserClass.new(ClassRegistry['Class'], Scope::GlobalScope, 'Y')
246
+ @y.superclass = @x = LaserClass.new(ClassRegistry['Class'], Scope::GlobalScope, 'X')
247
+ @x.superclass = ClassRegistry['Object']
248
+ @y2 = LaserClass.new(ClassRegistry['Class'], Scope::GlobalScope, 'Y2')
249
+ @y2.superclass = @x
250
+ @z = LaserClass.new(ClassRegistry['Class'], Scope::GlobalScope, 'Z')
251
+ @z.superclass = @y
252
+ @w = LaserClass.new(ClassRegistry['Class'], Scope::GlobalScope, 'W')
253
+ @w.superclass = @y2
254
+ end
255
+
256
+ describe '#superclass' do
257
+ it 'should return the direct superclass' do
258
+ @x.superclass.should == ClassRegistry['Object']
259
+ @y.superclass.should == @x
260
+ @y2.superclass.should == @x
261
+ @z.superclass.should == @y
262
+ @w.superclass.should == @y2
263
+ end
264
+ end
265
+
266
+ describe '#superset' do
267
+ it 'should return all ancestors and the current class, in order' do
268
+ @x.superset.should == [@x, ClassRegistry['Object'], ClassRegistry['BasicObject']]
269
+ @y.superset.should == [@y, @x, ClassRegistry['Object'], ClassRegistry['BasicObject']]
270
+ @y2.superset.should == [@y2, @x, ClassRegistry['Object'], ClassRegistry['BasicObject']]
271
+ @z.superset.should == [@z, @y, @x, ClassRegistry['Object'], ClassRegistry['BasicObject']]
272
+ @w.superset.should == [@w, @y2, @x, ClassRegistry['Object'], ClassRegistry['BasicObject']]
273
+ end
274
+ end
275
+
276
+ describe '#proper_superset' do
277
+ it 'should return all ancestors, in order' do
278
+ @x.proper_superset.should == [ClassRegistry['Object'], ClassRegistry['BasicObject']]
279
+ @y.proper_superset.should == [@x, ClassRegistry['Object'], ClassRegistry['BasicObject']]
280
+ @y2.proper_superset.should == [@x, ClassRegistry['Object'], ClassRegistry['BasicObject']]
281
+ @z.proper_superset.should == [@y, @x, ClassRegistry['Object'], ClassRegistry['BasicObject']]
282
+ @w.proper_superset.should == [@y2, @x, ClassRegistry['Object'], ClassRegistry['BasicObject']]
283
+ end
284
+ end
285
+
286
+ describe '#subset' do
287
+ it 'should return all known classes in the class tree rooted at the receiver' do
288
+ @w.subset.should == [@w]
289
+ @z.subset.should == [@z]
290
+ @y2.subset.should == [@y2, @w]
291
+ @y.subset.should == [@y, @z]
292
+ @x.subset.should == [@x, @y, @z, @y2, @w]
293
+ end
294
+ end
295
+
296
+ describe '#proper_subset' do
297
+ it 'should return all known classes in the class tree rooted at the receiver' do
298
+ @w.proper_subset.should == []
299
+ @z.proper_subset.should == []
300
+ @y2.proper_subset.should== [@w]
301
+ @y.proper_subset.should == [@z]
302
+ @x.proper_subset.should == [@y, @z, @y2, @w]
303
+ end
304
+ end
305
+ end
306
+
307
+ describe LaserMethod do
308
+ extend AnalysisHelpers
309
+ clean_registry
310
+
311
+ before do
312
+ @a = LaserClass.new(ClassRegistry['Class'], Scope::GlobalScope, 'A')
313
+ @b = LaserClass.new(ClassRegistry['Class'], Scope::GlobalScope, 'B')
314
+ @method = LaserMethod.new('foobar', nil)
315
+ end
316
+
317
+ describe '#name' do
318
+ it 'returns the name' do
319
+ @method.name.should == 'foobar'
320
+ end
321
+ end
322
+ end
@@ -0,0 +1,184 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe LexicalAnalysis do
4
+ before do
5
+ @class = Class.new do
6
+ include LexicalAnalysis
7
+ attr_accessor :body
8
+ def initialize(body)
9
+ self.body = body
10
+ end
11
+ end
12
+ end
13
+
14
+ describe '#lex' do
15
+ it 'lexes its body' do
16
+ @class.new('a').lex.should == [LexicalAnalysis::Token.new([[1,0], :on_ident, 'a'])]
17
+ end
18
+
19
+ it 'returns the empty list when parsing the first line with an encoding marker' do
20
+ @class.new('# this actually has nothing to do with encoding but it triggers').lex.should ==
21
+ []
22
+ end
23
+ end
24
+
25
+ describe '#text_between_token_positions' do
26
+ it 'finds the exclusive text between two simple tokens from a body text' do
27
+ body = "def initialize(body)\n self.body = body\nend"
28
+ left = LexicalAnalysis::Token.new([[2, 4], :on_kw, "self"])
29
+ right = LexicalAnalysis::Token.new([[2, 20], :on_nl, "\n"])
30
+ @class.new('').text_between_token_positions(body, left, right).should ==
31
+ '.body = body'
32
+ end
33
+
34
+ it 'allows including the left token with the inclusive :left hash option' do
35
+ body = "def initialize(body)\n self.body = body\nend"
36
+ left = LexicalAnalysis::Token.new([[2, 4], :on_kw, "self"])
37
+ right = LexicalAnalysis::Token.new([[2, 20], :on_nl, "\n"])
38
+ @class.new('').text_between_token_positions(body, left, right, :left).should ==
39
+ 'self.body = body'
40
+ end
41
+
42
+ it 'allows including the right token with the inclusive :right hash option' do
43
+ body = "def initialize(body)\n self.body = body\nend"
44
+ left = LexicalAnalysis::Token.new([[2, 4], :on_kw, "self"])
45
+ right = LexicalAnalysis::Token.new([[2, 20], :on_nl, "\n"])
46
+ @class.new('').text_between_token_positions(body, left, right, :right).should ==
47
+ ".body = body\n"
48
+ end
49
+
50
+ it 'allows including both tokens with the inclusive :both hash option' do
51
+ body = "def initialize(body)\n self.body = body\nend"
52
+ left = LexicalAnalysis::Token.new([[2, 4], :on_kw, "self"])
53
+ right = LexicalAnalysis::Token.new([[2, 20], :on_nl, "\n"])
54
+ @class.new('').text_between_token_positions(body, left, right, :both).should ==
55
+ "self.body = body\n"
56
+ end
57
+
58
+ it 'allows explicitly to exclude the tokens with the inclusive :none option' do
59
+ body = "def initialize(body)\n self.body = body\nend"
60
+ left = LexicalAnalysis::Token.new([[2, 4], :on_kw, "self"])
61
+ right = LexicalAnalysis::Token.new([[2, 20], :on_nl, "\n"])
62
+ @class.new('').text_between_token_positions(body, left, right, :none).should ==
63
+ '.body = body'
64
+ end
65
+
66
+ describe 'spanning multiple lines' do
67
+ it 'allows including the left token with the inclusive :left hash option' do
68
+ body = "def initialize(body)\n self.body = body\nend # a * b"
69
+ left = LexicalAnalysis::Token.new([[1, 14], :on_lparen, "("])
70
+ right = LexicalAnalysis::Token.new([[3, 3], :on_sp, " "])
71
+ @class.new('').text_between_token_positions(body, left, right, :left).should ==
72
+ "(body)\n self.body = body\nend"
73
+ end
74
+
75
+ it 'allows including the right token with the inclusive :right hash option' do
76
+ body = "def initialize(body)\n self.body = body\nend # a * b"
77
+ left = LexicalAnalysis::Token.new([[1, 14], :on_lparen, "("])
78
+ right = LexicalAnalysis::Token.new([[3, 3], :on_sp, " "])
79
+ @class.new('').text_between_token_positions(body, left, right, :right).should ==
80
+ "body)\n self.body = body\nend "
81
+ end
82
+
83
+ it 'allows including both tokens with the inclusive :both hash option' do
84
+ body = "def initialize(body)\n self.body = body\nend # a * b"
85
+ left = LexicalAnalysis::Token.new([[1, 14], :on_lparen, "("])
86
+ right = LexicalAnalysis::Token.new([[3, 3], :on_sp, " "])
87
+ @class.new('').text_between_token_positions(body, left, right, :both).should ==
88
+ "(body)\n self.body = body\nend "
89
+ end
90
+
91
+ it 'allows explicitly to exclude the tokens with the inclusive :none option' do
92
+ body = "def initialize(body)\n self.body = body\nend # a * b"
93
+ left = LexicalAnalysis::Token.new([[1, 14], :on_lparen, "("])
94
+ right = LexicalAnalysis::Token.new([[3, 3], :on_sp, " "])
95
+ @class.new('').text_between_token_positions(body, left, right, :none).should ==
96
+ "body)\n self.body = body\nend"
97
+ end
98
+ end
99
+ end
100
+
101
+ describe '#find_token' do
102
+ it 'lexes its body' do
103
+ @class.new('a + b').find_token(:on_op).should be_true
104
+ end
105
+
106
+ it 'returns falsy if token not found' do
107
+ @class.new('a + b').find_token(:on_kw).should be_false
108
+ end
109
+
110
+ it 'works with multiple token options' do
111
+ result = @class.new('a + b # hello').find_token(:on_op, :on_comment)
112
+ result.type.should == :on_op
113
+ end
114
+
115
+ it 'is not triggered by symbols' do
116
+ @class.new(':+').find_token(:on_op).should be_false
117
+ end
118
+ end
119
+
120
+ describe '#find_keyword' do
121
+ it 'lexes its body' do
122
+ @class.new('class A < B').find_keyword(:class).should be_true
123
+ end
124
+
125
+ it 'returns falsy if token not found' do
126
+ @class.new('class A < B').find_keyword(:end).should be_false
127
+ end
128
+
129
+ it 'returns the actual token if it is found' do
130
+ @class.new('class A < B').find_keyword(:class).should ==
131
+ LexicalAnalysis::Token.new([[1,0], :on_kw, 'class'])
132
+ end
133
+
134
+ it 'works with multiple keyword options' do
135
+ result = @class.new('class A < B; end').find_keyword(:class, :end)
136
+ result.body.should == 'class'
137
+ end
138
+
139
+ it 'is not triggered by symbols' do
140
+ @class.new(':unless').find_keyword(:unless).should be_false
141
+ end
142
+ end
143
+
144
+ describe '#split_on_token' do
145
+ it 'splits the input into two parts based on the token searched' do
146
+ left, right = @class.new('a + b; c + d').split_on_token(:on_semicolon)
147
+ left.should == 'a + b'
148
+ right.should == '; c + d'
149
+ end
150
+
151
+ it 'works with multiple searched tokens' do
152
+ left, right = @class.new('a + b; c + d').split_on_token(:on_semicolon, :on_op)
153
+ left.should == 'a '
154
+ right.should == '+ b; c + d'
155
+ end
156
+
157
+ it 'matches its own documentation' do
158
+ left, right = @class.new('').split_on_token('x = 5 unless y == 2', :on_kw)
159
+ left.should == 'x = 5 '
160
+ right.should == 'unless y == 2'
161
+ end
162
+ end
163
+
164
+
165
+ describe '#split_on_keyword' do
166
+ it 'splits the input into two parts based on the token searched' do
167
+ left, right = @class.new('rescue x if y').split_on_keyword(:if)
168
+ left.should == 'rescue x '
169
+ right.should == 'if y'
170
+ end
171
+
172
+ it 'works with multiple searched tokens' do
173
+ left, right = @class.new('rescue x if y').split_on_keyword(:if, :rescue)
174
+ left.should == ''
175
+ right.should == 'rescue x if y'
176
+ end
177
+
178
+ it 'matches its own documentation' do
179
+ left, right = @class.new('').split_on_keyword('x = 5 unless y == 2', :unless)
180
+ left.should == 'x = 5 '
181
+ right.should == 'unless y == 2'
182
+ end
183
+ end
184
+ end