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,42 @@
1
+ # Warning for rescuing "Exception" or "Object".
2
+ class Laser::RescueExceptionWarning < Laser::FileWarning
3
+ severity 5
4
+ type :dangerous
5
+ short_desc 'rescue Exception is dangerous'
6
+ desc 'The line rescues "Exception" or "Object", which is too broad. Rescue StandardError instead.'
7
+ setting_accessor :position
8
+ fixable true
9
+
10
+ def match?(body = self.body)
11
+ find_sexps(:rescue).map do |_, types, name|
12
+ case types[0]
13
+ when :mrhs_new_from_args
14
+ list = types[1] + types[2..-1]
15
+ when Array
16
+ list = types
17
+ end
18
+ list.map do |type|
19
+ if type[0] == :var_ref &&
20
+ type[1][0] == :@const && type[1][1] == "Exception"
21
+ warning = Laser::RescueExceptionWarning.new(file, body, position: type[1][2])
22
+ warning.position[0] -= 1
23
+ warning.line_number = type[1][2][1]
24
+ warning
25
+ end
26
+ end.compact
27
+ end.flatten
28
+ end
29
+
30
+ def fix(body = self.body)
31
+ result = ""
32
+ all_lines = body.lines.to_a
33
+ result << all_lines[0..position[0]-1].join if position[0]-1 >= 0
34
+ result << all_lines[position[0]][0,position[1]]
35
+ result << 'StandardError'
36
+ if trailing = all_lines[position[0]][position[1] + 'Exception'.size .. -1]
37
+ result << trailing
38
+ end
39
+ result << all_lines[position[0]+1..-1].join if position[0]+1 < all_lines.size
40
+ result
41
+ end
42
+ end
@@ -0,0 +1,25 @@
1
+ # Warning for using semicolons outside of class declarations.
2
+ class Laser::SemicolonWarning < Laser::LineWarning
3
+ type :style
4
+ short_desc 'Semicolon for multiple statements'
5
+ desc 'The line uses a semicolon to separate multiple statements outside of a class declaration.'
6
+ fixable true
7
+
8
+ def initialize(*args)
9
+ super
10
+ self.severity = line =~ /['"]/ ? 2 : 4
11
+ end
12
+
13
+ def match?(line = self.body)
14
+ !!(find_token(line, :on_semicolon) && !find_keyword(line, :class))
15
+ end
16
+
17
+ def fix(line = self.body)
18
+ left, right = split_on_token(line, :on_semicolon)
19
+ return line if right.empty?
20
+ return right[1..-1] if left.empty?
21
+
22
+ right = fix(right[1..-1])
23
+ "#{indent left}\n#{indent right}"
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ class Laser::SexpErrorWarning < Laser::FileWarning
2
+ type :dangerous
3
+ short_desc "Error"
4
+ desc { error.message }
5
+ setting_accessor :error
6
+
7
+ def line_number
8
+ error.ast_node.line_number
9
+ end
10
+
11
+ def severity
12
+ error.severity
13
+ end
14
+
15
+ def ==(other)
16
+ super && self.error == other.error
17
+ end
18
+
19
+ def match?(body = self.body)
20
+ parse.all_errors.map do |error|
21
+ Laser::SexpErrorWarning.new(error.ast_node.file_name, body, error: error)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,7 @@
1
+ # Warning for methods that are not called, ever.
2
+ class Laser::UncalledMethodWarning < Laser::FileWarning
3
+ type :dangerous
4
+ short_desc "Unused method"
5
+ desc { "The method #{method.owner.name}##{method.name} is never called." }
6
+ setting_accessor :method
7
+ end
@@ -0,0 +1,38 @@
1
+ # Warning for using semicolons outside of class declarations.
2
+ class Laser::UselessDoubleQuotesWarning < Laser::FileWarning
3
+ type :style
4
+ severity 1
5
+ short_desc 'Useless double quotes'
6
+ fixable true
7
+ setting_accessor :quoted_string, :uses_q_braces
8
+ desc do
9
+ if uses_q_braces
10
+ then "The string %q{#{quoted_string}} can be written with lowercase q for efficiency."
11
+ else "The string '#{quoted_string}' can be wrapped in single quotes for efficiency."
12
+ end
13
+ end
14
+
15
+ def match?(body = self.body)
16
+ list = find_sexps(:string_content)
17
+ list.map do |sym, *parts|
18
+ next if parts.size != 1 # ignore multiparts as they're fine
19
+ inner_sym, text, pos = parts.first
20
+ # skip if the string has a backslash or an apostrophe in it.
21
+ next unless inner_sym == :@tstring_content && text !~ /(\\)|(')/
22
+
23
+ previous_char = body.lines.to_a[pos[0] - 1][pos[1]-1,1]
24
+ uses_q_braces = (previous_char == '{' && body.lines.to_a[pos[0] - 1][pos[1]-3,2] == '%Q')
25
+ if previous_char == '"' || uses_q_braces
26
+ warning = Laser::UselessDoubleQuotesWarning.new(
27
+ file, body, quoted_string: text, uses_q_braces: uses_q_braces)
28
+ warning.line_number = pos[0]
29
+ warning
30
+ end
31
+ end.compact
32
+ end
33
+
34
+ def fix(body = self.body)
35
+ body.gsub("\"#{quoted_string}\"", "'#{quoted_string}'").
36
+ gsub("%Q{#{quoted_string}}", "%q{#{quoted_string}}")
37
+ end
38
+ end
@@ -0,0 +1,47 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe BasicAnnotation do
4
+ before(:each) do
5
+ @global_annotations = Annotations.global_annotations.dup
6
+ Annotations.global_annotations = []
7
+ @class = Class.new(BasicAnnotation) do
8
+ def annotate!(node)
9
+ node[0] = (node[0].to_s + 'lolz').intern
10
+ end
11
+ end
12
+ end
13
+
14
+ after(:each) do
15
+ Annotations.global_annotations.replace @global_annotations
16
+ end
17
+
18
+ describe '#add_global_annotator' do
19
+ it 'adds the given argument to the list of global annotations' do
20
+ foo = Class.new
21
+ @class.add_global_annotator foo
22
+ Annotations.global_annotations.last.should be_a(foo)
23
+ end
24
+ end
25
+
26
+ describe '#add_property' do
27
+ selectors = [:aaa, :aaa=, :bbb, :bbb=]
28
+ it 'adds accessors to Analysis::Sexp in a very intrusive manner' do
29
+ @class.add_property :aaa, :bbb
30
+ sexp = Sexp.new([:program, []])
31
+ selectors.each {|sel| sexp.should respond_to(sel)}
32
+ end
33
+ after do
34
+ selectors.each {|sel| Sexp.__send__(:undef_method, sel)}
35
+ end
36
+ end
37
+
38
+ describe '#add_computed_property' do
39
+ it 'adds a no-arg method that computes a property' do
40
+ @class.add_computed_property(:childsize) { self.children.size }
41
+ @class.add_global_annotator(@class)
42
+ sexp = Sexp.new([:abc, :cde, :aaa, :bbb, [:hi, 1, 2]])
43
+ sexp.childsize.should == 4
44
+ sexp.children[3].childsize.should == 2
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,68 @@
1
+ require_relative 'spec_helper'
2
+ describe CommentAttachmentAnnotation do
3
+ extend AnalysisHelpers
4
+ clean_registry
5
+
6
+ it_should_behave_like 'an annotator'
7
+
8
+ it 'adds the #docstring method to Sexp' do
9
+ Sexp.instance_methods.should include(:comment)
10
+ end
11
+
12
+ # [:program,
13
+ # [[:def,
14
+ # [:@ident, "silly", [3, 4]],
15
+ # [:paren,
16
+ # [:params,
17
+ # [[:@ident, "a", [3, 10]], [:@ident, "b", [3, 13]]],
18
+ # nil,
19
+ # nil,
20
+ # nil,
21
+ # nil]],
22
+ # [:bodystmt, [[:void_stmt]], nil, nil, nil]],
23
+ # [:class,
24
+ # [:const_ref, [:@const, "A", [6, 7]]],
25
+ # nil,
26
+ # [:bodystmt, [[:void_stmt]], nil, nil, nil]]]]
27
+ it 'discovers the comments before a method and class declaration' do
28
+ input = " # abc\n # def\ndef silly(a, b)\n end\n # a class\n class A990; end"
29
+ tree = annotate_all(input)
30
+ list = tree[1]
31
+
32
+ defn = list[0]
33
+ defn.comment.body.should == " abc\n def"
34
+ klass_defn = list[1]
35
+ klass_defn.comment.body.should == " a class"
36
+ end
37
+
38
+ # [:program,
39
+ # [[:def,
40
+ # [:@ident, "some_method", [3, 6]],
41
+ # [:paren, [:params, [[:@ident, "abc", [3, 18]]], nil, nil, nil, nil]],
42
+ # [:bodystmt,
43
+ # [[:assign,
44
+ # [:var_field, [:@ident, "y", [5, 4]]],
45
+ # [:binary,
46
+ # [:var_ref, [:@ident, "abc", [5, 8]]],
47
+ # :*,
48
+ # [:@int, "2", [5, 14]]]]],
49
+ # nil, nil, nil]]]]
50
+
51
+ it 'discovers comments before introduction of a new local variable' do
52
+ input = <<-EOF
53
+ # some method
54
+ # abc: String
55
+ def some_method(abc)
56
+ # y: String
57
+ y = abc * 2
58
+ end
59
+ EOF
60
+ tree = annotate_all(input)
61
+
62
+ list = tree[1]
63
+ defn = list[0]
64
+ defn.comment.body.should == " some method\n abc: String"
65
+ assignment = defn[3][1][0]
66
+ assignment.comment.body.should == " y: String"
67
+ end
68
+ end
@@ -0,0 +1,90 @@
1
+ require_relative 'spec_helper'
2
+ require 'set'
3
+ describe NodePointersAnnotation do
4
+ it_should_behave_like 'an annotator'
5
+
6
+ it 'adds the #parent method to Sexp' do
7
+ Sexp.instance_methods.should include(:parent)
8
+ end
9
+
10
+ it 'adds parents to each node with a toy example' do
11
+ tree = Sexp.new([:abc, Sexp.new([:def, 1, 2]),
12
+ Sexp.new([:zzz, Sexp.new([:return]), "hi", Sexp.new([:silly, 4])])])
13
+ NodePointersAnnotation.new.annotate!(tree)
14
+ expectalot(parent: { nil => [tree], tree => [tree[1], tree[2]],
15
+ tree[2] => [tree[2][1], tree[2][3]] } )
16
+ end
17
+
18
+ # This will actually verify that every node in the tree has a
19
+ # proper parent set. It's a complex, but thorough test.
20
+ it 'adds parents to each node with a real-world parse result' do
21
+ tree = Sexp.new(Ripper.sexp('x = proc {|x, *rst, &blk| p x ** rst[0]; blk.call(rst[1..-1])}'))
22
+ NodePointersAnnotation.new.annotate!(tree)
23
+ expectalot(parent: { nil => [tree], tree => [tree.children.first] })
24
+ tree.all_subtrees.each do |node|
25
+ node.parent.children.should include(node)
26
+ end
27
+ end
28
+
29
+ it 'adds the #ancestors method to Sexp' do
30
+ Sexp.instance_methods.should include(:ancestors)
31
+ end
32
+
33
+ it 'adds ancestors to each node with a toy example' do
34
+ tree = Sexp.new([:abc, Sexp.new([:def, 1, 2]),
35
+ Sexp.new([:zzz, Sexp.new([:return]), 'hi', Sexp.new([:silly, 4])])])
36
+ NodePointersAnnotation.new.annotate!(tree)
37
+ expectalot(ancestors: { [] => [tree], [tree] => [tree[1], tree[2]],
38
+ [tree, tree[2]] => [tree[2][1], tree[2][3]] } )
39
+ end
40
+
41
+ it 'adds the #root method to Sexp' do
42
+ Sexp.instance_methods.should include(:root)
43
+ end
44
+
45
+ it 'can compute the root from any node in the tree' do
46
+ tree = Sexp.new(Ripper.sexp('x = proc {|x, *rst, &blk| p x ** rst[0]; blk.call(rst[1..-1])}'))
47
+ NodePointersAnnotation.new.annotate!(tree)
48
+ tree.dfs { |node| node.root.should be tree }
49
+ end
50
+
51
+ # This will actually verify that every node in the tree has a
52
+ # proper parent set. It's a complex, but thorough test.
53
+ it 'adds parents to each node with a real-world parse result' do
54
+ tree = Sexp.new(Ripper.sexp('x = proc {|x, *rst, &blk| p x ** rst[0]; blk.call(rst[1..-1])}'))
55
+ NodePointersAnnotation.new.annotate!(tree)
56
+ expectalot(parent: { nil => [tree], tree => [tree.children.first] })
57
+ tree.all_subtrees.each do |node|
58
+ if node.parent
59
+ node.ancestors.should include(node.parent)
60
+ (node.ancestors & node.parent.ancestors).should == node.parent.ancestors
61
+ end
62
+ end
63
+ end
64
+
65
+ it 'adds the #next and #prev methods to Sexp' do
66
+ Sexp.instance_methods.should include(:next)
67
+ Sexp.instance_methods.should include(:prev)
68
+ end
69
+
70
+ it 'adds next and prevs to each node with a toy example' do
71
+ tree = Sexp.new([:abc, Sexp.new([:def, 1, 2]),
72
+ Sexp.new([:zzz, Sexp.new([:return]), "hi", Sexp.new([:silly, 4])])])
73
+ NodePointersAnnotation.new.annotate!(tree)
74
+ expectalot(prev: { nil => [tree[1], tree[2][1]], tree[1] => [tree[2]], tree[2][2] => [tree[2][3]] },
75
+ next: { nil => [tree[2], tree[2][3]], tree[2] => [tree[1]], tree[2][2] => [tree[2][1]] })
76
+ end
77
+
78
+ # This will actually verify that every node in the tree has a
79
+ # proper parent set. It's a complex, but thorough test.
80
+ it 'adds next and prevs to each node with a real-world parse result' do
81
+ tree = Sexp.new(Ripper.sexp('x = proc {|x, *rst, &blk| p x ** rst[0]; blk.call(rst[1..-1])}'))
82
+ NodePointersAnnotation.new.annotate!(tree)
83
+ expectalot(next: { nil => [tree] }, prev: { nil => [tree] })
84
+ visited = Set.new
85
+ tree.all_subtrees.each do |node|
86
+ node.prev.next.should == node if node.is_sexp?(node.prev)
87
+ node.next.prev.should == node if node.is_sexp?(node.next)
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,135 @@
1
+ require_relative 'spec_helper'
2
+ require 'set'
3
+ describe RuntimeAnnotation do
4
+ it_should_behave_like 'an annotator'
5
+
6
+ it 'adds the #runtime method to Sexp' do
7
+ Sexp.instance_methods.should include(:runtime)
8
+ end
9
+
10
+ # [:program,
11
+ # [[:assign,
12
+ # [:var_field, [:@ident, "abc", [1, 0]]],
13
+ # [:var_ref, [:@const, "ABC", [1, 6]]]]]]
14
+ it 'handles nested module/class declarations' do
15
+ input = 'module A; module B; class C; end; class D < C; end; end; end'
16
+ tree = Sexp.new(Ripper.sexp(input))
17
+ RuntimeAnnotation.new.annotate_with_text(tree, input)
18
+ tree.all_subtrees.each { |subtree| subtree.runtime.should == :load }
19
+ end
20
+
21
+ # [:program,
22
+ # [[:module,
23
+ # [:const_ref, [:@const, "A", [1, 7]]],
24
+ # [:bodystmt,
25
+ # [[:void_stmt],
26
+ # [:module,
27
+ # [:const_ref, [:@const, "B", [1, 17]]],
28
+ # [:bodystmt,
29
+ # [[:void_stmt],
30
+ # [:def,
31
+ # [:@ident, "abc", [1, 24]],
32
+ # [:paren,
33
+ # [:params,
34
+ # [[:@ident, "xyz", [1, 28]]],
35
+ # [[[:@ident, "jkl", [1, 33]],
36
+ # [:binary,
37
+ # [:var_ref, [:@ident, "xyz", [1, 37]]],
38
+ # :*,
39
+ # [:@int, "2", [1, 41]]]]],
40
+ # nil, nil, nil]],
41
+ # [:bodystmt,
42
+ # [[:void_stmt],
43
+ # [:command,
44
+ # [:@ident, "p", [1, 45]],
45
+ # [:args_add_block, [[:var_ref, [:@ident, "xyz", [1, 47]]]], false]],
46
+ # [:def,
47
+ # [:@ident, "another", [1, 56]],
48
+ # [:params, nil, nil, nil, nil, nil],
49
+ # [:bodystmt, [[:void_stmt]], nil, nil, nil]]],
50
+ # nil, nil, nil]]],
51
+ # nil, nil, nil]]],
52
+ # nil, nil, nil]]]]
53
+ it 'handles regular method definitions' do
54
+ input = 'module A; module B; def abc(xyz, jkl=xyz*2); p xyz; def another; end; end; end; end'
55
+ tree = Sexp.new(Ripper.sexp(input))
56
+ RuntimeAnnotation.new.annotate_with_text(tree, input)
57
+ mod_a = tree[1][0]
58
+ mod_b = mod_a[2][1][1]
59
+ defn = mod_b[2][1][1]
60
+ expectalot(:runtime => {
61
+ :load => [tree, tree[1], mod_a, mod_a[1], mod_a[2], mod_a[2][1],
62
+ mod_a[2][1][0], mod_b, mod_b[1], mod_b[1][1], defn, defn[1]],
63
+ :run => [*defn[2].all_subtrees, *defn[3].all_subtrees]
64
+ })
65
+ end
66
+
67
+ # [:program,
68
+ # [[:module,
69
+ # [:const_ref, [:@const, "A", [1, 7]]],
70
+ # [:bodystmt,
71
+ # [[:void_stmt],
72
+ # [:method_add_block,
73
+ # [:call,
74
+ # [[:@tstring_content, "a,", [1, 13]], [:@tstring_content, "b", [1, 16]]],
75
+ # :".",
76
+ # [:@ident, "each", [1, 19]]],
77
+ # [:brace_block,
78
+ # [:block_var,
79
+ # [:params, [[:@ident, "x", [1, 26]]], nil, nil, nil, nil],
80
+ # nil],
81
+ # [[:method_add_block,
82
+ # [:method_add_arg,
83
+ # [:fcall, [:@ident, "define_method", [1, 29]]],
84
+ # [:arg_paren,
85
+ # [:args_add_block, [[:var_ref, [:@ident, "x", [1, 43]]]], false]]],
86
+ # [:do_block,
87
+ # nil,
88
+ # [[:void_stmt], [:var_ref, [:@ident, "x", [1, 50]]]]]]]]]],
89
+ # nil, nil, nil]]]]
90
+
91
+ it 'gives up on blocks that are captured at load-time' do
92
+ # not unrealistic code! Sometime we need to know this executes at load-time!
93
+ input = 'module A; %w(a b).each {|x| define_method(x) do; x; end}; end'
94
+ tree = Sexp.new(Ripper.sexp(input))
95
+ RuntimeAnnotation.new.annotate_with_text(tree, input)
96
+ mod_a = tree[1][0]
97
+ mab_node = mod_a[2][1][1]
98
+ expectalot(:runtime => {
99
+ :load => [tree, tree[1], mod_a, mod_a[1], mod_a[2], mod_a[2][1],
100
+ mab_node, mab_node[1]],
101
+ :unknown => mab_node[2].all_subtrees
102
+ })
103
+ end
104
+
105
+ # [:program,
106
+ # [[:def,
107
+ # [:@ident, "k", [1, 4]],
108
+ # [:params, nil, nil, nil, nil, nil],
109
+ # [:bodystmt,
110
+ # [[:method_add_block,
111
+ # [:call,
112
+ # [[:@tstring_content, "a", [1, 10]], [:@tstring_content, "b", [1, 12]]],
113
+ # :".",
114
+ # [:@ident, "each", [1, 15]]],
115
+ # [:brace_block,
116
+ # [:block_var,
117
+ # [:params, [[:@ident, "x", [1, 22]]], nil, nil, nil, nil],
118
+ # nil],
119
+ # [[:method_add_block,
120
+ # [:method_add_arg,
121
+ # [:fcall, [:@ident, "define_method", [1, 25]]],
122
+ # [:arg_paren,
123
+ # [:args_add_block, [[:var_ref, [:@ident, "x", [1, 39]]]], false]]],
124
+ # [:do_block,
125
+ # nil,
126
+ # [[:void_stmt], [:var_ref, [:@ident, "x", [1, 46]]]]]]]]]],
127
+ # nil, nil, nil]]]]
128
+ it 'knows blocks captured at run-time retain run-time status' do
129
+ input = 'def k; %w(a b).each {|x| define_method(x) do; x; end}; end'
130
+ tree = Sexp.new(Ripper.sexp(input))
131
+ RuntimeAnnotation.new.annotate_with_text(tree, input)
132
+ defn = tree[1][0]
133
+ expectalot(:runtime => { :run => defn[3].all_subtrees })
134
+ end
135
+ end