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,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