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,46 @@
1
+ require 'rake'
2
+ module Laser
3
+ module Rake
4
+ class LaserTask
5
+ include ::Rake::DSL
6
+
7
+ Settings = Struct.new(:libs, :extras, :options, :using, :fix) do
8
+ def initialize(*args)
9
+ super
10
+ self.libs ||= []
11
+ self.extras ||= []
12
+ self.options ||= ''
13
+ self.using ||= []
14
+ self.fix ||= []
15
+ end
16
+ end
17
+
18
+ attr_accessor :settings
19
+
20
+ def initialize(task_name)
21
+ @settings = Settings.new
22
+ yield @settings if block_given?
23
+ @settings.using = [:all] if @settings.using.empty?
24
+ task task_name do
25
+ run
26
+ end
27
+ end
28
+
29
+ def run
30
+ require 'laser'
31
+ files = []
32
+ if @settings.libs.any?
33
+ @settings.libs.each do |lib|
34
+ Dir["#{lib}/**/*.rb"].each do |file|
35
+ files << file
36
+ end
37
+ end
38
+ end
39
+ runner = Laser::Runner.new(self.settings.options.split(/\s/) + files)
40
+ runner.using = self.settings.using
41
+ runner.fix = self.settings.fix
42
+ runner.run
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,189 @@
1
+ module Laser
2
+ class Runner
3
+ attr_accessor :using, :fix
4
+
5
+ def initialize(argv)
6
+ @argv = argv
7
+ @using = [:all]
8
+ @fix = [:all]
9
+ end
10
+
11
+ def run
12
+ settings, files = collect_options_and_arguments
13
+ # parse_forest: Array<Array<String, Sexp>>
14
+ parse_forest = files.zip(files.map { |file| Ripper.sexp(read_file(file))})
15
+ settings[:__using__] = warnings_to_consider
16
+ settings[:__fix__] = warnings_to_fix
17
+ scanner = Scanner.new(settings)
18
+ warnings = collect_warnings(files, scanner)
19
+ display_warnings(warnings, settings) if settings[:display]
20
+ print_modules if settings[:"list-modules"]
21
+ end
22
+
23
+ def collect_options_and_arguments
24
+ swizzling_argv do
25
+ settings = get_settings
26
+ handle_global_options(settings)
27
+ p settings if settings[:debug]
28
+ files = ARGV.dup
29
+ [settings, files]
30
+ end
31
+ end
32
+
33
+ # Processes the global options, which includes picking which warnings to
34
+ # run against the source code. The settings provided determine what
35
+ # modifies the runner's settings.
36
+ #
37
+ # @param [Hash] settings the settings from the command-line to process.
38
+ # @option settings :only (String) a list of warning names or short names
39
+ # that will be the only warnings run. The names should be whitespace-delimited.
40
+ # @option settings :"line-length" (Integer) a maximum line length to
41
+ # generate a warning for. A common choice is 80/83.
42
+ def handle_global_options(settings)
43
+ if settings[:"line-length"]
44
+ @using << Laser.LineLengthWarning(settings[:"line-length"])
45
+ end
46
+ if (only_name = settings[:only])
47
+ @fix = @using = Warning.concrete_warnings.select do |w|
48
+ classname = w.name && w.name.split('::').last
49
+ (classname && only_name.index(classname)) || (w.short_name && w.short_name.index(only_name))
50
+ end
51
+ end
52
+ if settings[:profile]
53
+ require 'benchmark'
54
+ require 'profile'
55
+ SETTINGS[:profile] = true
56
+ end
57
+ ARGV.replace(['(stdin)']) if settings[:stdin]
58
+ end
59
+
60
+ # Parses the command-line options using Trollop
61
+ #
62
+ # @return [Hash{Symbol => Object}] the settings entered by the user
63
+ def get_settings
64
+ warning_opts = get_warning_options
65
+ Trollop::options do
66
+ banner 'LASER: Lexically- and Semantically-Enriched Ruby'
67
+ opt :fix, 'Should errors be fixed in-line?', short: '-f'
68
+ opt :display, 'Should errors be displayed?', short: '-b', default: true
69
+ opt :'report-fixed', 'Should fixed errors be reported anyway?', short: '-r'
70
+ opt :'line-length', 'Warn at the given line length', short: '-l', type: :int
71
+ opt :only, 'Only consider the given warning (by short or full name)', short: '-O', type: :string
72
+ opt :stdin, 'Read Ruby code from standard input', short: '-s'
73
+ opt :'list-modules', 'Print the discovered, loaded modules'
74
+ opt :profile, 'Run the profiler during execution'
75
+ warning_opts.each { |warning| opt(*warning) }
76
+ end
77
+ end
78
+
79
+ # Gets all the options from the warning plugins and collects them
80
+ # with overriding rules. The later the declaration is run, the higher the
81
+ # priority the option has.
82
+ def get_warning_options
83
+ all_options = Warning.all_warnings.inject({}) do |result, warning|
84
+ options = warning.options
85
+ options = [options] if options.any? && !options[0].is_a?(Array)
86
+ options.each do |option|
87
+ result[option.first] = option
88
+ end
89
+ result
90
+ end
91
+ all_options.values
92
+ end
93
+
94
+ # Prints the known modules after analysis.
95
+ def print_modules
96
+ Analysis::LaserModule.all_modules.map do |mod|
97
+ result = []
98
+ result << if Analysis::LaserClass === mod && mod.superclass
99
+ then "#{mod.path} < #{mod.superclass.path}"
100
+ else mod.name
101
+ end
102
+ result
103
+ end.sort.flatten.each { |name| puts name }
104
+ end
105
+
106
+ def read_file(file)
107
+ case file
108
+ when '(stdin)' then $stdin.read
109
+ else File.read(file)
110
+ end
111
+ end
112
+
113
+ # Converts a list of warnings and symbol shortcuts for warnings to just a
114
+ # list of warnings.
115
+ def convert_warning_list(list)
116
+ list.map do |list|
117
+ case list
118
+ when :all then Warning.all_warnings
119
+ when :whitespace
120
+ [ExtraBlankLinesWarning, ExtraWhitespaceWarning,
121
+ OperatorSpacing, MisalignedUnindentationWarning]
122
+ else list
123
+ end
124
+ end.flatten
125
+ end
126
+
127
+ # Returns the list of warnings the user has activated for use.
128
+ def warnings_to_consider
129
+ convert_warning_list(@using)
130
+ end
131
+
132
+ # Returns the list of warnings the user has selected for fixing
133
+ def warnings_to_fix
134
+ convert_warning_list(@fix)
135
+ end
136
+
137
+ # Sets the ARGV variable to the runner's arguments during the execution
138
+ # of the block.
139
+ def swizzling_argv
140
+ old_argv = ARGV.dup
141
+ ARGV.replace @argv
142
+ yield
143
+ ensure
144
+ ARGV.replace old_argv
145
+ end
146
+
147
+ # Collects warnings from all the provided files by running them through
148
+ # the scanner.
149
+ #
150
+ # @param [Array<String>] files the files to scan. If (stdin) is in the
151
+ # array, then data will be read from STDIN until EOF is reached.
152
+ # @param [Scanner] scanner the scanner that will look for warnings
153
+ # in the source text.
154
+ # @return [Array<Warning>] a set of warnings, ordered by file.
155
+ def collect_warnings(files, scanner)
156
+ full_list = files.map do |file|
157
+ data = file == '(stdin)' ? STDIN.read : File.read(file)
158
+ if scanner.settings[:fix]
159
+ scanner.settings[:output_file] = scanner.settings[:stdin] ? STDOUT : File.open(file, 'w')
160
+ end
161
+ results = scanner.scan(data, file)
162
+ if scanner.settings[:fix] && !scanner.settings[:stdin]
163
+ scanner.settings[:output_file].close
164
+ end
165
+ results
166
+ end
167
+ full_list.flatten
168
+ end
169
+
170
+ # Displays warnings using user-provided settings.
171
+ #
172
+ # @param [Array<Warning>] warnings the warnings generated by the input
173
+ # files, ordered by file
174
+ # @param [Hash{Symbol => Object}] settings the user-set display settings
175
+ def display_warnings(warnings, settings)
176
+ num_fixable = warnings.select { |warn| warn.fixable? }.size
177
+ num_total = warnings.size
178
+
179
+ results = "#{num_total} warnings found. #{num_fixable} are fixable."
180
+ puts results
181
+ puts '=' * results.size
182
+
183
+ warnings.each do |warning|
184
+ puts "#{warning.file}:#{warning.line_number} #{warning.name} " +
185
+ "(#{warning.severity}) - #{warning.desc}"
186
+ end
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,169 @@
1
+ module Laser
2
+ class Scanner
3
+ attr_accessor :settings
4
+ attr_accessor :indent_stack
5
+
6
+ DEFAULT_SETTINGS = {fix: false, output: STDOUT, indent_size: 2,
7
+ __using__: Laser::Warning.warning_set,
8
+ __fix__: Laser::Warning.warning_set}
9
+
10
+ # Initializes the scanner with the given settings
11
+ #
12
+ # @param [Hash] settings the settings to use to customize this scanner's
13
+ # scanning behavior
14
+ def initialize(settings = {})
15
+ @settings = DEFAULT_SETTINGS.merge(settings)
16
+ @settings[:__scanner__] = self
17
+ self.indent_stack = []
18
+ end
19
+
20
+ # Returns the list of warnings to use for scanning.
21
+ def using
22
+ @settings[:__using__]
23
+ end
24
+
25
+ # Should we use this warning?
26
+ def using?(warning)
27
+ @settings[:__using__].include? warning
28
+ end
29
+
30
+ # Returns the list of warnings to use for scanning.
31
+ def fix
32
+ @settings[:__fix__]
33
+ end
34
+
35
+ # Should we use this warning?
36
+ def fixing?(warning)
37
+ @settings[:__fix__].include? warning.class
38
+ end
39
+
40
+ # Scans the text for warnings.
41
+ #
42
+ # @param [String] text the input ruby file to scan
43
+ # @return [Array[Laser::Warnings]] the warnings generated by the code.
44
+ # If the code is clean, an empty array is returned.
45
+ def scan(text, filename='(none)')
46
+ warnings = scan_for_file_warnings(text, filename)
47
+ text = filter_fixable(warnings).inject(text) do |text, warning|
48
+ warning.fix(text)
49
+ end
50
+ with_fixing_piped_to_output do
51
+ text.split(/\n/).each_with_index do |line, number|
52
+ warnings.concat process_line(line, number + 1, filename)
53
+ end
54
+ end
55
+ warnings += unused_method_warnings
56
+ warnings
57
+ end
58
+
59
+ def with_fixing_piped_to_output
60
+ self.settings[:output_lines] = []
61
+ yield
62
+ if @settings[:fix]
63
+ self.settings[:output_file].write self.settings[:output_lines].join("\n")
64
+ end
65
+ end
66
+
67
+ # Finds all matching warnings, and if the user wishes, fix a subset of them.
68
+ def process_line(line, line_number, filename)
69
+ warnings = all_warnings_for_line(line, line_number, filename)
70
+ fix_input(warnings, line, line_number, filename) if @settings[:fix]
71
+ warnings
72
+ end
73
+
74
+ # Tries to fix the given line with a set of matching warnings for that line.
75
+ # May recurse if there are multiple warnings on the same line.
76
+ def fix_input(warnings, line, line_number, filename)
77
+ fixable_warnings = filter_fixable warnings
78
+ if fixable_warnings.size == 1
79
+ self.settings[:output_lines] << fixable_warnings.first.fix rescue line
80
+ elsif fixable_warnings.size > 1
81
+ new_text = fixable_warnings.first.fix rescue line
82
+ process_line(new_text, line_number, filename)
83
+ else
84
+ self.settings[:output_lines] << line
85
+ end
86
+ end
87
+
88
+ # Returns all warnings that match the line
89
+ def all_warnings_for_line(line, line_number, filename)
90
+ new_warnings = check_for_indent_warnings!(line, filename)
91
+ new_warnings.concat scan_for_line_warnings(line, filename)
92
+ new_warnings.each {|warning| warning.line_number = line_number}
93
+ end
94
+
95
+ # Returns only the warnings that we should fix
96
+ def filter_fixable(warnings)
97
+ warnings.select {|warning| warning.fixable? && fixing?(warning) }
98
+ end
99
+
100
+ # Checks for new warnings based on indentation.
101
+ def check_for_indent_warnings!(line, filename)
102
+ return [] if line == ""
103
+ indent_size = get_indent_size line
104
+ if indent_size > current_indent
105
+ self.indent_stack.push indent_size
106
+ elsif indent_size < current_indent
107
+ previous = self.indent_stack.pop
108
+ if indent_size != current_indent &&
109
+ using.include?(MisalignedUnindentationWarning)
110
+ warnings_to_check = [MisalignedUnindentationWarning.new(filename, line, current_indent)]
111
+ return filtered_warnings_from_line(line, warnings_to_check)
112
+ end
113
+ end
114
+ []
115
+ end
116
+
117
+ def unused_method_warnings
118
+ methods = Analysis::UnusedMethodDetection.unused_methods
119
+ methods.map do |method|
120
+ ast_node = method.proc.ast_node
121
+ UncalledMethodWarning.new(ast_node.file_name, ast_node.line_number, method: method)
122
+ end
123
+ end
124
+
125
+ # Gets the current indent size
126
+ def current_indent
127
+ self.indent_stack.last || 0
128
+ end
129
+
130
+ # Gets the indent size of a given line
131
+ def get_indent_size(line)
132
+ line.match(/^\s*/)[0].size
133
+ end
134
+
135
+ # Goes through all file warning subclasses and see what warnings the file
136
+ # generates as a whole.
137
+ def scan_for_file_warnings(file, filename)
138
+ scan_for_warnings(using & FileWarning.all_warnings, file, filename)
139
+ end
140
+
141
+ # Goes through all line warning subclasses and checks if we got some new
142
+ # warnings for a given line
143
+ def scan_for_line_warnings(line, filename)
144
+ warnings = scan_for_warnings(using & LineWarning.all_warnings, line, filename)
145
+ filtered_warnings_from_line(line, warnings)
146
+ end
147
+
148
+ private
149
+
150
+ # Filters the list of warnings by checking the line for warnings to
151
+ # ignore. The line should contain "laser: ignore ClassToIgnore" in a comment,
152
+ # though you can omit the space between "laser:" and "ignore".
153
+ def filtered_warnings_from_line(line, warnings)
154
+ match = line.match(/#.*laser:\s*ignore\s+(.*)$/)
155
+ return warnings unless match && ignore_label = match[1]
156
+ class_names = ignore_label.split
157
+ result = warnings.reject do |warning|
158
+ class_names.include?(warning.class.name.gsub(/.*::(.*)/, '\1')) ||
159
+ class_names.include?(warning.class.short_name)
160
+ end
161
+ result
162
+ end
163
+
164
+ def scan_for_warnings(warnings, content, filename)
165
+ warnings.map! { |warning| warning.new(filename, content, @settings)}
166
+ warnings.map { |warning| warning.generated_warnings(warning.body)}.flatten
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,110 @@
1
+ class Thread
2
+ class << self
3
+ def abort_on_exception
4
+ end
5
+
6
+ def abort_on_exception=(bool)
7
+ end
8
+
9
+ def current
10
+ end
11
+
12
+ # yields: once
13
+ def exclusive
14
+ end
15
+
16
+ def exit
17
+ end
18
+
19
+ def start(*args)
20
+ end
21
+ alias :fork :start
22
+
23
+ def kill(thread)
24
+ end
25
+
26
+ def list
27
+ end
28
+
29
+ def main
30
+ end
31
+
32
+ def pass
33
+ end
34
+
35
+ def stop
36
+ end
37
+ end
38
+
39
+ def [](key)
40
+ end
41
+
42
+ def []=(key, val)
43
+ end
44
+
45
+ def abort_on_exception
46
+ end
47
+
48
+ def abort_on_exception=(val)
49
+ end
50
+
51
+ def add_trace_func(proc)
52
+ end
53
+
54
+ def alive?
55
+ end
56
+
57
+ def backtrace
58
+ end
59
+
60
+ def exit
61
+ end
62
+ alias kill exit
63
+ alias terminate exit
64
+
65
+ def group
66
+ end
67
+
68
+ def inspect
69
+ end
70
+
71
+ def join(limit=nil)
72
+ end
73
+
74
+ def key?(sym)
75
+ end
76
+
77
+ def keys
78
+ end
79
+
80
+ def priority
81
+ end
82
+
83
+ def priority=(val)
84
+ end
85
+
86
+ # raises: always
87
+ def raise(*args)
88
+ end
89
+
90
+ def run
91
+ end
92
+
93
+ def safe_level
94
+ end
95
+
96
+ def set_trace_func(proc)
97
+ end
98
+
99
+ def status
100
+ end
101
+
102
+ def stop?
103
+ end
104
+
105
+ def value
106
+ end
107
+
108
+ def wakeup
109
+ end
110
+ end