laser 0.7.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (319) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +14 -0
  4. data/LICENSE +661 -0
  5. data/README.md +158 -0
  6. data/Rakefile +104 -0
  7. data/VERSION +1 -0
  8. data/bin/laser +7 -0
  9. data/design_docs/goals.md +57 -0
  10. data/design_docs/object_regex.md +426 -0
  11. data/design_docs/type_annotations.md +80 -0
  12. data/ext/laser/BasicBlock.cpp +572 -0
  13. data/ext/laser/BasicBlock.h +118 -0
  14. data/ext/laser/extconf.rb +3 -0
  15. data/features/laser.feature +25 -0
  16. data/features/step_definitions/laser_steps.rb +39 -0
  17. data/features/support/env.rb +14 -0
  18. data/features/support/testdata/1_input +1 -0
  19. data/features/support/testdata/1_output +1 -0
  20. data/features/support/testdata/2_input +4 -0
  21. data/features/support/testdata/2_output +4 -0
  22. data/features/support/testdata/3_input +8 -0
  23. data/features/support/testdata/3_output +11 -0
  24. data/features/support/testdata/4_input +5 -0
  25. data/features/support/testdata/4_output +5 -0
  26. data/features/support/testdata/5_input +13 -0
  27. data/laser.gemspec +382 -0
  28. data/lib/laser.rb +98 -0
  29. data/lib/laser/analysis/annotations.rb +95 -0
  30. data/lib/laser/analysis/annotations/annotation_config.yaml +3 -0
  31. data/lib/laser/analysis/annotations/comment_attachment_annotation.rb +66 -0
  32. data/lib/laser/analysis/annotations/node_pointers_annotation.rb +36 -0
  33. data/lib/laser/analysis/annotations/runtime_annotation.rb +55 -0
  34. data/lib/laser/analysis/argument_expansion.rb +132 -0
  35. data/lib/laser/analysis/arity.rb +34 -0
  36. data/lib/laser/analysis/bindings.rb +144 -0
  37. data/lib/laser/analysis/bootstrap/bootstrap.rb +298 -0
  38. data/lib/laser/analysis/bootstrap/laser_class.rb +106 -0
  39. data/lib/laser/analysis/bootstrap/laser_method.rb +255 -0
  40. data/lib/laser/analysis/bootstrap/laser_module.rb +403 -0
  41. data/lib/laser/analysis/bootstrap/laser_module_copy.rb +74 -0
  42. data/lib/laser/analysis/bootstrap/laser_object.rb +69 -0
  43. data/lib/laser/analysis/bootstrap/laser_proc.rb +150 -0
  44. data/lib/laser/analysis/bootstrap/laser_singleton_class.rb +44 -0
  45. data/lib/laser/analysis/comments.rb +35 -0
  46. data/lib/laser/analysis/control_flow.rb +28 -0
  47. data/lib/laser/analysis/control_flow/alias_analysis.rb +31 -0
  48. data/lib/laser/analysis/control_flow/basic_block.rb +105 -0
  49. data/lib/laser/analysis/control_flow/cfg_builder.rb +2505 -0
  50. data/lib/laser/analysis/control_flow/cfg_instruction.rb +190 -0
  51. data/lib/laser/analysis/control_flow/constant_propagation.rb +742 -0
  52. data/lib/laser/analysis/control_flow/control_flow_graph.rb +370 -0
  53. data/lib/laser/analysis/control_flow/lifetime_analysis.rb +91 -0
  54. data/lib/laser/analysis/control_flow/method_call_search.rb +26 -0
  55. data/lib/laser/analysis/control_flow/raise_properties.rb +25 -0
  56. data/lib/laser/analysis/control_flow/simulation.rb +385 -0
  57. data/lib/laser/analysis/control_flow/static_single_assignment.rb +185 -0
  58. data/lib/laser/analysis/control_flow/unreachability_analysis.rb +57 -0
  59. data/lib/laser/analysis/control_flow/unused_variables.rb +91 -0
  60. data/lib/laser/analysis/control_flow/yield_properties.rb +103 -0
  61. data/lib/laser/analysis/errors.rb +131 -0
  62. data/lib/laser/analysis/laser_utils.rb +18 -0
  63. data/lib/laser/analysis/lexical_analysis.rb +172 -0
  64. data/lib/laser/analysis/method_call.rb +68 -0
  65. data/lib/laser/analysis/protocol_registry.rb +30 -0
  66. data/lib/laser/analysis/scope.rb +118 -0
  67. data/lib/laser/analysis/sexp.rb +159 -0
  68. data/lib/laser/analysis/sexp_analysis.rb +40 -0
  69. data/lib/laser/analysis/sexp_extensions/constant_extraction.rb +115 -0
  70. data/lib/laser/analysis/sexp_extensions/source_location.rb +164 -0
  71. data/lib/laser/analysis/sexp_extensions/type_inference.rb +47 -0
  72. data/lib/laser/analysis/signature.rb +76 -0
  73. data/lib/laser/analysis/special_methods/send.rb +67 -0
  74. data/lib/laser/analysis/unused_methods.rb +21 -0
  75. data/lib/laser/analysis/visitor.rb +141 -0
  76. data/lib/laser/annotation_parser/annotations.treetop +126 -0
  77. data/lib/laser/annotation_parser/annotations_parser.rb +748 -0
  78. data/lib/laser/annotation_parser/class_annotations.treetop +82 -0
  79. data/lib/laser/annotation_parser/class_annotations_parser.rb +654 -0
  80. data/lib/laser/annotation_parser/overload.treetop +24 -0
  81. data/lib/laser/annotation_parser/overload_parser.rb +167 -0
  82. data/lib/laser/annotation_parser/parsers.rb +6 -0
  83. data/lib/laser/annotation_parser/structural.treetop +37 -0
  84. data/lib/laser/annotation_parser/structural_parser.rb +406 -0
  85. data/lib/laser/annotation_parser/useful_parsers.treetop +47 -0
  86. data/lib/laser/annotation_parser/useful_parsers_parser.rb +674 -0
  87. data/lib/laser/rake/task.rb +46 -0
  88. data/lib/laser/runner.rb +189 -0
  89. data/lib/laser/scanner.rb +169 -0
  90. data/lib/laser/standard_library/_thread.rb +110 -0
  91. data/lib/laser/standard_library/abbrev.rb +103 -0
  92. data/lib/laser/standard_library/array.rb +418 -0
  93. data/lib/laser/standard_library/base64.rb +91 -0
  94. data/lib/laser/standard_library/basic_object.rb +55 -0
  95. data/lib/laser/standard_library/benchmark.rb +556 -0
  96. data/lib/laser/standard_library/bignum.rb +185 -0
  97. data/lib/laser/standard_library/cgi.rb +275 -0
  98. data/lib/laser/standard_library/cgi/cookie.rb +147 -0
  99. data/lib/laser/standard_library/cgi/core.rb +791 -0
  100. data/lib/laser/standard_library/cgi/html.rb +1021 -0
  101. data/lib/laser/standard_library/cgi/session.rb +537 -0
  102. data/lib/laser/standard_library/cgi/session/pstore.rb +111 -0
  103. data/lib/laser/standard_library/cgi/util.rb +188 -0
  104. data/lib/laser/standard_library/class_definitions.rb +333 -0
  105. data/lib/laser/standard_library/comparable.rb +125 -0
  106. data/lib/laser/standard_library/complex.rb +162 -0
  107. data/lib/laser/standard_library/enumerable.rb +178 -0
  108. data/lib/laser/standard_library/exceptions.rb +135 -0
  109. data/lib/laser/standard_library/fixnum.rb +188 -0
  110. data/lib/laser/standard_library/float.rb +180 -0
  111. data/lib/laser/standard_library/hash.rb +237 -0
  112. data/lib/laser/standard_library/integer.rb +123 -0
  113. data/lib/laser/standard_library/laser_magic.rb +7 -0
  114. data/lib/laser/standard_library/nil_false_true.rb +113 -0
  115. data/lib/laser/standard_library/numbers.rb +192 -0
  116. data/lib/laser/standard_library/proc.rb +31 -0
  117. data/lib/laser/standard_library/set.rb +1348 -0
  118. data/lib/laser/standard_library/string.rb +666 -0
  119. data/lib/laser/standard_library/stringio.rb +2 -0
  120. data/lib/laser/standard_library/symbol.rb +125 -0
  121. data/lib/laser/standard_library/tsort.rb +242 -0
  122. data/lib/laser/support/acts_as_struct.rb +66 -0
  123. data/lib/laser/support/frequency.rb +55 -0
  124. data/lib/laser/support/inheritable_attributes.rb +145 -0
  125. data/lib/laser/support/module_extensions.rb +94 -0
  126. data/lib/laser/support/placeholder_object.rb +13 -0
  127. data/lib/laser/third_party/rgl/adjacency.rb +221 -0
  128. data/lib/laser/third_party/rgl/base.rb +228 -0
  129. data/lib/laser/third_party/rgl/bidirectional.rb +39 -0
  130. data/lib/laser/third_party/rgl/condensation.rb +47 -0
  131. data/lib/laser/third_party/rgl/connected_components.rb +138 -0
  132. data/lib/laser/third_party/rgl/control_flow.rb +170 -0
  133. data/lib/laser/third_party/rgl/depth_first_spanning_tree.rb +37 -0
  134. data/lib/laser/third_party/rgl/dominators.rb +124 -0
  135. data/lib/laser/third_party/rgl/dot.rb +93 -0
  136. data/lib/laser/third_party/rgl/graphxml.rb +51 -0
  137. data/lib/laser/third_party/rgl/implicit.rb +174 -0
  138. data/lib/laser/third_party/rgl/mutable.rb +117 -0
  139. data/lib/laser/third_party/rgl/rdot.rb +445 -0
  140. data/lib/laser/third_party/rgl/topsort.rb +72 -0
  141. data/lib/laser/third_party/rgl/transitivity.rb +180 -0
  142. data/lib/laser/third_party/rgl/traversal.rb +348 -0
  143. data/lib/laser/types/types.rb +433 -0
  144. data/lib/laser/version.rb +14 -0
  145. data/lib/laser/warning.rb +149 -0
  146. data/lib/laser/warning_sets/default.yml +13 -0
  147. data/lib/laser/warnings/assignment_in_condition.rb +20 -0
  148. data/lib/laser/warnings/comment_spacing.rb +31 -0
  149. data/lib/laser/warnings/extra_blank_lines.rb +30 -0
  150. data/lib/laser/warnings/extra_whitespace.rb +16 -0
  151. data/lib/laser/warnings/hash_symbol_18_warning.rb +63 -0
  152. data/lib/laser/warnings/hash_symbol_19_warning.rb +29 -0
  153. data/lib/laser/warnings/line_length.rb +115 -0
  154. data/lib/laser/warnings/misaligned_unindentation.rb +17 -0
  155. data/lib/laser/warnings/operator_spacing.rb +68 -0
  156. data/lib/laser/warnings/parens_on_declaration.rb +30 -0
  157. data/lib/laser/warnings/rescue_exception.rb +42 -0
  158. data/lib/laser/warnings/semicolon.rb +25 -0
  159. data/lib/laser/warnings/sexp_errors.rb +24 -0
  160. data/lib/laser/warnings/uncalled_method_warning.rb +7 -0
  161. data/lib/laser/warnings/useless_double_quotes.rb +38 -0
  162. data/spec/analysis_specs/annotations_spec.rb +47 -0
  163. data/spec/analysis_specs/annotations_specs/comment_attachment_spec.rb +68 -0
  164. data/spec/analysis_specs/annotations_specs/node_pointers_annotation_spec.rb +90 -0
  165. data/spec/analysis_specs/annotations_specs/runtime_annotation_spec.rb +135 -0
  166. data/spec/analysis_specs/annotations_specs/spec_helper.rb +33 -0
  167. data/spec/analysis_specs/argument_expansion_spec.rb +113 -0
  168. data/spec/analysis_specs/bindings_spec.rb +36 -0
  169. data/spec/analysis_specs/comment_spec.rb +93 -0
  170. data/spec/analysis_specs/control_flow_specs/cfg_instruction_spec.rb +111 -0
  171. data/spec/analysis_specs/control_flow_specs/constant_propagation_spec.rb +560 -0
  172. data/spec/analysis_specs/control_flow_specs/control_flow_graph_spec.rb +5 -0
  173. data/spec/analysis_specs/control_flow_specs/raise_properties_spec.rb +310 -0
  174. data/spec/analysis_specs/control_flow_specs/raise_type_inference_spec.rb +301 -0
  175. data/spec/analysis_specs/control_flow_specs/return_type_inference_spec.rb +431 -0
  176. data/spec/analysis_specs/control_flow_specs/simulation_spec.rb +158 -0
  177. data/spec/analysis_specs/control_flow_specs/spec_helper.rb +110 -0
  178. data/spec/analysis_specs/control_flow_specs/tuple_misuse_inference_spec.rb +125 -0
  179. data/spec/analysis_specs/control_flow_specs/unreachability_analysis_spec.rb +76 -0
  180. data/spec/analysis_specs/control_flow_specs/unused_variable_spec.rb +99 -0
  181. data/spec/analysis_specs/control_flow_specs/yield_properties_spec.rb +372 -0
  182. data/spec/analysis_specs/error_spec.rb +30 -0
  183. data/spec/analysis_specs/laser_class_spec.rb +322 -0
  184. data/spec/analysis_specs/lexical_analysis_spec.rb +184 -0
  185. data/spec/analysis_specs/protocol_registry_spec.rb +63 -0
  186. data/spec/analysis_specs/scope_annotation_spec.rb +1013 -0
  187. data/spec/analysis_specs/scope_spec.rb +126 -0
  188. data/spec/analysis_specs/sexp_analysis_spec.rb +30 -0
  189. data/spec/analysis_specs/sexp_extension_specs/constant_extraction_spec.rb +309 -0
  190. data/spec/analysis_specs/sexp_extension_specs/source_location_spec.rb +231 -0
  191. data/spec/analysis_specs/sexp_extension_specs/spec_helper.rb +1 -0
  192. data/spec/analysis_specs/sexp_extension_specs/type_inference_spec.rb +252 -0
  193. data/spec/analysis_specs/sexp_spec.rb +167 -0
  194. data/spec/analysis_specs/spec_helper.rb +27 -0
  195. data/spec/analysis_specs/unused_methods_spec.rb +65 -0
  196. data/spec/analysis_specs/visitor_spec.rb +64 -0
  197. data/spec/annotation_parser_specs/annotations_parser_spec.rb +89 -0
  198. data/spec/annotation_parser_specs/class_annotation_parser_spec.rb +120 -0
  199. data/spec/annotation_parser_specs/overload_parser_spec.rb +39 -0
  200. data/spec/annotation_parser_specs/parsers_spec.rb +14 -0
  201. data/spec/annotation_parser_specs/spec_helper.rb +1 -0
  202. data/spec/annotation_parser_specs/structural_parser_spec.rb +67 -0
  203. data/spec/laser_spec.rb +14 -0
  204. data/spec/rake_specs/spec_helper.rb +1 -0
  205. data/spec/rake_specs/task_spec.rb +67 -0
  206. data/spec/runner_spec.rb +207 -0
  207. data/spec/scanner_spec.rb +75 -0
  208. data/spec/spec_helper.rb +121 -0
  209. data/spec/standard_library/exceptions_spec.rb +19 -0
  210. data/spec/standard_library/globals_spec.rb +14 -0
  211. data/spec/standard_library/set_spec.rb +31 -0
  212. data/spec/standard_library/spec_helper.rb +1 -0
  213. data/spec/standard_library/standard_library_spec.rb +302 -0
  214. data/spec/support_specs/acts_as_struct_spec.rb +94 -0
  215. data/spec/support_specs/frequency_spec.rb +23 -0
  216. data/spec/support_specs/module_extensions_spec.rb +117 -0
  217. data/spec/support_specs/spec_helper.rb +1 -0
  218. data/spec/type_specs/spec_helper.rb +1 -0
  219. data/spec/type_specs/types_spec.rb +133 -0
  220. data/spec/warning_spec.rb +95 -0
  221. data/spec/warning_specs/assignment_in_condition_spec.rb +68 -0
  222. data/spec/warning_specs/comment_spacing_spec.rb +65 -0
  223. data/spec/warning_specs/extra_blank_lines_spec.rb +70 -0
  224. data/spec/warning_specs/extra_whitespace_spec.rb +33 -0
  225. data/spec/warning_specs/hash_symbol_18_warning_spec.rb +89 -0
  226. data/spec/warning_specs/hash_symbol_19_warning_spec.rb +63 -0
  227. data/spec/warning_specs/line_length_spec.rb +173 -0
  228. data/spec/warning_specs/misaligned_unindentation_spec.rb +35 -0
  229. data/spec/warning_specs/operator_spacing_spec.rb +104 -0
  230. data/spec/warning_specs/parens_on_declaration_spec.rb +57 -0
  231. data/spec/warning_specs/rescue_exception_spec.rb +105 -0
  232. data/spec/warning_specs/semicolon_spec.rb +58 -0
  233. data/spec/warning_specs/spec_helper.rb +1 -0
  234. data/spec/warning_specs/useless_double_quotes_spec.rb +74 -0
  235. data/status_reports/2010/12/2010-12-14.md +163 -0
  236. data/status_reports/2010/12/2010-12-23.md +298 -0
  237. data/status_reports/2010/12/2010-12-24.md +6 -0
  238. data/test/third_party_tests/rgl_tests/TestComponents.rb +65 -0
  239. data/test/third_party_tests/rgl_tests/TestCycles.rb +61 -0
  240. data/test/third_party_tests/rgl_tests/TestDirectedGraph.rb +125 -0
  241. data/test/third_party_tests/rgl_tests/TestDot.rb +18 -0
  242. data/test/third_party_tests/rgl_tests/TestEdge.rb +34 -0
  243. data/test/third_party_tests/rgl_tests/TestGraph.rb +71 -0
  244. data/test/third_party_tests/rgl_tests/TestGraphXML.rb +57 -0
  245. data/test/third_party_tests/rgl_tests/TestImplicit.rb +52 -0
  246. data/test/third_party_tests/rgl_tests/TestRdot.rb +863 -0
  247. data/test/third_party_tests/rgl_tests/TestTransitivity.rb +129 -0
  248. data/test/third_party_tests/rgl_tests/TestTraversal.rb +220 -0
  249. data/test/third_party_tests/rgl_tests/TestUnDirectedGraph.rb +102 -0
  250. data/test/third_party_tests/rgl_tests/examples/north/Graph.log +128 -0
  251. data/test/third_party_tests/rgl_tests/examples/north/g.10.0.graphml +28 -0
  252. data/test/third_party_tests/rgl_tests/examples/north/g.10.1.graphml +28 -0
  253. data/test/third_party_tests/rgl_tests/examples/north/g.10.11.graphml +31 -0
  254. data/test/third_party_tests/rgl_tests/examples/north/g.10.12.graphml +27 -0
  255. data/test/third_party_tests/rgl_tests/examples/north/g.10.13.graphml +27 -0
  256. data/test/third_party_tests/rgl_tests/examples/north/g.10.14.graphml +27 -0
  257. data/test/third_party_tests/rgl_tests/examples/north/g.10.15.graphml +26 -0
  258. data/test/third_party_tests/rgl_tests/examples/north/g.10.16.graphml +26 -0
  259. data/test/third_party_tests/rgl_tests/examples/north/g.10.17.graphml +26 -0
  260. data/test/third_party_tests/rgl_tests/examples/north/g.10.19.graphml +37 -0
  261. data/test/third_party_tests/rgl_tests/examples/north/g.10.2.graphml +28 -0
  262. data/test/third_party_tests/rgl_tests/examples/north/g.10.20.graphml +38 -0
  263. data/test/third_party_tests/rgl_tests/examples/north/g.10.22.graphml +43 -0
  264. data/test/third_party_tests/rgl_tests/examples/north/g.10.24.graphml +30 -0
  265. data/test/third_party_tests/rgl_tests/examples/north/g.10.25.graphml +45 -0
  266. data/test/third_party_tests/rgl_tests/examples/north/g.10.27.graphml +38 -0
  267. data/test/third_party_tests/rgl_tests/examples/north/g.10.28.graphml +30 -0
  268. data/test/third_party_tests/rgl_tests/examples/north/g.10.29.graphml +38 -0
  269. data/test/third_party_tests/rgl_tests/examples/north/g.10.3.graphml +26 -0
  270. data/test/third_party_tests/rgl_tests/examples/north/g.10.30.graphml +34 -0
  271. data/test/third_party_tests/rgl_tests/examples/north/g.10.31.graphml +42 -0
  272. data/test/third_party_tests/rgl_tests/examples/north/g.10.34.graphml +42 -0
  273. data/test/third_party_tests/rgl_tests/examples/north/g.10.37.graphml +28 -0
  274. data/test/third_party_tests/rgl_tests/examples/north/g.10.38.graphml +38 -0
  275. data/test/third_party_tests/rgl_tests/examples/north/g.10.39.graphml +36 -0
  276. data/test/third_party_tests/rgl_tests/examples/north/g.10.4.graphml +26 -0
  277. data/test/third_party_tests/rgl_tests/examples/north/g.10.40.graphml +37 -0
  278. data/test/third_party_tests/rgl_tests/examples/north/g.10.41.graphml +37 -0
  279. data/test/third_party_tests/rgl_tests/examples/north/g.10.42.graphml +26 -0
  280. data/test/third_party_tests/rgl_tests/examples/north/g.10.45.graphml +28 -0
  281. data/test/third_party_tests/rgl_tests/examples/north/g.10.46.graphml +32 -0
  282. data/test/third_party_tests/rgl_tests/examples/north/g.10.5.graphml +31 -0
  283. data/test/third_party_tests/rgl_tests/examples/north/g.10.50.graphml +30 -0
  284. data/test/third_party_tests/rgl_tests/examples/north/g.10.56.graphml +29 -0
  285. data/test/third_party_tests/rgl_tests/examples/north/g.10.57.graphml +32 -0
  286. data/test/third_party_tests/rgl_tests/examples/north/g.10.58.graphml +32 -0
  287. data/test/third_party_tests/rgl_tests/examples/north/g.10.6.graphml +26 -0
  288. data/test/third_party_tests/rgl_tests/examples/north/g.10.60.graphml +32 -0
  289. data/test/third_party_tests/rgl_tests/examples/north/g.10.61.graphml +34 -0
  290. data/test/third_party_tests/rgl_tests/examples/north/g.10.62.graphml +34 -0
  291. data/test/third_party_tests/rgl_tests/examples/north/g.10.68.graphml +30 -0
  292. data/test/third_party_tests/rgl_tests/examples/north/g.10.69.graphml +32 -0
  293. data/test/third_party_tests/rgl_tests/examples/north/g.10.7.graphml +29 -0
  294. data/test/third_party_tests/rgl_tests/examples/north/g.10.70.graphml +26 -0
  295. data/test/third_party_tests/rgl_tests/examples/north/g.10.71.graphml +27 -0
  296. data/test/third_party_tests/rgl_tests/examples/north/g.10.72.graphml +28 -0
  297. data/test/third_party_tests/rgl_tests/examples/north/g.10.74.graphml +29 -0
  298. data/test/third_party_tests/rgl_tests/examples/north/g.10.75.graphml +29 -0
  299. data/test/third_party_tests/rgl_tests/examples/north/g.10.78.graphml +27 -0
  300. data/test/third_party_tests/rgl_tests/examples/north/g.10.79.graphml +34 -0
  301. data/test/third_party_tests/rgl_tests/examples/north/g.10.8.graphml +29 -0
  302. data/test/third_party_tests/rgl_tests/examples/north/g.10.80.graphml +34 -0
  303. data/test/third_party_tests/rgl_tests/examples/north/g.10.82.graphml +35 -0
  304. data/test/third_party_tests/rgl_tests/examples/north/g.10.83.graphml +32 -0
  305. data/test/third_party_tests/rgl_tests/examples/north/g.10.85.graphml +34 -0
  306. data/test/third_party_tests/rgl_tests/examples/north/g.10.86.graphml +34 -0
  307. data/test/third_party_tests/rgl_tests/examples/north/g.10.88.graphml +37 -0
  308. data/test/third_party_tests/rgl_tests/examples/north/g.10.89.graphml +29 -0
  309. data/test/third_party_tests/rgl_tests/examples/north/g.10.9.graphml +26 -0
  310. data/test/third_party_tests/rgl_tests/examples/north/g.10.90.graphml +32 -0
  311. data/test/third_party_tests/rgl_tests/examples/north/g.10.91.graphml +31 -0
  312. data/test/third_party_tests/rgl_tests/examples/north/g.10.92.graphml +26 -0
  313. data/test/third_party_tests/rgl_tests/examples/north/g.10.93.graphml +32 -0
  314. data/test/third_party_tests/rgl_tests/examples/north/g.10.94.graphml +34 -0
  315. data/test/third_party_tests/rgl_tests/examples/north/g.12.8.graphml +40 -0
  316. data/test/third_party_tests/rgl_tests/examples/north/g.14.9.graphml +36 -0
  317. data/test/third_party_tests/rgl_tests/test_helper.rb +7 -0
  318. data/test/third_party_tests/test_inheritable_attributes.rb +187 -0
  319. metadata +470 -0
@@ -0,0 +1,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