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,68 @@
1
+ module Laser
2
+ module Analysis
3
+ class MethodCall
4
+ attr_reader :node
5
+
6
+ def initialize(node)
7
+ @node = node
8
+ end
9
+
10
+ def implicit_receiver?
11
+ case node.type
12
+ when :call, :aref, :unary, :binary, :super, :zsuper then false
13
+ when :fcall, :command, :command_call, :var_ref, :vcall then true
14
+ when :method_add_block, :method_add_arg then node[1].method_call.implicit_receiver?
15
+ end
16
+ end
17
+
18
+ # Calculates the name of the method this method call represents.
19
+ #
20
+ # returns: String
21
+ def method_name
22
+ case node.type
23
+ when :super, :zsuper then 'super'
24
+ when :aref then :[]
25
+ when :unary then node[1]
26
+ when :binary then node[2]
27
+ when :fcall, :command, :vcall then node[1].expanded_identifier.to_sym
28
+ when :call, :command_call then node[3].expanded_identifier.to_sym
29
+ when :var_ref then node.expanded_identifier.to_sym
30
+ when :method_add_block, :method_add_arg then node[1].method_call.method_name
31
+ end
32
+ end
33
+
34
+ # The receiver node is the node representing the explicit receiver.
35
+ # If nil, then the implicit receiver, self, is used.
36
+ #
37
+ # return: Sexp | NilClass
38
+ def receiver_node
39
+ case node.type
40
+ when :method_add_arg, :method_add_block then node[1].method_call.receiver_node
41
+ when :var_ref, :vcall, :command, :fcall, :super, :zsuper, :unary then nil
42
+ when :call, :command_call, :binary, :aref then node[1]
43
+ end
44
+ end
45
+
46
+ # Returns an ArgumentExpansion representation of the arguments of this
47
+ # method call.
48
+ def arguments
49
+ ArgumentExpansion.new(arg_node)
50
+ end
51
+
52
+ # Returns a node, if any, representing the arguments to this method call.
53
+ #
54
+ # returns: Sexp
55
+ def arg_node
56
+ case node.type
57
+ when :command, :aref then node[2][1]
58
+ when :method_add_arg then (node[2][1] ? node[2][1] : nil)
59
+ when :method_add_block then node[1].method_call.arg_node
60
+ when :call, :var_ref, :vcall, :command_call, :zsuper then nil
61
+ when :command_call then node[4][1]
62
+ when :super
63
+ node[1].type == :arg_paren ? node[1][1] : node[1]
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,30 @@
1
+ module Laser
2
+ module Analysis
3
+ # The ProtocolRegistry module handles negotiating instantiated protocols at
4
+ # compile-time, such as the automatically-generated protocols created by a
5
+ # class creation (as each class has a corresponding protocol, though some
6
+ # distinct classes may have equivalent protocols).
7
+ module ProtocolRegistry
8
+ extend ModuleExtensions
9
+ cattr_accessor_with_default :class_protocols, {}
10
+
11
+ def self.add_class(klass)
12
+ self.class_protocols[klass.path] = klass
13
+ end
14
+
15
+ def self.[](class_name)
16
+ result = self.class_protocols[class_name.gsub(/^::/, '')]
17
+ result ? [result] : []
18
+ end
19
+ end
20
+
21
+ module ClassRegistry
22
+ def self.[](class_name)
23
+ if ProtocolRegistry[class_name].any?
24
+ then ProtocolRegistry[class_name].first
25
+ else raise ArgumentError.new("No class found with the path #{class_name}.")
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,118 @@
1
+ module Laser
2
+ module Analysis
3
+ # This class models a scope in Ruby. It has a constant table,
4
+ # a self pointer, and a parent pointer to the enclosing scope.
5
+ # It also has a local variable table.
6
+ class Scope
7
+ class ScopeLookupFailure < Error
8
+ attr_accessor :scope, :query
9
+ def initialize(scope, query)
10
+ @scope, @query = scope, query
11
+ super("Scope does not contain #{query.inspect}", nil, MAJOR_ERROR)
12
+ end
13
+ end
14
+
15
+ # lexical_target = cref in YARV terms
16
+ attr_accessor :constants, :parent, :locals, :method, :lexical_target
17
+ def initialize(parent, self_ptr, constants={}, locals={})
18
+ unless respond_to?(:lookup_local)
19
+ raise NotImplementedError.new(
20
+ 'must create OpenScope or ClosedScope. Not just Scope.')
21
+ end
22
+ @parent, @constants, @locals = parent, constants, locals
23
+ @locals['self'] = Bindings::LocalVariableBinding.new('self', self_ptr)
24
+ if self_ptr && Bindings::Base === self_ptr
25
+ self_ptr.self_owner = self
26
+ end
27
+ @lexical_target = self_ptr
28
+ @method = nil
29
+ end
30
+
31
+ def initialize_copy(other)
32
+ @locals = other.locals.dup
33
+ @constants = other.constants.dup
34
+ end
35
+
36
+ def self_ptr
37
+ @locals['self'].value
38
+ end
39
+
40
+ def self_ptr=(other)
41
+ @locals['self'] = Bindings::LocalVariableBinding.new('self', other)
42
+ end
43
+
44
+ def add_binding!(new_binding)
45
+ case new_binding.name[0,1]
46
+ when /[A-Z]/
47
+ constants[new_binding.name] = new_binding
48
+ else
49
+ locals[new_binding.name] = new_binding
50
+ end
51
+ end
52
+
53
+ def path
54
+ self_ptr.path
55
+ end
56
+
57
+ def lookup_or_create_local(var_name)
58
+ lookup_local(var_name)
59
+ rescue ScopeLookupFailure
60
+ binding = Bindings::LocalVariableBinding.new(var_name, nil)
61
+ add_binding!(binding)
62
+ binding
63
+ end
64
+
65
+ # Proper variable lookup. The old ones were hacks.
66
+ def lookup(str)
67
+ if str[0,2] == '::'
68
+ Scope::GlobalScope.lookup(str[2..-1])
69
+ elsif str.include?('::')
70
+ parts = str.split('::')
71
+ final_scope = parts[0..-2].inject(self) { |scope, part| scope.lookup(part).scope }
72
+ final_scope.lookup(parts.last)
73
+ elsif str =~ /^\$/ then lookup_global(str)
74
+ elsif str =~ /^@/ then lookup_ivar(str)
75
+ elsif str =~ /^@@/ then lookup_cvar(str)
76
+ else lookup_local(str)
77
+ end
78
+ end
79
+
80
+ # Looks up a global binding. Defers to the global scope and creates on-demand.
81
+ def lookup_global(str)
82
+ Scope::GlobalScope.locals[str] ||=
83
+ Bindings::GlobalVariableBinding.new(str, nil)
84
+ end
85
+
86
+ # Looks up an instance variable binding. Defers to the current value of self's
87
+ # class,
88
+ def lookup_ivar(str)
89
+ unless (result = self_ptr.klass.instance_variables[str])
90
+ result = Bindings::InstanceVariableBinding.new(str, LaserObject.new)
91
+ self_ptr.klass.add_instance_variable!(result)
92
+ end
93
+ result
94
+ end
95
+
96
+ # Does this scope see the given variable name?
97
+ def sees_var?(var)
98
+ lookup(var) rescue false
99
+ end
100
+ end
101
+
102
+ class OpenScope < Scope
103
+ def lookup_local(str)
104
+ if locals[str]
105
+ then locals[str]
106
+ elsif parent then parent.lookup_local(str)
107
+ else raise ScopeLookupFailure.new(self, str)
108
+ end
109
+ end
110
+ end
111
+
112
+ class ClosedScope < Scope
113
+ def lookup_local(str)
114
+ locals[str] or raise ScopeLookupFailure.new(self, str)
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,159 @@
1
+ module Laser
2
+ module Analysis
3
+ # Replaces the ParseTree Sexps by adding a few handy-dandy methods.
4
+ class Sexp < Array
5
+ include SexpExtensions::ConstantExtraction
6
+ include SexpExtensions::SourceLocation
7
+ include SexpExtensions::TypeInference
8
+
9
+ extend ModuleExtensions
10
+ attr_accessor :errors, :binding, :file_name, :file_source, :scope
11
+ attr_accessor :reachable
12
+
13
+ # Initializes the Sexp with the contents of the array returned by Ripper.
14
+ #
15
+ # @param [Array<Object>] other the other
16
+ def initialize(other, file_name=nil, file_source=nil)
17
+ @reachable = true
18
+ @expr_type = nil
19
+ @errors = []
20
+ @file_name = file_name
21
+ @file_source = file_source
22
+ replace other
23
+ replace_children!
24
+ end
25
+
26
+ # @return [Array<Object>] the children of the node.
27
+ def children
28
+ @children ||= ((Array === self[0] ? self : self[1..-1]) || [])
29
+ end
30
+
31
+ # @return [Symbol] the type of the node.
32
+ def type
33
+ self[0]
34
+ end
35
+
36
+ def add_error(error)
37
+ errors << error unless errors.include?(error)
38
+ end
39
+
40
+ # is the given object a sexp?
41
+ #
42
+ # @return Boolean
43
+ def is_sexp?(sexp)
44
+ Analysis::Sexp === sexp
45
+ end
46
+
47
+ def lines
48
+ @file_source.lines.to_a
49
+ end
50
+
51
+ def find_type(type)
52
+ deep_find { |node| node.type == type }
53
+ end
54
+
55
+ # Same as #find for Enumerable, only recursively. Useful for "jumping"
56
+ # past useless parser nodes.
57
+ def deep_find
58
+ ([self] + all_subtrees.to_a).each do |node|
59
+ return node if yield(node)
60
+ end
61
+ nil
62
+ end
63
+
64
+ def all_subtrees
65
+ to_visit = self.children.dup
66
+ visited = Set.new
67
+ while to_visit.any?
68
+ todo = to_visit.shift
69
+ next unless is_sexp?(todo)
70
+
71
+ case todo[0]
72
+ when Array
73
+ to_visit.concat todo
74
+ when ::Symbol
75
+ to_visit.concat todo.children
76
+ visited << todo
77
+ end
78
+ end
79
+ visited
80
+ end
81
+
82
+ # Returns an enumerator that iterates over each subnode of this node
83
+ # in DFS order.
84
+ def dfs_enumerator
85
+ Enumerator.new do |g|
86
+ dfs do |node|
87
+ g.yield node
88
+ end
89
+ end
90
+ end
91
+
92
+ # Returns all errors in this subtree, in DFS order.
93
+ # returns: [Error]
94
+ def all_errors
95
+ dfs_enumerator.map(&:errors).flatten
96
+ end
97
+
98
+ # Performs a DFS on the node, yielding each subnode (including the given node)
99
+ # in DFS order.
100
+ def dfs
101
+ yield self
102
+ self.children.each do |child|
103
+ next unless is_sexp?(child)
104
+ case child[0]
105
+ when Array
106
+ child.each { |x| x.dfs { |y| yield y}}
107
+ when ::Symbol
108
+ child.dfs { |y| yield y }
109
+ end
110
+ end
111
+ end
112
+
113
+ # Replaces the children with Sexp versions of them
114
+ def replace_children!
115
+ replace(map do |x|
116
+ case x
117
+ when Array
118
+ self.class.new(x, @file_name, @file_source)
119
+ else x
120
+ end
121
+ end)
122
+ end
123
+ private :replace_children!
124
+
125
+ # Returns the text of the identifier, assuming this node identifies something.
126
+ def expanded_identifier
127
+ case type
128
+ when :@ident, :@const, :@gvar, :@cvar, :@ivar, :@kw, :@op
129
+ self[1]
130
+ when :var_ref, :var_field, :const_ref, :symbol
131
+ self[1].expanded_identifier
132
+ when :top_const_ref, :top_const_field
133
+ "::#{self[1].expanded_identifier}"
134
+ when :const_path_ref, :const_path_field
135
+ lhs, rhs = children
136
+ "#{lhs.expanded_identifier}::#{rhs.expanded_identifier}"
137
+ end
138
+ end
139
+
140
+ def is_method_call?
141
+ [:command, :method_add_arg, :method_add_block, :vcall, :var_ref, :call,
142
+ :fcall, :command_call, :binary, :unary, :super, :zsuper, :aref].include?(type)
143
+ end
144
+
145
+ # Returns the MethodCall wrapping up all the method call information about this
146
+ # node.
147
+ #
148
+ # raises: TypeError
149
+ # return: MethodCall
150
+ def method_call
151
+ unless is_method_call?
152
+ raise TypeError.new("Only method call nodes define #method_call. "+
153
+ "This node is of type #{type}.")
154
+ end
155
+ MethodCall.new(self)
156
+ end
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,40 @@
1
+ module Laser
2
+ # This is a set of methods that get provided to Warnings so they can perform
3
+ # parse-tree analysis of their bodies.
4
+ module Analysis
5
+ extend ModuleExtensions
6
+
7
+ # inputs: Array<(String, String)>
8
+ # Array of (filename, body) tuples.
9
+ def self.analyze_inputs(inputs)
10
+ Annotations.annotate_inputs(inputs)
11
+ end
12
+
13
+ PARSING_CACHE = {}
14
+
15
+ # Parses the given text.
16
+ #
17
+ # @param [String] body (self.body) The text to parse
18
+ # @return [Sexp, NilClass] the sexp representing the input text.
19
+ def parse(body = self.body)
20
+ return PARSING_CACHE[body] if PARSING_CACHE[body]
21
+ pairs = Analysis.analyze_inputs([['(stdin)', body]])
22
+ PARSING_CACHE[body] = pairs[0][1]
23
+ end
24
+
25
+ # Finds all sexps of the given type in the given Sexp tree.
26
+ #
27
+ # @param [Symbol] type the type of sexp to search for
28
+ # @param [Sexp] tree (self.parse(self.body)) The tree to search in. Leave
29
+ # blank to search the entire body.
30
+ # @return [Array<Sexp>] all sexps in the input tree (or whole body) that
31
+ # are of the given type.
32
+ def find_sexps(type, tree = self.parse(self.body))
33
+ result = tree[0] == type ? [tree] : []
34
+ tree.each do |node|
35
+ result.concat find_sexps(type, node) if node.is_a?(Array)
36
+ end
37
+ result
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,115 @@
1
+ module Laser::Analysis
2
+ module SexpExtensions
3
+ module ConstantExtraction
4
+
5
+ # Is this node of constant value? This might be known statically (because
6
+ # it is a literal) or it might be because it's been proven through analysis.
7
+ def is_constant
8
+ case self.type
9
+ when :@CHAR, :@tstring_content, :@int, :@float, :@regexp_end, :symbol, :@label
10
+ true
11
+ when :string_content, :string_literal, :assoc_new, :symbol_literal, :dot2, :dot3
12
+ children.all?(&:is_constant)
13
+ when :hash
14
+ self[1].nil? || self[1].is_constant
15
+ when :array, :regexp_literal, :assoclist_from_args, :bare_assoc_hash, :dyna_symbol
16
+ self[1].nil? || self[1].all?(&:is_constant)
17
+ when :var_ref, :const_ref, :const_path_ref, :var_field
18
+ if self[1].type == :@kw
19
+ %w(nil true false self __LINE__ __FILE__).include?(expanded_identifier)
20
+ elsif !self.binding.nil?
21
+ Bindings::ConstantBinding === scope.lookup(expanded_identifier)
22
+ end
23
+ when :paren
24
+ self[1].type != :params && self[1].all?(&:is_constant)
25
+ else
26
+ false
27
+ end
28
+ end
29
+
30
+ # What is this node's constant value? This might be known statically (because
31
+ # it is a literal) or it might be because it's been proven through analysis.
32
+ def constant_value
33
+ unless is_constant
34
+ return :none
35
+ end
36
+ case type
37
+ when :@CHAR
38
+ char_part = self[1][1..-1]
39
+ if char_part.size == 1
40
+ char_part
41
+ else
42
+ eval(%Q{"#{char_part}"})
43
+ end
44
+ when :@tstring_content
45
+ str = self[1]
46
+ pos = self.parent.parent.source_begin
47
+ first_two = lines[pos[0]-1][pos[1],2]
48
+ if first_two[0,1] == '"' || first_two == '%Q'
49
+ eval(%Q{"#{str}"})
50
+ else
51
+ str
52
+ end
53
+ when :string_content
54
+ children.map(&:constant_value).join
55
+ when :string_literal, :symbol_literal
56
+ self[1].constant_value
57
+ when :@int
58
+ Integer(self[1])
59
+ when :@float
60
+ Float(self[1])
61
+ when :@regexp_end
62
+ str = self[1]
63
+ result = 0
64
+ result |= Regexp::IGNORECASE if str.include?('i')
65
+ result |= Regexp::MULTILINE if str.include?('m')
66
+ result |= Regexp::EXTENDED if str.include?('x')
67
+ result
68
+ when :regexp_literal
69
+ parts, options = children
70
+ Regexp.new(parts.map(&:constant_value).join, options.constant_value)
71
+ when :assoc_new
72
+ children.map(&:constant_value)
73
+ when :assoclist_from_args, :bare_assoc_hash
74
+ parts = self[1]
75
+ Hash[*parts.map(&:constant_value).flatten]
76
+ when :hash
77
+ part = self[1]
78
+ part.nil? ? {} : part.constant_value
79
+ when :symbol
80
+ self[1][1].to_sym
81
+ when :dyna_symbol
82
+ parts = self[1]
83
+ parts.map(&:constant_value).join.to_sym
84
+ when :@label
85
+ self[1][0..-2].to_sym
86
+ when :array
87
+ parts = self[1]
88
+ parts.nil? ? [] : parts.map(&:constant_value)
89
+ when :var_ref, :const_path_ref, :const_ref, :var_field
90
+ case self[1].type
91
+ when :@kw
92
+ case self[1][1]
93
+ when 'self' then scope.self_ptr
94
+ when 'nil' then nil
95
+ when 'true' then true
96
+ when 'false' then false
97
+ when '__LINE__' then self[1][2][0]
98
+ when '__FILE__' then @file_name
99
+ end
100
+ else
101
+ scope.lookup(expanded_identifier).value
102
+ end
103
+ when :dot2
104
+ lhs, rhs = children
105
+ (lhs.constant_value)..(rhs.constant_value)
106
+ when :dot3
107
+ lhs, rhs = children
108
+ (lhs.constant_value)...(rhs.constant_value)
109
+ when :paren
110
+ self[1].last.constant_value
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end