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,433 @@
1
+ require 'set'
2
+ module Laser
3
+ module Types
4
+ # All these relations are very inefficient, but they don't show up in
5
+ # profiling, yet.
6
+ #
7
+ # Subtype relation. Extremely important. Don't mess it up.
8
+ def self.subtype?(sub, top)
9
+ case top
10
+ when ClassObjectType
11
+ sub.possible_classes.all? { |sub_class| sub_class <= top.class_object }
12
+ when ClassType
13
+ if top.variance == :invariant
14
+ klass = top.possible_classes.first
15
+ sub.possible_classes.all? do |sub_class|
16
+ if Analysis::LaserSingletonClass === sub_class
17
+ sub_class <= klass
18
+ else
19
+ sub_class == klass
20
+ end
21
+ end
22
+ else
23
+ sub.possible_classes.subset?(top.possible_classes)
24
+ end
25
+ when UnionType
26
+ top.member_types.any? { |member| subtype?(sub, member) }
27
+ else
28
+ sub.possible_classes.subset?(top.possible_classes)
29
+ end
30
+ end
31
+
32
+ def self.equal?(t1, t2)
33
+ t1.possible_classes == t2.possible_classes
34
+ end
35
+
36
+ def self.overlap?(t1, t2)
37
+ !(t1.possible_classes & t2.possible_classes).empty?
38
+ end
39
+
40
+ def self.optional(t1)
41
+ Types::UnionType.new([t1, Types::NILCLASS])
42
+ end
43
+
44
+ class Base
45
+ extend ActsAsStruct
46
+
47
+ def |(other)
48
+ UnionType.new([self, other])
49
+ end
50
+
51
+ def hash
52
+ signature.values.map(&:hash).inject(:+)
53
+ end
54
+
55
+ def eql?(other)
56
+ self == other
57
+ end
58
+
59
+ def ==(other)
60
+ signature.inject(true) {|cur, (name, val)| cur && (val == other.send(name)) }
61
+ end
62
+ end
63
+
64
+ class UnionType < Base
65
+ acts_as_struct :member_types
66
+ def initialize(member_types)
67
+ @member_types = Set.new(flatten_unions(member_types))
68
+ end
69
+
70
+ def flatten_unions(types)
71
+ result = []
72
+ types.each do |type|
73
+ if UnionType === type
74
+ result += type.member_types.to_a
75
+ else
76
+ result << type
77
+ end
78
+ end
79
+ result
80
+ end
81
+
82
+ def signature
83
+ {member_types: member_types}
84
+ end
85
+
86
+ def possible_classes
87
+ member_types.map { |type| type.possible_classes }.inject(:|) || Set[]
88
+ end
89
+
90
+ def public_matching_methods(name)
91
+ name = name.to_sym
92
+ member_types.map { |type| type.public_matching_methods(name) }.flatten.uniq
93
+ end
94
+
95
+ def matching_methods(name)
96
+ name = name.to_sym
97
+ member_types.map { |type| type.matching_methods(name) }.flatten.uniq
98
+ end
99
+ end
100
+
101
+ class SelfType < Base
102
+ acts_as_struct :scope
103
+
104
+ def signature
105
+ {scope: scope}
106
+ end
107
+ end
108
+
109
+ class StructuralType < Base
110
+ acts_as_struct :method_name, :argument_types, :return_type
111
+
112
+ def signature
113
+ {method_name: method_name, argument_types: argument_types,
114
+ return_type: return_type}
115
+ end
116
+ end
117
+
118
+ class ClassObjectType < Base
119
+ attr_reader :class_object
120
+ def initialize(class_object)
121
+ if String === class_object
122
+ @class_object = Analysis::ClassRegistry[class_object]
123
+ else
124
+ @class_object = class_object
125
+ end
126
+ end
127
+
128
+ def ==(other)
129
+ Types::equal?(self, other)
130
+ end
131
+
132
+ def inspect
133
+ "#<ClassObjectType: #{class_object.name}>"
134
+ end
135
+
136
+ def member_types
137
+ [self]
138
+ end
139
+
140
+ def possible_classes
141
+ Set[class_object]
142
+ end
143
+
144
+ def matching_methods(name)
145
+ [*class_object.instance_method(name)]
146
+ end
147
+
148
+ def public_matching_methods(name)
149
+ [*class_object.public_instance_method(name)]
150
+ end
151
+
152
+ def class_name
153
+ class_object.name
154
+ end
155
+
156
+ def variance
157
+ :invariant
158
+ end
159
+
160
+ def signature
161
+ {class_name: class_object.name, variance: :invariant}
162
+ end
163
+ end
164
+
165
+ class ClassType < Base
166
+ acts_as_struct :class_name, :variance
167
+ def inspect
168
+ "#<Class: #{class_name} variance: #{variance}>"
169
+ end
170
+
171
+ def member_types
172
+ [self]
173
+ end
174
+
175
+ def public_matching_methods(name)
176
+ name = name.to_sym
177
+ possible_classes.map do |klass|
178
+ klass.instance_method(name) if klass.visibility_table[name] == :public
179
+ end.compact.uniq
180
+ end
181
+
182
+ def matching_methods(name)
183
+ name = name.to_sym
184
+ possible_classes.map { |klass| klass.instance_method(name) }.compact.uniq
185
+ end
186
+
187
+ def possible_classes
188
+ klass = Analysis::ClassRegistry[class_name]
189
+ case variance
190
+ when :invariant then ::Set[klass]
191
+ when :covariant
192
+ if Analysis::LaserClass === klass
193
+ then ::Set.new klass.subset
194
+ else ::Set.new klass.classes_including.map(&:subset).flatten # module
195
+ end
196
+ when :contravariant then ::Set.new klass.superset
197
+ end
198
+ end
199
+
200
+ def signature
201
+ {class_name: class_name, variance: variance}
202
+ end
203
+ end
204
+
205
+ TOP = ClassType.new('BasicObject', :covariant)
206
+ STRING = ClassObjectType.new('String')
207
+ FIXNUM = ClassObjectType.new('Fixnum')
208
+ BIGNUM = ClassObjectType.new('Bignum')
209
+ FLOAT = ClassObjectType.new('Float')
210
+ ARRAY = ClassObjectType.new('Array')
211
+ HASH = ClassObjectType.new('Hash')
212
+ PROC = ClassObjectType.new('Proc')
213
+ NILCLASS = ClassObjectType.new('NilClass')
214
+ TRUECLASS = ClassObjectType.new('TrueClass')
215
+ FALSECLASS = ClassObjectType.new('FalseClass')
216
+ FALSY = UnionType.new([FALSECLASS, NILCLASS])
217
+ BOOLEAN = UnionType.new([TRUECLASS, FALSECLASS])
218
+ BLOCK = UnionType.new([PROC, NILCLASS])
219
+ EMPTY = UnionType.new([])
220
+
221
+ class GenericType < Base
222
+ acts_as_struct :base_type, :subtypes
223
+
224
+ def signature
225
+ {base_type: base_type, subtypes: subtypes}
226
+ end
227
+ end
228
+
229
+ # Represents a Tuple: an array of a given, fixed size, with each position
230
+ # in the array possessing a set of constraints.
231
+ class TupleType < Base
232
+ attr_reader :element_types
233
+ def initialize(element_types)
234
+ @element_types = element_types
235
+ end
236
+
237
+ def size
238
+ element_types.size
239
+ end
240
+
241
+ def [](idx)
242
+ element_types[idx]
243
+ end
244
+
245
+ def possible_classes
246
+ ::Set[Analysis::ClassRegistry['Array']]
247
+ end
248
+
249
+ def member_types
250
+ [self]
251
+ end
252
+
253
+ def public_matching_methods(name)
254
+ if ClassRegistry['Array'].visibility_for(name) == :public
255
+ matching_methods(name)
256
+ else
257
+ Types::ARRAY.public_matching_methods(name)
258
+ end
259
+ end
260
+
261
+ def matching_methods(name)
262
+ name = name.to_sym
263
+ case name
264
+ when :[]
265
+ [TupleIndexMethod.new(self)]
266
+ when :to_a, :to_ary
267
+ [TupleSelfMethod.new(self, name)]
268
+ when :+
269
+ [TuplePlusMethod.new(self)]
270
+ when :*
271
+ [TupleTimesMethod.new(self)]
272
+ else
273
+ Types::ARRAY.matching_methods(name)
274
+ end
275
+ end
276
+
277
+ def signature
278
+ {element_types: element_types}
279
+ end
280
+
281
+ class TupleMethod
282
+ attr_reader :tuple_type
283
+
284
+ def initialize(tuple_type)
285
+ @tuple_type = tuple_type
286
+ end
287
+
288
+ def method_missing(method, *args, &blk)
289
+ Analysis::ClassRegistry['Array'].instance_method(name).send(method, *args, &blk)
290
+ end
291
+ end
292
+
293
+ class TupleSelfMethod < TupleMethod
294
+ attr_reader :name
295
+
296
+ def initialize(tuple_type, name)
297
+ @name = name
298
+ super(tuple_type)
299
+ end
300
+
301
+ def return_type_for_types(self_type, arg_types = [], block_type = nil)
302
+ tuple_type
303
+ end
304
+
305
+ def raise_frequency_for_types(self_type, arg_types = [], block_type = nil)
306
+ Frequency::NEVER
307
+ end
308
+
309
+ def raise_type_for_types(self_type, arg_types = [], block_type = nil)
310
+ Types::EMPTY
311
+ end
312
+ end
313
+
314
+ class TuplePlusMethod < TupleMethod
315
+ def name
316
+ '+'
317
+ end
318
+
319
+ def return_type_for_types(self_type, arg_types = [], block_type = nil)
320
+ if arg_types.first.member_types.one?
321
+ other_type = arg_types.first.member_types.first
322
+ end
323
+ if Types::TupleType === other_type
324
+ Types::TupleType.new(tuple_type.element_types + other_type.element_types)
325
+ else
326
+ Types::ARRAY
327
+ end
328
+ end
329
+
330
+ def raise_frequency_for_types(self_type, arg_types = [], block_type = nil)
331
+ Frequency::MAYBE
332
+ end
333
+
334
+ def raise_type_for_types(self_type, arg_types = [], block_type = nil)
335
+ Types::UnionType.new([Types::ClassType.new('ArgumentError', :invariant)])
336
+ end
337
+ end
338
+
339
+ class TupleTimesMethod < TupleMethod
340
+ def name
341
+ '*'
342
+ end
343
+
344
+ def return_type_for_types(self_type, arg_types = [], block_type = nil)
345
+ resulting_choices = Set.new
346
+ element_types = tuple_type.element_types
347
+
348
+ arg_types[0].possible_classes.each do |klass|
349
+ if Analysis::LaserSingletonClass === klass &&
350
+ (klass < Analysis::ClassRegistry['Integer'] || klass < Analysis::ClassRegistry['Float'])
351
+ factor = klass.get_instance.to_i
352
+ if factor >= 0
353
+ resulting_choices << TupleType.new(element_types * klass.get_instance)
354
+ end
355
+ elsif klass < Analysis::ClassRegistry['Numeric']
356
+ resulting_choices << Types::ARRAY
357
+ end
358
+ end
359
+
360
+ Types::UnionType.new(resulting_choices)
361
+ end
362
+
363
+ def raise_frequency_for_types(self_type, arg_types = [], block_type = nil)
364
+ Frequency::MAYBE
365
+ end
366
+
367
+ def raise_type_for_types(self_type, arg_types = [], block_type = nil)
368
+ Types::UnionType.new([Types::ClassType.new('ArgumentError', :invariant)])
369
+ end
370
+ end
371
+
372
+ class TupleIndexMethod < TupleMethod
373
+ def name
374
+ '[]'
375
+ end
376
+
377
+ def return_type_for_types(self_type, arg_types = [], block_type = nil)
378
+ resulting_choices = Set.new
379
+ element_types = tuple_type.element_types
380
+ if arg_types.size == 1
381
+ arg_types[0].possible_classes.each do |klass|
382
+ if Analysis::LaserSingletonClass === klass && klass < Analysis::ClassRegistry['Fixnum']
383
+ resulting_choices << (element_types[klass.get_instance] || Types::NILCLASS)
384
+ elsif Analysis::LaserSingletonClass === klass && klass < Analysis::ClassRegistry['Range']
385
+ if element_types[klass.get_instance]
386
+ resulting_choices << TupleType.new(element_types[klass.get_instance])
387
+ else # invalid ranges (arr = [1, 2]; arr[-3..3]) return nil
388
+ resulting_choices << Types::NILCLASS
389
+ end
390
+ elsif klass == Analysis::ClassRegistry['Fixnum']
391
+ resulting_choices.merge(element_types)
392
+ resulting_choices << Types::NILCLASS
393
+ elsif klass == Analysis::ClassRegistry['Range']
394
+ # no idea, just say "all arrays"
395
+ resulting_choices << Types::ARRAY
396
+ end
397
+ end
398
+ elsif arg_types.size == 2 # start, length
399
+ arg_types[0].possible_classes.each do |klass_1|
400
+ arg_types[1].possible_classes.each do |klass_2|
401
+ if Analysis::LaserSingletonClass === klass_1 && klass_1 < Analysis::ClassRegistry['Fixnum'] &&
402
+ Analysis::LaserSingletonClass === klass_2 && klass_2 < Analysis::ClassRegistry['Fixnum']
403
+ new_elts = element_types[klass_1.get_instance, klass_2.get_instance]
404
+ resulting_choices << TupleType.new(new_elts)
405
+ end
406
+ end
407
+ end
408
+ else
409
+ # error, should never reach
410
+ end
411
+ Types::UnionType.new(resulting_choices)
412
+ end
413
+
414
+ def raise_frequency_for_types(self_type, arg_types = [], block_type = nil)
415
+ Frequency::NEVER
416
+ end
417
+
418
+ def raise_type_for_types(self_type, arg_types = [], block_type = nil)
419
+ Types::EMPTY
420
+ end
421
+ end
422
+ end
423
+
424
+ EXPECTATIONS = {'to_s' => Types::STRING,
425
+ 'to_str' => Types::STRING,
426
+ 'to_i' => Types::ClassType.new('Integer', :covariant),
427
+ 'to_int' => Types::ClassType.new('Integer', :covariant),
428
+ 'to_f' => Types::FLOAT,
429
+ 'to_a' => Types::ARRAY,
430
+ 'to_ary' => Types::ARRAY,
431
+ '!' => Types::BOOLEAN }
432
+ end
433
+ end
@@ -0,0 +1,14 @@
1
+ module Laser
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 7
5
+ PATCH = 0
6
+ BUILD = 'pre1'
7
+
8
+ if BUILD.empty?
9
+ STRING = [MAJOR, MINOR, PATCH].compact.join('.')
10
+ else
11
+ STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,149 @@
1
+ module Laser
2
+ Warning = Struct.new(:name, :file, :body, :line_number, :severity) do
3
+ extend ModuleExtensions
4
+ include LexicalAnalysis
5
+ include Analysis
6
+
7
+ cattr_accessor :short_name
8
+ cattr_accessor_with_default :match_filters, []
9
+ cattr_get_and_setter :severity, :short_desc, :desc, :fixable
10
+ attr_accessor :settings
11
+
12
+ desc { "#{self.class.name} #{file}:#{line_number} (#{severity})" }
13
+
14
+ # This tracks all subclasses (and subclasses of subclasses, etc). Plus, this
15
+ # method is inherited, so Laser::LineWarning.all_subclasses will have all
16
+ # subclasses of Laser::LineWarning!
17
+ def self.all_warnings
18
+ @all_warnings ||= [self]
19
+ end
20
+
21
+ def self.warning_set(named='default')
22
+ list = YAML.load_file(File.join(File.dirname(__FILE__), 'warning_sets', named+'.yml'))
23
+ list.map { |name| Laser.const_get(name) }
24
+ end
25
+
26
+ # Returns all "concrete" warnings, that is, those that have an actual
27
+ # implementation. No meta-warnings like FileWarning/LineWarning.
28
+ #
29
+ # @return [Array<Class>] the concrete warnings you might want to use
30
+ def self.concrete_warnings
31
+ all_warnings - [self, FileWarning, LineWarning]
32
+ end
33
+
34
+ # All types should be shared and modified by *all* subclasses. This makes
35
+ # Laser::Warning.all_types a global registry.
36
+ def self.all_types
37
+ $all_types ||= Hash.new {|h,k| h[k] = []}
38
+ end
39
+
40
+ # When a Warning subclass is subclassed, store the subclass and inform the
41
+ # next superclass up the inheritance hierarchy.
42
+ def self.inherited(klass)
43
+ self.all_warnings << klass
44
+ next_klass = self.superclass
45
+ while next_klass != Laser::Warning.superclass
46
+ next_klass.send(:inherited, klass)
47
+ next_klass = next_klass.superclass
48
+ end
49
+ end
50
+
51
+ # Override in subclasses to provide a list of options to send to Trollop
52
+ def self.options
53
+ @options ||= [:debug, "Shows debug output from laser's scanner", {short: '-d'}]
54
+ end
55
+
56
+ # Adds an option in Trollop format.
57
+ def self.opt(*args)
58
+ self.options << args
59
+ end
60
+
61
+ # Modified cattr_get_and_setter that updates the class's short_name and
62
+ # registers the class as a member of the given type.
63
+ def self.type(*args)
64
+ if args.any?
65
+ @type = args.first.to_s
66
+ all_types[@type] << self
67
+ self.short_name = @type[0,2].upcase + all_types[@type].size.to_s
68
+ else
69
+ @type
70
+ end
71
+ end
72
+
73
+ # Adds an instance method that extracts a key from the settings of
74
+ # the warning. This is a simple way of storing metadata about the
75
+ # discovered error/issue for presentational purposes.
76
+ def self.setting_accessor(*syms)
77
+ syms.each { |sym| class_eval("def #{sym}\n @settings[#{sym.inspect}]\nend") }
78
+ end
79
+
80
+ # Default initializer.
81
+ def initialize(file, body, settings = {})
82
+ super(self.class.short_desc, file, body, 0, self.class.severity)
83
+ @settings = settings
84
+ end
85
+
86
+ def match?(body = self.body)
87
+ false
88
+ end
89
+
90
+ def generated_warnings(*args)
91
+ case match_result = match?(*args)
92
+ when Array then match_result
93
+ when false, nil then []
94
+ else [self]
95
+ end
96
+ end
97
+
98
+ def fix
99
+ self.body
100
+ end
101
+
102
+ def fixable?
103
+ self.class.fixable
104
+ end
105
+
106
+ def desc
107
+ case desc = self.class.desc
108
+ when String then desc
109
+ when Proc then instance_eval(&self.class.desc)
110
+ end
111
+ end
112
+
113
+ def indent(string, amt = nil)
114
+ amt ||= self.body.match(/^(\s*)/)[1].size
115
+ ' ' * amt + string.lstrip
116
+ end
117
+
118
+ def count_occurrences(string, substring)
119
+ count = 0
120
+ 0.upto(string.size - substring.size) do |start|
121
+ if string[start,substring.size] == substring
122
+ count += 1
123
+ end
124
+ end
125
+ count
126
+ end
127
+
128
+ def get_indent(line = self.body)
129
+ line =~ /^(\s*).*$/ ? $1 : ''
130
+ end
131
+ end
132
+
133
+ class LineWarning < Warning
134
+ alias_method :line, :body
135
+ def self.options
136
+ @options ||= []
137
+ end
138
+ end
139
+
140
+ class FileWarning < Warning
141
+ def self.options
142
+ @options ||= []
143
+ end
144
+ end
145
+ end
146
+
147
+ Dir[File.expand_path(File.join(File.dirname(__FILE__), 'warnings', '**', '*.rb'))].each do |file|
148
+ load file
149
+ end