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,13 @@
1
+ ---
2
+ - "AssignmentInConditionWarning"
3
+ - "InlineCommentSpaceWarning"
4
+ - "ExtraBlankLinesWarning"
5
+ - "ExtraWhitespaceWarning"
6
+ - "MisalignedUnindentationWarning"
7
+ - "OperatorSpacing"
8
+ - "ParensOnDeclarationWarning"
9
+ - "RescueExceptionWarning"
10
+ - "SemicolonWarning"
11
+ - "UselessDoubleQuotesWarning"
12
+ - "HashSymbol19Warning"
13
+ - "SexpErrorWarning"
@@ -0,0 +1,20 @@
1
+ # Warning for not having parens in a method declaration with arguments
2
+ class Laser::AssignmentInConditionWarning < Laser::FileWarning
3
+ type :gotcha
4
+ severity 3
5
+ short_desc 'Assignment in condition not in parentheses'
6
+
7
+ def match?(body = self.body)
8
+ to_search = find_sexps(:if) + find_sexps(:unless) + find_sexps(:elsif)
9
+ to_search.map do |sym, condition, _, _|
10
+ assignments = find_sexps(:assign, condition)
11
+ assignments.reject do |node|
12
+ ancestors = node.ancestors.map(&:type)
13
+ path_to_node = ancestors[ancestors.rindex(sym)..-1]
14
+ path_to_node.include?(:paren)
15
+ end
16
+ end.compact.flatten.map do |node|
17
+ Laser::AssignmentInConditionWarning.new(file, body)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,31 @@
1
+ # Warning for insufficient space between inline comments and code
2
+ class Laser::InlineCommentSpaceWarning < Laser::LineWarning
3
+ OPTION_KEY = :inline_comment_space
4
+ DEFAULT_SPACE = 2
5
+ type :style
6
+ short_desc 'Inline comment spacing error'
7
+ desc { "Inline comments must be exactly #{@settings[OPTION_KEY]} spaces from code." }
8
+ opt OPTION_KEY, 'Number of spaces between code and inline comments', default: DEFAULT_SPACE
9
+ fixable true
10
+
11
+ def match?(line = self.body)
12
+ return false unless comment_token = find_token(:on_comment)
13
+ left_of_comment = line[0,comment_token.col].lstrip
14
+ return false if left_of_comment[0,1] == '#'
15
+ stripped = left_of_comment.rstrip
16
+ return false if stripped.empty?
17
+ padding_size = left_of_comment.size - stripped.size
18
+ return spacing != padding_size
19
+ end
20
+
21
+ def fix
22
+ comment_token = find_token(:on_comment)
23
+ comment_pos = comment_token.col - 1
24
+ left_of_comment = line[0..comment_pos].rstrip
25
+ left_of_comment + (' ' * spacing) + comment_token.body
26
+ end
27
+
28
+ def spacing
29
+ @settings[OPTION_KEY] || DEFAULT_SPACE
30
+ end
31
+ end
@@ -0,0 +1,30 @@
1
+ # Warning for using semicolons outside of class declarations.
2
+ class Laser::ExtraBlankLinesWarning < Laser::FileWarning
3
+ EXTRA_LINE = /\n[\t ]*\Z/
4
+ type :style
5
+ severity 1
6
+ short_desc 'Extra blank lines'
7
+ desc { "This file has #{count_extra_lines} blank lines at the end of it." }
8
+ fixable true
9
+
10
+ def match?(body = self.body)
11
+ body =~ EXTRA_LINE
12
+ end
13
+
14
+ def fix(body = self.body)
15
+ body.gsub(/\s*\Z/, '')
16
+ end
17
+
18
+ # Counts how many extra lines there are at the end of the file.
19
+ def count_extra_lines
20
+ # We use this logic because #lines ignores blank lines at the end, and
21
+ # split(/\n/) does as well.
22
+ count = 0
23
+ working_body = self.body.dup
24
+ while working_body =~ EXTRA_LINE
25
+ working_body.sub!(EXTRA_LINE, '')
26
+ count += 1
27
+ end
28
+ count
29
+ end
30
+ end
@@ -0,0 +1,16 @@
1
+ # Warning for having extra space at the end of a line.
2
+ class Laser::ExtraWhitespaceWarning < Laser::LineWarning
3
+ type :style
4
+ severity 2
5
+ short_desc 'Extra Whitespace'
6
+ desc 'The line has trailing whitespace.'
7
+ fixable true
8
+
9
+ def match?(body = self.body)
10
+ /\s+$/ === line
11
+ end
12
+
13
+ def fix
14
+ self.line.gsub(/\s+$/, '')
15
+ end
16
+ end
@@ -0,0 +1,63 @@
1
+ # Warning for rescuing "Exception" or "Object".
2
+ class Laser::HashSymbol18Warning < Laser::FileWarning
3
+ severity 1
4
+ type :style
5
+ short_desc 'symbol hash key in 1.8 style'
6
+ desc { "The Hash key :#{tokens[1][1]} is used in a Hash literal in 1.8 style." }
7
+ fixable true
8
+ setting_accessor :tokens
9
+ setting_accessor :line_adjustments
10
+
11
+ MATCH_18 = ObjectRegex.new('symbeg (ident | kw) sp? hashrocket')
12
+
13
+ # Must implement reg_desc slightly differently from LexicalAnalysis::Token
14
+ HS18Token = Struct.new(:type, :body, :line, :col) do
15
+ # Unpacks the token from Ripper and breaks it into its separate components.
16
+ #
17
+ # @param [Array<Array<Integer, Integer>, Symbol, String>] token the token
18
+ # from Ripper that we're wrapping
19
+ def initialize(token)
20
+ (self.line, self.col), self.type, self.body = token
21
+ end
22
+
23
+ def width
24
+ body.size
25
+ end
26
+
27
+ def reg_desc
28
+ if type == :on_op && body == '=>'
29
+ 'hashrocket'
30
+ else
31
+ type.to_s.sub(/^on_/, '')
32
+ end
33
+ end
34
+ end
35
+
36
+ def match?(body = self.body)
37
+ tokens = lex(body, HS18Token)
38
+ matches = MATCH_18.all_matches(tokens)
39
+ line_adjustments = Hash.new(0)
40
+ matches.map do |match_tokens|
41
+ result = Laser::HashSymbol18Warning.new(file, body,
42
+ tokens: match_tokens,
43
+ line_adjustments: line_adjustments)
44
+ result.line_number = match_tokens[0].line
45
+ result
46
+ end
47
+ end
48
+
49
+ def fix(body = self.body)
50
+ lines = body.lines.to_a # eagerly expand lines
51
+ symbeg, ident, *spacing_and_comments, rocket = tokens
52
+ lines[symbeg.line - 1][symbeg.col + line_adjustments[symbeg.line],1] = ''
53
+ lines[ident.line - 1].insert(ident.col + line_adjustments[ident.line] + ident.width - 1, ':')
54
+ lines[rocket.line - 1][rocket.col + line_adjustments[rocket.line],2] = ''
55
+ if spacing_and_comments.last != nil && spacing_and_comments.last.type == :on_sp
56
+ lines[rocket.line - 1][rocket.col + line_adjustments[rocket.line] - 1,1] = ''
57
+ line_adjustments[rocket.line] -= 3 # chomped " =>"
58
+ else
59
+ line_adjustments[rocket.line] -= 2 # only chomped the "=>"
60
+ end
61
+ lines.join
62
+ end
63
+ end
@@ -0,0 +1,29 @@
1
+ # Warning for rescuing "Exception" or "Object".
2
+ class Laser::HashSymbol19Warning < Laser::FileWarning
3
+ severity 1
4
+ type :style
5
+ short_desc 'symbol hash key in 1.9 style'
6
+ desc { "The Hash key #{token[1]} is used in a Hash literal in 1.9 style." }
7
+ fixable true
8
+ setting_accessor :token
9
+ setting_accessor :line_adjustments
10
+
11
+ def match?(body = self.body)
12
+ line_adjustments = Hash.new(0)
13
+ lex.map do |token|
14
+ if token.type == :on_label
15
+ Laser::HashSymbol19Warning.new(file, body,
16
+ token: token,
17
+ line_adjustments: line_adjustments)
18
+ end
19
+ end.compact
20
+ end
21
+
22
+ def fix(body = self.body)
23
+ lines = body.lines.to_a # eagerly expand lines
24
+ label = token
25
+ lines[label.line - 1][label.col + line_adjustments[label.line],label.body.size] = ":#{label.body[0..-2]} =>"
26
+ line_adjustments[label.line] += 3 # " =>" is inserted and is 3 chars
27
+ lines.join
28
+ end
29
+ end
@@ -0,0 +1,115 @@
1
+ class Laser::GenericLineLengthWarning < Laser::LineWarning
2
+ cattr_accessor_with_default :line_length_limit, 80000
3
+ type :style
4
+ short_desc 'Line too long'
5
+ desc { "Line length: #{line.size} > #{self.class.line_length_limit} (max)" }
6
+ fixable true
7
+
8
+ def self.inspect
9
+ "Laser::GenericLineLengthWarning<#{line_length_limit}>"
10
+ end
11
+
12
+ def match?(body = self.body)
13
+ !!(line.rstrip.size > self.class.line_length_limit)
14
+ end
15
+
16
+ def fix(content_stack = nil)
17
+ result = handle_long_comments(self.line)
18
+ return result if result
19
+ result = try_to_fix_guarded_lines(self.line)
20
+ return result if result
21
+ self.line
22
+ end
23
+
24
+ def try_to_fix_guarded_lines(line)
25
+ return nil if line !~ /\b(if|unless)\s/ # quick fast check
26
+ code, guard = split_on_keyword(:if, :unless)
27
+ code.rstrip!
28
+ return nil if code.empty? || guard.empty? || code.strip == 'end'
29
+ # check guard for closing braces
30
+ return nil if count_occurrences(guard, '}') != count_occurrences(guard, '{')
31
+ indent = get_indent(line)
32
+ indent_unit = ' ' * @settings[:indent_size]
33
+
34
+ result = code
35
+ until guard.empty?
36
+ condition = indent + guard.strip
37
+ body = result.split(/\n/).map { |line| indent_unit + line}.join("\n")
38
+ new_condition, guard = split_on_keyword(condition[indent.size+1..-1], :if, :unless)
39
+ if new_condition.empty?
40
+ new_condition, guard = guard.rstrip, ''
41
+ else
42
+ new_condition = "#{condition[indent.size,1]}#{new_condition.rstrip}"
43
+ end
44
+ condition = indent + new_condition unless guard.empty?
45
+ result = condition + "\n" + body + "\n" + indent + 'end'
46
+ end
47
+
48
+ result
49
+ end
50
+
51
+ def handle_long_comments(line)
52
+ code, comment = split_on_token(line, :on_comment)
53
+ return nil if comment.empty?
54
+ indent, code = code.match(/^(\s*)(.*)$/)[1..2]
55
+ hashes, comment = comment.match(/^(#+\s*)(.*)$/)[1..2]
56
+ comment_cleaned = fix_long_comment(indent + hashes + comment)
57
+ code_cleaned = !code.strip.empty? ? "\n" + indent + code.rstrip : ''
58
+ comment_cleaned + code_cleaned
59
+ end
60
+
61
+ def fix_long_comment(text)
62
+ # Must have no leading text
63
+ return nil unless text =~ /^(\s*)(#+\s*)(.*)\Z/
64
+ indent, hashes, comment = $1, $2, $3
65
+ indent_size = indent.size
66
+ # The "+ 2" is (indent)#(single space)
67
+ space_for_text_per_line = self.class.line_length_limit - (indent_size + hashes.size)
68
+ lines = ['']
69
+ words = comment.split(/\s/)
70
+ quota = space_for_text_per_line
71
+ current_line = 0
72
+ while words.any?
73
+ word = words.shift
74
+ # break on word big enough to make a new line, unless its the first word
75
+ if quota - (word.size + 1) < 0 && quota < space_for_text_per_line
76
+ current_line += 1
77
+ lines << ''
78
+ quota = space_for_text_per_line
79
+ end
80
+ unless lines[current_line].empty?
81
+ lines[current_line] << ' '
82
+ quota -= 1
83
+ end
84
+ lines[current_line] << word
85
+ quota -= word.size
86
+ end
87
+ lines.map { |line| indent + hashes + line }.join("\n")
88
+ end
89
+ end
90
+
91
+ module Laser
92
+ def LineLengthCustomSeverity(size, severity)
93
+ Laser.class_eval do
94
+ if const_defined?("GenericLineLengthWarning_#{size}_#{severity}")
95
+ return const_get("GenericLineLengthWarning_#{size}_#{severity}")
96
+ end
97
+ new_warning = Class.new(Laser::GenericLineLengthWarning)
98
+ const_set("GenericLineLengthWarning_#{size}_#{severity}", new_warning)
99
+ new_warning.line_length_limit = size
100
+ new_warning.severity = severity
101
+ new_warning.desc = Laser::GenericLineLengthWarning.desc
102
+ new_warning.type(Laser::GenericLineLengthWarning.type)
103
+ new_warning
104
+ end
105
+ end
106
+
107
+ def LineLengthMaximum(size)
108
+ (@table ||= {})[size] ||= LineLengthCustomSeverity(size, 8)
109
+ end
110
+
111
+ def LineLengthWarning(size)
112
+ (@table ||= {})[size] ||= LineLengthCustomSeverity(size, 3)
113
+ end
114
+ module_function :LineLengthMaximum, :LineLengthWarning, :LineLengthCustomSeverity
115
+ end
@@ -0,0 +1,17 @@
1
+ # This warning is used when
2
+ class Laser::MisalignedUnindentationWarning < Laser::LineWarning
3
+ type :style
4
+ severity 2
5
+ short_desc 'Misaligned Unindentation'
6
+ desc { "Expected #{@expectation} spaces, but instead found #{get_indent.size}" }
7
+ fixable true
8
+
9
+ def initialize(file, line, expectation)
10
+ super(file, line)
11
+ @expectation = expectation
12
+ end
13
+
14
+ def fix
15
+ indent self.line, @expectation
16
+ end
17
+ end
@@ -0,0 +1,68 @@
1
+ # Warning for not putting space around operators
2
+ class Laser::OperatorSpacing < Laser::LineWarning
3
+ OPERATORS = %w(+ - / * != !== = == === ~= !~ += -= *= /= ** **= ||= || && &&= &= |= | & ^)
4
+
5
+ type :style
6
+ severity 5
7
+ short_desc 'No operator spacing'
8
+ desc { "Insufficient spacing around #{self.match?(self.line).body}" }
9
+ fixable true
10
+
11
+ def match?(line = self.body)
12
+ working_line = ignore_block_params line
13
+ working_line = ignore_splat_args working_line
14
+ working_line = ignore_to_proc_args working_line
15
+ working_line = ignore_array_splat_idiom working_line
16
+ lexed = lex(working_line)
17
+ lexed.each_with_index do |token, idx|
18
+ next unless token.type == :on_op
19
+ next if token.body == '::' || token.body[0,2] == '..'
20
+ next if idx == lexed.size - 1 # Last token on line (continuation) is ok
21
+ next if token.body == '-' && [:on_float, :on_int].include?(lexed[idx+1].type)
22
+ if token.body == '&' && (idx == 0 || [:on_sp, :on_lparen, :on_comma].include?(lexed[idx-1].type))
23
+ next if [:on_lparen, :on_comma, :on_sp].include?(lexed[idx+1].type) ||
24
+ (lexed[idx+2] && [:on_rparen, :on_comma].include?(lexed[idx+2].type))
25
+ end
26
+ return token if lexed[idx+1].type != :on_sp && lexed[idx+1].type != :on_op
27
+ return token if idx > 0 && ![:on_sp, :on_op].include?(lexed[idx-1].type)
28
+ end
29
+ nil
30
+ end
31
+
32
+ def generated_warnings(*args)
33
+ match?(*args) ? [self] : []
34
+ end
35
+
36
+ def ignore_block_params(line)
37
+ line.gsub(/(\{|(do))\s*\|.*\|/, '\1')
38
+ end
39
+
40
+ def ignore_splat_args(line)
41
+ line.gsub(/(\(|(, ))\&([a-z][A-Za-z0-9_]*)((, )|\)|\Z)/, '\1')
42
+ end
43
+
44
+ def ignore_array_splat_idiom(line)
45
+ line.gsub(/\[\*([a-z][A-Za-z0-9_]*)\]/, '\1')
46
+ end
47
+
48
+ def ignore_to_proc_args(line)
49
+ line.gsub(/(\(|(, ))\*([a-z][A-Za-z0-9_]*)((, )|\)|\Z)/, '\1')
50
+ end
51
+
52
+ def is_block_line?(line)
53
+ line =~ /do\s*\|/ || line =~ /\{\s*\|/
54
+ end
55
+
56
+ def fix
57
+ line = self.line.dup
58
+ OPERATORS.each do |op|
59
+ next if op == '==' && line =~ /!==/
60
+ next if op == '=' && line =~ /!=/
61
+ next if op == '|' && self.is_block_line?(line)
62
+ embed = op.gsub(/(\+|\-|\*|\||\^)/, '\\\\\\1')
63
+ line.gsub!(/([A-Za-z0-9_]!|[A-Za-z0-9_?])(#{embed})/, '\1 \2')
64
+ line.gsub!(/(#{embed})([$A-Za-z0-9_?!])/, '\1 \2')
65
+ end
66
+ line
67
+ end
68
+ end
@@ -0,0 +1,30 @@
1
+ # Warning for not having parens in a method declaration with arguments
2
+ class Laser::ParensOnDeclarationWarning < Laser::FileWarning
3
+ type :style
4
+ severity 1
5
+ short_desc 'Missing parentheses in method declaration'
6
+ setting_accessor :method_name
7
+ desc do
8
+ "The method #{method_name} should have its arguments wrapped in parentheses."
9
+ end
10
+
11
+ def match?(body = self.body)
12
+ def_list = find_sexps(:def).select do |sym, name, args, body|
13
+ case args.type
14
+ when :params then args.children.any?
15
+ when :paren then !args[1].children.any?
16
+ end
17
+ end.map do |sym, name, args, body|
18
+ Laser::ParensOnDeclarationWarning.new(file, body, method_name: name[1])
19
+ end
20
+ sdef_list = find_sexps(:defs).select do |sym, target, op, name, args, body|
21
+ case args.type
22
+ when :params then args.children.any?
23
+ when :paren then !args[1].children.any?
24
+ end
25
+ end.map do |sym, target, op, name, args, body|
26
+ Laser::ParensOnDeclarationWarning.new(file, body, method_name: name[1])
27
+ end
28
+ def_list + sdef_list
29
+ end
30
+ end