ruby-lint 0.0.3 → 0.0.4

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 (347) hide show
  1. data.tar.gz.asc +14 -14
  2. data/.gitignore +1 -2
  3. data/.rubocop.yml +59 -0
  4. data/.travis.yml +3 -7
  5. data/.yardopts +2 -2
  6. data/Gemfile +4 -0
  7. data/MANIFEST +103 -67
  8. data/README.md +13 -31
  9. data/Rakefile +1 -6
  10. data/checksum/ruby-lint-0.0.3.gem.sha512 +1 -0
  11. data/debug/memory_usage.rb +14 -0
  12. data/debug/profile.rb +18 -0
  13. data/doc/architecture.md +14 -18
  14. data/doc/changelog.md +29 -0
  15. data/doc/code_analysis.md +12 -12
  16. data/doc/configuration.md +21 -50
  17. data/doc/graphviz/flow.dot +1 -1
  18. data/doc/images/flow.png +0 -0
  19. data/lib/ruby-lint.rb +33 -19
  20. data/lib/ruby-lint/analysis/argument_amount.rb +84 -0
  21. data/lib/ruby-lint/analysis/base.rb +132 -0
  22. data/lib/ruby-lint/analysis/confusing_variables.rb +26 -0
  23. data/lib/ruby-lint/analysis/pedantics.rb +36 -0
  24. data/lib/ruby-lint/analysis/shadowing_variables.rb +47 -0
  25. data/lib/ruby-lint/analysis/undefined_methods.rb +91 -0
  26. data/lib/ruby-lint/analysis/undefined_variables.rb +46 -0
  27. data/lib/ruby-lint/analysis/unused_variables.rb +49 -0
  28. data/lib/ruby-lint/ast/builder.rb +17 -0
  29. data/lib/ruby-lint/ast/node.rb +39 -0
  30. data/lib/ruby-lint/cli.rb +0 -19
  31. data/lib/ruby-lint/cli/analyze.rb +54 -28
  32. data/lib/ruby-lint/cli/ast.rb +21 -6
  33. data/lib/ruby-lint/cli/base.rb +0 -23
  34. data/lib/ruby-lint/configuration.rb +112 -42
  35. data/lib/ruby-lint/constant_loader.rb +10 -28
  36. data/lib/ruby-lint/default_names.rb +19 -0
  37. data/lib/ruby-lint/definition/constant_proxy.rb +56 -0
  38. data/lib/ruby-lint/definition/ruby_method.rb +21 -143
  39. data/lib/ruby-lint/definition/ruby_object.rb +142 -246
  40. data/lib/ruby-lint/definition_builder/base.rb +43 -0
  41. data/lib/ruby-lint/definition_builder/primitive.rb +39 -0
  42. data/lib/ruby-lint/definition_builder/ruby_array.rb +77 -0
  43. data/lib/ruby-lint/definition_builder/ruby_block.rb +34 -0
  44. data/lib/ruby-lint/definition_builder/ruby_class.rb +24 -0
  45. data/lib/ruby-lint/definition_builder/ruby_hash.rb +37 -0
  46. data/lib/ruby-lint/definition_builder/ruby_method.rb +84 -0
  47. data/lib/ruby-lint/definition_builder/ruby_module.rb +68 -0
  48. data/lib/ruby-lint/definition_generator.rb +41 -15
  49. data/lib/ruby-lint/definitions/core/arg0.rb +1 -1
  50. data/lib/ruby-lint/definitions/core/argf.rb +1 -1
  51. data/lib/ruby-lint/definitions/core/argument_error.rb +2 -2
  52. data/lib/ruby-lint/definitions/core/argv.rb +1 -1
  53. data/lib/ruby-lint/definitions/core/array.rb +6 -6
  54. data/lib/ruby-lint/definitions/core/autoload.rb +2 -2
  55. data/lib/ruby-lint/definitions/core/basic_object.rb +3 -3
  56. data/lib/ruby-lint/definitions/core/bignum.rb +2 -2
  57. data/lib/ruby-lint/definitions/core/binding.rb +2 -2
  58. data/lib/ruby-lint/definitions/core/class.rb +2 -2
  59. data/lib/ruby-lint/definitions/core/comparable.rb +1 -1
  60. data/lib/ruby-lint/definitions/core/complex.rb +4 -4
  61. data/lib/ruby-lint/definitions/core/condition_variable.rb +2 -2
  62. data/lib/ruby-lint/definitions/core/continuation.rb +2 -2
  63. data/lib/ruby-lint/definitions/core/data.rb +2 -2
  64. data/lib/ruby-lint/definitions/core/date.rb +34 -34
  65. data/lib/ruby-lint/definitions/core/date_time.rb +26 -26
  66. data/lib/ruby-lint/definitions/core/default_record_separator.rb +1 -1
  67. data/lib/ruby-lint/definitions/core/digest.rb +14 -14
  68. data/lib/ruby-lint/definitions/core/dir.rb +34 -34
  69. data/lib/ruby-lint/definitions/core/encoding.rb +237 -237
  70. data/lib/ruby-lint/definitions/core/encoding_error.rb +2 -2
  71. data/lib/ruby-lint/definitions/core/enumerable.rb +15 -15
  72. data/lib/ruby-lint/definitions/core/enumerator.rb +2 -2
  73. data/lib/ruby-lint/definitions/core/env.rb +1 -1
  74. data/lib/ruby-lint/definitions/core/eoferror.rb +2 -2
  75. data/lib/ruby-lint/definitions/core/erb.rb +22 -22
  76. data/lib/ruby-lint/definitions/core/errno.rb +525 -525
  77. data/lib/ruby-lint/definitions/core/etc.rb +6 -6
  78. data/lib/ruby-lint/definitions/core/exception.rb +2 -2
  79. data/lib/ruby-lint/definitions/core/false.rb +1 -1
  80. data/lib/ruby-lint/definitions/core/false_class.rb +2 -2
  81. data/lib/ruby-lint/definitions/core/fatal_error.rb +2 -2
  82. data/lib/ruby-lint/definitions/core/fiber.rb +2 -2
  83. data/lib/ruby-lint/definitions/core/fiber_error.rb +2 -2
  84. data/lib/ruby-lint/definitions/core/file.rb +68 -68
  85. data/lib/ruby-lint/definitions/core/file_list.rb +2 -2
  86. data/lib/ruby-lint/definitions/core/file_test.rb +1 -1
  87. data/lib/ruby-lint/definitions/core/file_utils.rb +16 -16
  88. data/lib/ruby-lint/definitions/core/fixnum.rb +4 -4
  89. data/lib/ruby-lint/definitions/core/float.rb +16 -16
  90. data/lib/ruby-lint/definitions/core/float_domain_error.rb +2 -2
  91. data/lib/ruby-lint/definitions/core/gc.rb +2 -2
  92. data/lib/ruby-lint/definitions/core/gem.rb +119 -119
  93. data/lib/ruby-lint/definitions/core/hash.rb +14 -14
  94. data/lib/ruby-lint/definitions/core/immediate_value.rb +1 -1
  95. data/lib/ruby-lint/definitions/core/index_error.rb +2 -2
  96. data/lib/ruby-lint/definitions/core/integer.rb +2 -2
  97. data/lib/ruby-lint/definitions/core/interrupt.rb +2 -2
  98. data/lib/ruby-lint/definitions/core/io.rb +38 -38
  99. data/lib/ruby-lint/definitions/core/ioerror.rb +2 -2
  100. data/lib/ruby-lint/definitions/core/kernel.rb +3 -3
  101. data/lib/ruby-lint/definitions/core/key_error.rb +2 -2
  102. data/lib/ruby-lint/definitions/core/load_error.rb +6 -6
  103. data/lib/ruby-lint/definitions/core/local_jump_error.rb +2 -2
  104. data/lib/ruby-lint/definitions/core/main.rb +1 -1
  105. data/lib/ruby-lint/definitions/core/marshal.rb +35 -35
  106. data/lib/ruby-lint/definitions/core/match_data.rb +2 -2
  107. data/lib/ruby-lint/definitions/core/math.rb +7 -7
  108. data/lib/ruby-lint/definitions/core/memory_segmention_error.rb +2 -2
  109. data/lib/ruby-lint/definitions/core/method.rb +2 -2
  110. data/lib/ruby-lint/definitions/core/module.rb +1 -1
  111. data/lib/ruby-lint/definitions/core/monitor.rb +4 -4
  112. data/lib/ruby-lint/definitions/core/monitor_mixin.rb +5 -5
  113. data/lib/ruby-lint/definitions/core/mutex.rb +2 -2
  114. data/lib/ruby-lint/definitions/core/name_error.rb +2 -2
  115. data/lib/ruby-lint/definitions/core/nil.rb +1 -1
  116. data/lib/ruby-lint/definitions/core/nil_class.rb +2 -2
  117. data/lib/ruby-lint/definitions/core/no_memory_error.rb +2 -2
  118. data/lib/ruby-lint/definitions/core/no_method_error.rb +2 -2
  119. data/lib/ruby-lint/definitions/core/not_implemented_error.rb +2 -2
  120. data/lib/ruby-lint/definitions/core/numeric.rb +2 -2
  121. data/lib/ruby-lint/definitions/core/object.rb +2 -2
  122. data/lib/ruby-lint/definitions/core/object_space.rb +1 -1
  123. data/lib/ruby-lint/definitions/core/open_struct.rb +3 -3
  124. data/lib/ruby-lint/definitions/core/option_parser.rb +83 -83
  125. data/lib/ruby-lint/definitions/core/precision.rb +1 -1
  126. data/lib/ruby-lint/definitions/core/primitive_failure.rb +2 -2
  127. data/lib/ruby-lint/definitions/core/proc.rb +2 -2
  128. data/lib/ruby-lint/definitions/core/process.rb +29 -29
  129. data/lib/ruby-lint/definitions/core/psych.rb +149 -149
  130. data/lib/ruby-lint/definitions/core/queue.rb +2 -2
  131. data/lib/ruby-lint/definitions/core/rake.rb +117 -117
  132. data/lib/ruby-lint/definitions/core/rake_file_utils.rb +1 -1
  133. data/lib/ruby-lint/definitions/core/rakeversion.rb +1 -1
  134. data/lib/ruby-lint/definitions/core/random.rb +2 -2
  135. data/lib/ruby-lint/definitions/core/range.rb +4 -4
  136. data/lib/ruby-lint/definitions/core/range_error.rb +2 -2
  137. data/lib/ruby-lint/definitions/core/rational.rb +2 -2
  138. data/lib/ruby-lint/definitions/core/rb_config.rb +3 -3
  139. data/lib/ruby-lint/definitions/core/regexp.rb +28 -28
  140. data/lib/ruby-lint/definitions/core/regexp_error.rb +2 -2
  141. data/lib/ruby-lint/definitions/core/rubinius.rb +1057 -1057
  142. data/lib/ruby-lint/definitions/core/ruby_copyright.rb +1 -1
  143. data/lib/ruby-lint/definitions/core/ruby_description.rb +1 -1
  144. data/lib/ruby-lint/definitions/core/ruby_engine.rb +1 -1
  145. data/lib/ruby-lint/definitions/core/ruby_lint.rb +9 -9
  146. data/lib/ruby-lint/definitions/core/ruby_patchlevel.rb +1 -1
  147. data/lib/ruby-lint/definitions/core/ruby_platform.rb +1 -1
  148. data/lib/ruby-lint/definitions/core/ruby_release_date.rb +1 -1
  149. data/lib/ruby-lint/definitions/core/ruby_version.rb +1 -1
  150. data/lib/ruby-lint/definitions/core/runtime_error.rb +2 -2
  151. data/lib/ruby-lint/definitions/core/scan_error.rb +2 -2
  152. data/lib/ruby-lint/definitions/core/script_error.rb +2 -2
  153. data/lib/ruby-lint/definitions/core/security_error.rb +2 -2
  154. data/lib/ruby-lint/definitions/core/shellwords.rb +1 -1
  155. data/lib/ruby-lint/definitions/core/signal.rb +3 -3
  156. data/lib/ruby-lint/definitions/core/signal_exception.rb +2 -2
  157. data/lib/ruby-lint/definitions/core/singleton.rb +2 -2
  158. data/lib/ruby-lint/definitions/core/sized_queue.rb +2 -2
  159. data/lib/ruby-lint/definitions/core/standard_error.rb +2 -2
  160. data/lib/ruby-lint/definitions/core/stderr.rb +1 -1
  161. data/lib/ruby-lint/definitions/core/stdin.rb +1 -1
  162. data/lib/ruby-lint/definitions/core/stdout.rb +1 -1
  163. data/lib/ruby-lint/definitions/core/stop_iteration.rb +2 -2
  164. data/lib/ruby-lint/definitions/core/string.rb +21 -21
  165. data/lib/ruby-lint/definitions/core/string_io.rb +7 -7
  166. data/lib/ruby-lint/definitions/core/string_scanner.rb +4 -4
  167. data/lib/ruby-lint/definitions/core/struct.rb +20 -20
  168. data/lib/ruby-lint/definitions/core/syck.rb +4 -4
  169. data/lib/ruby-lint/definitions/core/symbol.rb +2 -2
  170. data/lib/ruby-lint/definitions/core/syntax_error.rb +2 -2
  171. data/lib/ruby-lint/definitions/core/system_call_error.rb +2 -2
  172. data/lib/ruby-lint/definitions/core/system_exit.rb +2 -2
  173. data/lib/ruby-lint/definitions/core/system_stack_error.rb +2 -2
  174. data/lib/ruby-lint/definitions/core/thread.rb +6 -6
  175. data/lib/ruby-lint/definitions/core/thread_error.rb +2 -2
  176. data/lib/ruby-lint/definitions/core/thread_group.rb +2 -2
  177. data/lib/ruby-lint/definitions/core/time.rb +3 -3
  178. data/lib/ruby-lint/definitions/core/toplevel_binding.rb +1 -1
  179. data/lib/ruby-lint/definitions/core/true.rb +1 -1
  180. data/lib/ruby-lint/definitions/core/true_class.rb +2 -2
  181. data/lib/ruby-lint/definitions/core/type_error.rb +2 -2
  182. data/lib/ruby-lint/definitions/core/unbound_method.rb +2 -2
  183. data/lib/ruby-lint/definitions/core/unmarshalable.rb +1 -1
  184. data/lib/ruby-lint/definitions/core/unsupported_library_error.rb +2 -2
  185. data/lib/ruby-lint/definitions/core/weak_ref.rb +4 -4
  186. data/lib/ruby-lint/definitions/core/zero_division_error.rb +2 -2
  187. data/lib/ruby-lint/definitions/rails.rb +12 -0
  188. data/lib/ruby-lint/definitions/rails/abstract_controller.rb +335 -0
  189. data/lib/ruby-lint/definitions/rails/action_controller.rb +1244 -0
  190. data/lib/ruby-lint/definitions/rails/action_dispatch.rb +741 -0
  191. data/lib/ruby-lint/definitions/rails/action_mailer.rb +502 -0
  192. data/lib/ruby-lint/definitions/rails/action_pack.rb +16 -0
  193. data/lib/ruby-lint/definitions/rails/action_view.rb +898 -0
  194. data/lib/ruby-lint/definitions/rails/active_model.rb +437 -0
  195. data/lib/ruby-lint/definitions/rails/active_record.rb +2901 -0
  196. data/lib/ruby-lint/definitions/rails/active_support.rb +1963 -0
  197. data/lib/ruby-lint/definitions/rails/arel.rb +665 -0
  198. data/lib/ruby-lint/definitions/rails/rails.rb +452 -0
  199. data/lib/ruby-lint/definitions/rails/sprockets.rb +968 -0
  200. data/lib/ruby-lint/generated_constant.rb +33 -0
  201. data/lib/ruby-lint/helper/constant_paths.rb +30 -21
  202. data/lib/ruby-lint/inspector.rb +20 -2
  203. data/lib/ruby-lint/iterator.rb +11 -171
  204. data/lib/ruby-lint/nested_stack.rb +46 -0
  205. data/lib/ruby-lint/parser.rb +24 -806
  206. data/lib/ruby-lint/report.rb +2 -30
  207. data/lib/ruby-lint/report/entry.rb +2 -2
  208. data/lib/ruby-lint/runner.rb +81 -0
  209. data/lib/ruby-lint/template/definition.erb +12 -8
  210. data/lib/ruby-lint/variable_predicates.rb +16 -58
  211. data/lib/ruby-lint/version.rb +1 -1
  212. data/lib/ruby-lint/virtual_machine.rb +1044 -0
  213. data/ruby-lint.gemspec +17 -7
  214. data/spec/fixtures/complex/rails/basic_controller.rb +9 -0
  215. data/spec/fixtures/complex/rcap.rb +38 -0
  216. data/spec/fixtures/complex/slop.rb +680 -0
  217. data/spec/fixtures/config.yml +8 -0
  218. data/spec/fixtures/invalid.rb +3 -0
  219. data/spec/fixtures/invalid_2.rb +3 -0
  220. data/spec/fixtures/syntax_error.rb +1 -0
  221. data/spec/fixtures/valid.rb +3 -0
  222. data/spec/helper.rb +6 -0
  223. data/spec/ruby-lint/{analyze → analysis}/argument_amount.rb +7 -7
  224. data/spec/ruby-lint/analysis/confusing_variables.rb +46 -0
  225. data/spec/ruby-lint/analysis/pedantics.rb +43 -0
  226. data/spec/ruby-lint/{analyze → analysis}/shadowing_variables.rb +5 -5
  227. data/spec/ruby-lint/{analyze → analysis}/undefined_methods.rb +18 -18
  228. data/spec/ruby-lint/{analyze → analysis}/undefined_variables.rb +19 -25
  229. data/spec/ruby-lint/{analyze → analysis}/unused_variables.rb +29 -16
  230. data/spec/ruby-lint/ast/node.rb +33 -0
  231. data/spec/ruby-lint/cli/analyze.rb +31 -0
  232. data/spec/ruby-lint/cli/ast.rb +23 -0
  233. data/spec/ruby-lint/configuration.rb +45 -6
  234. data/spec/ruby-lint/definition/constant_proxy.rb +31 -0
  235. data/spec/ruby-lint/definition/dsl.rb +13 -20
  236. data/spec/ruby-lint/definition/ruby_method.rb +65 -148
  237. data/spec/ruby-lint/definition/ruby_object.rb +60 -96
  238. data/spec/ruby-lint/definition_builder/primitive.rb +62 -0
  239. data/spec/ruby-lint/definition_builder/ruby_class.rb +108 -0
  240. data/spec/ruby-lint/definition_builder/ruby_method.rb +53 -0
  241. data/spec/ruby-lint/definition_builder/ruby_module.rb +50 -0
  242. data/spec/ruby-lint/iterator.rb +40 -16
  243. data/spec/ruby-lint/nested_stack.rb +23 -0
  244. data/spec/ruby-lint/parser.rb +14 -0
  245. data/spec/ruby-lint/report.rb +0 -10
  246. data/spec/ruby-lint/report/entry.rb +8 -4
  247. data/spec/ruby-lint/runner.rb +32 -0
  248. data/spec/ruby-lint/virtual_machine/assignments/arrays.rb +87 -0
  249. data/spec/ruby-lint/virtual_machine/assignments/hashes.rb +52 -0
  250. data/spec/ruby-lint/virtual_machine/assignments/optional.rb +41 -0
  251. data/spec/ruby-lint/{definitions_builder → virtual_machine}/assignments/return_values.rb +11 -11
  252. data/spec/ruby-lint/virtual_machine/assignments/variables.rb +85 -0
  253. data/spec/ruby-lint/virtual_machine/associate_nodes.rb +17 -0
  254. data/spec/ruby-lint/virtual_machine/autoloading.rb +31 -0
  255. data/spec/ruby-lint/virtual_machine/blocks.rb +64 -0
  256. data/spec/ruby-lint/virtual_machine/classes/class_methods.rb +21 -0
  257. data/spec/ruby-lint/virtual_machine/classes/extending.rb +104 -0
  258. data/spec/ruby-lint/virtual_machine/classes/redefining.rb +24 -0
  259. data/spec/ruby-lint/virtual_machine/classes/sclass.rb +94 -0
  260. data/spec/ruby-lint/virtual_machine/classes/scoping.rb +60 -0
  261. data/spec/ruby-lint/virtual_machine/complex/rails.rb +18 -0
  262. data/spec/ruby-lint/virtual_machine/complex/rcap.rb +15 -0
  263. data/spec/ruby-lint/virtual_machine/complex/slop.rb +16 -0
  264. data/spec/ruby-lint/{definitions_builder → virtual_machine}/for.rb +2 -2
  265. data/spec/ruby-lint/virtual_machine/freeze.rb +13 -0
  266. data/spec/ruby-lint/virtual_machine/interpolation.rb +12 -0
  267. data/spec/ruby-lint/virtual_machine/methods/defining.rb +40 -0
  268. data/spec/ruby-lint/virtual_machine/methods/exporting.rb +19 -0
  269. data/spec/ruby-lint/virtual_machine/methods/parameters.rb +77 -0
  270. data/spec/ruby-lint/virtual_machine/methods/patching.rb +26 -0
  271. data/spec/ruby-lint/virtual_machine/methods/scoping.rb +63 -0
  272. data/spec/ruby-lint/virtual_machine/methods/visibility.rb +64 -0
  273. data/spec/ruby-lint/{definitions_builder → virtual_machine}/modules.rb +16 -16
  274. data/spec/ruby-lint/virtual_machine/reference_amount.rb +33 -0
  275. data/spec/ruby-lint/virtual_machine/unused.rb +17 -0
  276. data/spec/support/bacon.rb +13 -13
  277. data/spec/support/building.rb +23 -16
  278. data/spec/support/coveralls.rb +5 -0
  279. data/spec/support/fixtures.rb +20 -0
  280. data/spec/support/parsing.rb +3 -5
  281. data/spec/support/simplecov.rb +5 -3
  282. data/task/build.rake +1 -1
  283. data/task/cop.rake +11 -0
  284. data/task/generate.rake +40 -2
  285. data/task/profile.rake +27 -0
  286. data/task/todo.rake +6 -0
  287. data/task/travis.rake +7 -0
  288. metadata +160 -75
  289. metadata.gz.asc +14 -14
  290. data/doc/build/.gitkeep +0 -0
  291. data/lib/ruby-lint/analyze/argument_amount.rb +0 -73
  292. data/lib/ruby-lint/analyze/shadowing_variables.rb +0 -32
  293. data/lib/ruby-lint/analyze/undefined_methods.rb +0 -68
  294. data/lib/ruby-lint/analyze/undefined_variables.rb +0 -72
  295. data/lib/ruby-lint/analyze/unused_variables.rb +0 -48
  296. data/lib/ruby-lint/base.rb +0 -85
  297. data/lib/ruby-lint/definitions_builder.rb +0 -692
  298. data/lib/ruby-lint/helper/conversion.rb +0 -33
  299. data/lib/ruby-lint/helper/current_scope.rb +0 -98
  300. data/lib/ruby-lint/helper/methods.rb +0 -91
  301. data/lib/ruby-lint/node.rb +0 -107
  302. data/lib/ruby-lint/parser_error.rb +0 -30
  303. data/spec/ruby-lint/constant_loader.rb +0 -32
  304. data/spec/ruby-lint/definition/method_calls.rb +0 -26
  305. data/spec/ruby-lint/definitions_builder/assignments/arrays.rb +0 -71
  306. data/spec/ruby-lint/definitions_builder/assignments/hashes.rb +0 -65
  307. data/spec/ruby-lint/definitions_builder/assignments/objects.rb +0 -23
  308. data/spec/ruby-lint/definitions_builder/assignments/optional.rb +0 -22
  309. data/spec/ruby-lint/definitions_builder/assignments/variables.rb +0 -71
  310. data/spec/ruby-lint/definitions_builder/associate_nodes.rb +0 -17
  311. data/spec/ruby-lint/definitions_builder/blocks.rb +0 -40
  312. data/spec/ruby-lint/definitions_builder/classes.rb +0 -230
  313. data/spec/ruby-lint/definitions_builder/methods.rb +0 -147
  314. data/spec/ruby-lint/definitions_builder/reference_amount.rb +0 -31
  315. data/spec/ruby-lint/definitions_builder/unused.rb +0 -15
  316. data/spec/ruby-lint/node.rb +0 -38
  317. data/spec/ruby-lint/parser/assignments.rb +0 -225
  318. data/spec/ruby-lint/parser/classes.rb +0 -110
  319. data/spec/ruby-lint/parser/errors.rb +0 -12
  320. data/spec/ruby-lint/parser/metadata.rb +0 -17
  321. data/spec/ruby-lint/parser/method_definitions.rb +0 -111
  322. data/spec/ruby-lint/parser/methods.rb +0 -217
  323. data/spec/ruby-lint/parser/modules.rb +0 -70
  324. data/spec/ruby-lint/parser/operators.rb +0 -40
  325. data/spec/ruby-lint/parser/statements/begin.rb +0 -55
  326. data/spec/ruby-lint/parser/statements/case.rb +0 -34
  327. data/spec/ruby-lint/parser/statements/defined.rb +0 -11
  328. data/spec/ruby-lint/parser/statements/for.rb +0 -34
  329. data/spec/ruby-lint/parser/statements/if.rb +0 -46
  330. data/spec/ruby-lint/parser/statements/return.rb +0 -14
  331. data/spec/ruby-lint/parser/statements/super.rb +0 -49
  332. data/spec/ruby-lint/parser/statements/unless.rb +0 -42
  333. data/spec/ruby-lint/parser/statements/until.rb +0 -25
  334. data/spec/ruby-lint/parser/statements/while.rb +0 -25
  335. data/spec/ruby-lint/parser/statements/yield.rb +0 -18
  336. data/spec/ruby-lint/parser/types/arrays.rb +0 -47
  337. data/spec/ruby-lint/parser/types/booleans.rb +0 -11
  338. data/spec/ruby-lint/parser/types/constants.rb +0 -32
  339. data/spec/ruby-lint/parser/types/hashes.rb +0 -55
  340. data/spec/ruby-lint/parser/types/nil.rb +0 -7
  341. data/spec/ruby-lint/parser/types/numbers.rb +0 -11
  342. data/spec/ruby-lint/parser/types/procs.rb +0 -11
  343. data/spec/ruby-lint/parser/types/ranges.rb +0 -11
  344. data/spec/ruby-lint/parser/types/regexp.rb +0 -27
  345. data/spec/ruby-lint/parser/types/strings.rb +0 -44
  346. data/spec/ruby-lint/parser/types/symbols.rb +0 -15
  347. data/task/stdlib.rake +0 -23
@@ -0,0 +1,33 @@
1
+ module RubyLint
2
+ ##
3
+ # {RubyLint::GeneratedConstant} contains information about a constant (and
4
+ # its data) that was pre-generated using {RubyLint::DefinitionGenerator}.
5
+ #
6
+ # @!attribute [r] methods
7
+ # @return [Hash]
8
+ #
9
+ # @!attribute [r] name
10
+ # @return [String]
11
+ #
12
+ # @!attribute [r] constant
13
+ # @return [Class]
14
+ #
15
+ # @!attribute [r] superclass
16
+ # @return [String]
17
+ #
18
+ class GeneratedConstant
19
+ attr_reader :methods, :name, :constant, :superclass
20
+
21
+ ##
22
+ # @param [Hash] attributes
23
+ #
24
+ def initialize(attributes = {})
25
+ attributes.each do |key, value|
26
+ instance_variable_set("@#{key}", value)
27
+ end
28
+
29
+ @methods ||= []
30
+ @superclass ||= 'Object'
31
+ end
32
+ end # GeneratedConstant
33
+ end # RubyLint
@@ -6,35 +6,44 @@ module RubyLint
6
6
  #
7
7
  module ConstantPaths
8
8
  ##
9
- # Iterates over each segment of the constant path and yields the supplied
10
- # block.
9
+ # Looks up a definition for a given constant path. If no constant could
10
+ # be found `nil` is returned.
11
11
  #
12
- # @example
13
- # path = s(:constant_path, s(:constant, 'A'), s(:constant, 'B')
12
+ # The first constant segment in the path can inherit constants from the
13
+ # outer scope, any following constants will be limited to the scope of
14
+ # the constant itself.
14
15
  #
15
- # iterate_constant_path(path) do |name, segment, definition|
16
- # puts name
17
- # end
16
+ # @param [RubyLint::AST::Node] node
17
+ # @return [RubyLint::Definition::RubyObject|NilClass]
18
18
  #
19
- # @param [RubyLint::Node] node The constant path to iterate over.
19
+ def resolve_constant_path(node)
20
+ current = definitions
21
+
22
+ constant_segments(node).each_with_index do |segment, index|
23
+ found = current.lookup(:const, segment, index == 0)
24
+
25
+ found ? current = found : return
26
+ end
27
+
28
+ return current
29
+ end
30
+
31
+ ##
32
+ # Returns an Array containing the segments of a constant path.
20
33
  #
21
- # @yieldparam [String] name The name of the current segment.
22
- # @yieldparam [RubyLint::Node] node The raw AST node of the current
23
- # segment.
24
- # @yieldparam [RubyLint::Definition::RubyObject] definition The
25
- # definition object of the current segment.
34
+ # @param [RubyLint::AST::Node] node
35
+ # @return [Array<String>]
26
36
  #
27
- def iterate_constant_path(node)
28
- definitions = current_scope
37
+ def constant_segments(node)
38
+ segments = []
29
39
 
30
- node.children.each do |segment|
31
- name = segment.children[0]
32
- definition = definitions.lookup(:constant, name)
40
+ if node.children[0]
41
+ segments.concat(constant_segments(node.children[0]))
42
+ end
33
43
 
34
- yield name, segment, definition
44
+ segments << node.children[1].to_s
35
45
 
36
- definition ? definitions = definition : break
37
- end
46
+ return segments
38
47
  end
39
48
  end # ConstantPaths
40
49
  end # Helper
@@ -52,7 +52,16 @@ module RubyLint
52
52
  source.constants.each do |name|
53
53
  next unless source.const_defined?(name)
54
54
 
55
- constant = source.const_get(name)
55
+ # FIXME: When using autoload/Rails in some cases this will trigger a
56
+ # load error. I have no idea why.
57
+ begin
58
+ constant = source.const_get(name)
59
+ rescue LoadError => error
60
+ warn error.message
61
+
62
+ next
63
+ end
64
+
56
65
  name = name.to_s
57
66
  full_name = include_source ? "#{source_name}::#{name}" : name
58
67
 
@@ -105,6 +114,15 @@ module RubyLint
105
114
  return methods.sort_by(&:name)
106
115
  end
107
116
 
117
+ ##
118
+ # Returns the superclass of the current constant or `nil` if there is none.
119
+ #
120
+ # @return [Mixed]
121
+ #
122
+ def inspect_superclass
123
+ return constant.respond_to?(:superclass) ? constant.superclass : nil
124
+ end
125
+
108
126
  ##
109
127
  # Formats the list of methods in a human readable format.
110
128
  #
@@ -147,7 +165,7 @@ module RubyLint
147
165
  # @return [TrueClass|FalseClass]
148
166
  #
149
167
  def process_child_constants?(source, constant)
150
- return constant.respond_to?(:constants) \
168
+ return constant.respond_to?(:consts) \
151
169
  && constant != source \
152
170
  && !constant.constants.empty?
153
171
  end
@@ -16,17 +16,17 @@ module RubyLint
16
16
  #
17
17
  # These event names are used to call the corresponding callback methods if
18
18
  # they exist. Each callback method takes a single argument: the node (an
19
- # instance of {RubyLint::Node}) that belongs to the event.
19
+ # instance of {RubyLint::AST::Node}) that belongs to the event.
20
20
  #
21
21
  # Creating iterator classes is done by extending this particular class and
22
22
  # adding the needed methods to it:
23
23
  #
24
24
  # class MyIterator < RubyLint::Iterator
25
- # def on_integer(node)
25
+ # def on_int(node)
26
26
  # puts node.children[0]
27
27
  # end
28
28
  #
29
- # def after_integer(node)
29
+ # def after_int(node)
30
30
  # puts '---'
31
31
  # end
32
32
  # end
@@ -35,43 +35,17 @@ module RubyLint
35
35
  # integers it processes. After processing an integer it will display three
36
36
  # dashes.
37
37
  #
38
- # Each instance of a class that subclasses {RubyLint::Iterator} also has
39
- # access to the instance variable `@options`. This instance variable is used
40
- # to store certain information, such as the list of definitions for a block
41
- # of Ruby code. The following two keys are set by default:
42
- #
43
- # * `:definitions`: a set of Ruby definitions such as classes and methods.
44
- # * `:report`: an instance of {RubyLint::Report} that can be used for adding
45
- # information about the analyzed code.
46
- # * `:node_definitions`: a Hash that associates {RubyLint::Node} instances
47
- # with the corresponding scope.
48
- #
49
- # To make it easier to add data to a report sub classes can use the following
50
- # three methods:
51
- #
52
- # * error
53
- # * info
54
- # * warning
55
- #
56
- # These methods take away some of the boilerplate that would otherwise be
57
- # required to check for a report and add data to it if it's set.
58
- #
59
38
  class Iterator
60
- ##
61
- # Hash containing the options that were set for the iterator.
62
- #
63
- # @return [Hash]
64
- #
65
- attr_reader :options
66
-
67
39
  ##
68
40
  # @param [Hash] options Hash containing custom options to set for the
69
41
  # iterator.
70
42
  #
71
43
  def initialize(options = {})
72
- @options = default_options.merge(options)
73
- @definitions = []
74
- @call_types = []
44
+ options.each do |key, value|
45
+ instance_variable_set("@#{key}", value)
46
+ end
47
+
48
+ after_initialize if respond_to?(:after_initialize)
75
49
  end
76
50
 
77
51
  ##
@@ -81,18 +55,14 @@ module RubyLint
81
55
  # iterate over.
82
56
  #
83
57
  def iterate(node)
84
- return unless node.is_a?(Node)
58
+ return unless node.is_a?(AST::Node)
85
59
 
86
60
  before, after = callback_names(node)
87
61
 
88
62
  execute_callback(before, node)
89
63
 
90
64
  node.children.each do |child|
91
- if child.is_a?(Array)
92
- child.each { |c| iterate(c) }
93
- else
94
- iterate(child)
95
- end
65
+ iterate(child) if child.is_a?(AST::Node)
96
66
  end
97
67
 
98
68
  execute_callback(after, node)
@@ -100,107 +70,6 @@ module RubyLint
100
70
 
101
71
  protected
102
72
 
103
- ##
104
- # Adds an error message to the report.
105
- #
106
- # @param [String] message The message to add.
107
- # @param [RubyLint::Node] node The node for which to add the message.
108
- #
109
- def error(message, node)
110
- add_message(:error, message, node)
111
- end
112
-
113
- ##
114
- # Adds a warning message to the report.
115
- #
116
- # @see RubyLint::Callback#error
117
- #
118
- def warning(message, node)
119
- add_message(:warning, message, node)
120
- end
121
-
122
- ##
123
- # Adds a regular informational message to the report.
124
- #
125
- # @see RubyLint::Callback#error
126
- #
127
- def info(message, node)
128
- add_message(:info, message, node)
129
- end
130
-
131
- ##
132
- # Adds a message of the given level.
133
- #
134
- # @param [Symbol] level
135
- # @param [String] message
136
- # @param [String] node
137
- #
138
- def add_message(level, message, node)
139
- if has_report?
140
- @options[:report].add(
141
- level,
142
- message,
143
- node.line,
144
- node.column,
145
- node.file
146
- )
147
- end
148
- end
149
-
150
- ##
151
- # Returns `true` if the current iterator has a report instance set.
152
- #
153
- # @return [TrueClass|FalseClass]
154
- #
155
- def has_report?
156
- return @options[:report].is_a?(Report)
157
- end
158
-
159
- ##
160
- # Returns a definition list to use for the last segment in the constant
161
- # path. If one of the segments is invalid `nil` is returned instead.
162
- #
163
- # @param [Array] path An array of nodes or definitions that make up the
164
- # constant path.
165
- # @return [RubyLint::Definition::RubyObject|NilClass]
166
- #
167
- def resolve_definitions(path)
168
- current = definitions
169
-
170
- path.each do |segment|
171
- if segment.is_a?(Definition::RubyObject)
172
- name = segment.name
173
- else
174
- name = segment.children[0]
175
- end
176
-
177
- found = current.lookup(segment.type, name)
178
- found ? current = found : return
179
- end
180
-
181
- return current
182
- end
183
-
184
- ##
185
- # Returns the call type to use for method calls.
186
- #
187
- # @return [Symbol]
188
- #
189
- def call_type
190
- return @call_types.empty? ? :instance_method : @call_types[-1]
191
- end
192
-
193
- ##
194
- # Returns the current definition list to use.
195
- #
196
- # @return [RubyLint::Definition::RubyObject]
197
- #
198
- def definitions
199
- return @definitions.empty? ? @options[:definitions] : @definitions[-1]
200
- end
201
-
202
- protected
203
-
204
73
  ##
205
74
  # Executes the specified callback method if it exists.
206
75
  #
@@ -218,36 +87,7 @@ module RubyLint
218
87
  # @return [Array]
219
88
  #
220
89
  def callback_names(node)
221
- return [:"on_#{node.type}", :"after_#{node.type}"]
222
- end
223
-
224
- ##
225
- # Associates a definitions object with a node of the AST.
226
- #
227
- # @param [RubyLint::Node] node
228
- # @param [RubyLint::Definition::RubyObject] definitions
229
- #
230
- def associate_node_definition(node, definitions)
231
- @options[:node_definitions][node] = definitions
232
- end
233
-
234
- ##
235
- # Retrieves the definitions list associated to an AST node.
236
- #
237
- # @param [RubyLint::Node] node
238
- # @return [RubyLint::Definition::RubyObject|NilClass]
239
- #
240
- def associated_definition(node)
241
- return @options[:node_definitions][node]
242
- end
243
-
244
- ##
245
- # Returns a Hash containing the default configuration options.
246
- #
247
- # @return [Hash]
248
- #
249
- def default_options
250
- return {:node_definitions => {}}
90
+ return ["on_#{node.type}", "after_#{node.type}"]
251
91
  end
252
92
  end # Iterator
253
93
  end # RubyLint
@@ -0,0 +1,46 @@
1
+ module RubyLint
2
+ ##
3
+ # {RubyLint::NestedStack} is a basic implementation of a nested stack. It's
4
+ # primarily used by {RubyLint::VirtualMachine} for storing variables and
5
+ # values during assignments.
6
+ #
7
+ class NestedStack
8
+ def initialize
9
+ @values = []
10
+ end
11
+
12
+ ##
13
+ # Adds a new stack to push values to.
14
+ #
15
+ def add_stack
16
+ @values << []
17
+ end
18
+
19
+ ##
20
+ # Returns `true` if the stack is empty.
21
+ #
22
+ # @return [TrueClass|FalseClass]
23
+ #
24
+ def empty?
25
+ return @values.empty?
26
+ end
27
+
28
+ ##
29
+ # Pushes a value to the current (= last) stack.
30
+ #
31
+ # @param [Mixed] value
32
+ #
33
+ def push(value)
34
+ @values.last << value
35
+ end
36
+
37
+ ##
38
+ # Pops the last stack from the collection and returns it.
39
+ #
40
+ # @return [Array]
41
+ #
42
+ def pop
43
+ return @values.pop
44
+ end
45
+ end # NestedStack
46
+ end # RubyLint
@@ -1,826 +1,44 @@
1
1
  module RubyLint
2
2
  ##
3
- # {RubyLint::Parser} parses Ruby code and returns a clean and usable AST
4
- # instead of the rather raw AST returned by Ripper itself. Each node in the
5
- # AST is an instance of {RubyLint::Node}.
3
+ # {RubyLint::Parser} provides a small wrapper around the Parser Gem and
4
+ # allows for the use of a custom AST builder.
6
5
  #
7
- # ## Example
6
+ # @!attribute [r] internal_parser
7
+ # @return [Parser::Parser]
8
8
  #
9
- # RubyLint::Parser.new('[10, 20]').parse
10
- # # => (root (array (integer "10") (integer "20")))
11
- #
12
- class Parser < Ripper::SexpBuilderPP
13
- ##
14
- # Hash containing various Ripper types and the RubyLint types to use
15
- # instead.
16
- #
17
- # @return [Hash]
18
- #
19
- TYPE_MAPPING = {
20
- :ident => :identifier,
21
- :gvar => :global_variable,
22
- :ivar => :instance_variable,
23
- :cvar => :class_variable,
24
- :const => :constant,
25
- :int => :integer,
26
- :float => :float,
27
- :tstring_content => :string,
28
- :label => :symbol,
29
- :kw => :keyword
30
- }
31
-
32
- ##
33
- # Array containing all the event names of which the methods should simply
34
- # returned the passed argument.
35
- #
36
- # @return [Array]
37
- #
38
- RETURN_FIRST_ARG_EVENTS = [
39
- :arg_paren,
40
- :assoclist_from_args,
41
- :begin,
42
- :block_var,
43
- :blockarg,
44
- :const_ref,
45
- :mlhs_paren,
46
- :mrhs_new_from_args,
47
- :rest_param,
48
- :symbol_literal,
49
- :top_const_ref,
50
- :var_field,
51
- :paren
52
- ]
53
-
54
- ##
55
- # Array of event names that should return an instance of
56
- # {RubyLint::Token::MethodToken}.
57
- #
58
- # @return [Array]
59
- #
60
- RETURN_METHOD_EVENTS = [:fcall, :vcall]
61
-
62
- ##
63
- # List of modified statements, used to dynamically define the callback
64
- # methods.
65
- #
66
- # @return [Hash]
67
- #
68
- MOD_STATEMENT_EVENTS = {
69
- :while_mod => :while,
70
- :if_mod => :if,
71
- :unless_mod => :unless,
72
- :until_mod => :until
73
- }
74
-
75
- ##
76
- # Collection of Ripper events of which the callbacks all share similar
77
- # code. The corresponding methods are defined on the fly.
78
- #
79
- # @return [Hash]
80
- #
81
- BASIC_EVENTS = {
82
- :bodystmt => :body,
83
- :class => :class,
84
- :module => :module,
85
- :binary => :binary,
86
- :unary => :unary,
87
- :return => :return,
88
- :else => :else,
89
- :unless => :unless,
90
- :until => :until,
91
- :while => :while,
92
- :dot2 => :dot2,
93
- :dot3 => :dot3,
94
- :assoc_new => :key_value,
95
- :hash => :hash,
96
- :aref => :aref,
97
- :string_concat => :string_concat,
98
- :string_embexpr => :embed,
99
- :begin => :begin,
100
- :ensure => :ensure,
101
- :defined => :defined,
102
- :super => :super,
103
- :yield0 => :yield,
104
- :yield => :yield,
105
- :sclass => :sclass
106
- }
107
-
108
- ##
109
- # Hash containing various Ripper event names and the methods these events
110
- # should execute.
111
- #
112
- # @return [Hash]
113
- #
114
- EVENT_ALIASES = {
115
- :dyna_symbol => :on_symbol,
116
- :aref_field => :on_aref,
117
- :bare_assoc_hash => :on_hash,
118
- :do_block => :on_brace_block
119
- }
120
-
121
- ##
122
- # Array of events (the ones used by ruby-lint) of which the child nodes
123
- # should be stripped of `nil` values.
124
- #
125
- # @return [Array]
126
- #
127
- COMPACT_EVENT_ARGS = [:body, :unless]
128
-
129
- ##
130
- # Array of events of which the first callback parameter should be used for
131
- # the child nodes of a callback.
132
- #
133
- # @return [Array]
134
- #
135
- UNPACK_EVENT_ARGS = [:else, :hash, :embed, :ensure]
136
-
137
- ##
138
- # Hash containing parameter indexes and the node types.
139
- #
140
- # @return [Hash]
141
- #
142
- PARAMETER_INDEX_TYPES = {
143
- 0 => :argument,
144
- 1 => :optional_argument,
145
- 2 => :rest_argument,
146
- 3 => :more_argument,
147
- 4 => :block_argument
148
- }
149
-
150
- SCANNER_EVENTS.each do |type|
151
- define_method("on_#{type}") do |value|
152
- return Node.new(readable_type_name(type), [value], metadata)
153
- end
154
- end
155
-
156
- RETURN_FIRST_ARG_EVENTS.each do |event|
157
- define_method("on_#{event}") { |*args| return args[0] }
158
- end
159
-
160
- RETURN_METHOD_EVENTS.each do |event|
161
- define_method("on_#{event}") do |node|
162
- return Node.new(
163
- :method,
164
- [node.children[0], on_params, nil, nil], metadata(node)
165
- )
166
- end
167
- end
168
-
169
- BASIC_EVENTS.each do |original, new|
170
- define_method("on_#{original}") do |*args|
171
- if COMPACT_EVENT_ARGS.include?(new)
172
- args = args.map { |arg| arg.compact rescue arg }.compact
173
- end
174
-
175
- args = args[0] if UNPACK_EVENT_ARGS.include?(new)
176
-
177
- return Node.new(new, args, metadata)
178
- end
179
- end
180
-
181
- MOD_STATEMENT_EVENTS.each do |mod, normal|
182
- define_method("on_#{mod}") do |statement, value|
183
- value = [value] unless value.is_a?(Array)
184
-
185
- return send("on_#{normal}", statement, value)
186
- end
187
- end
188
-
189
- EVENT_ALIASES.each do |event, method|
190
- define_method("on_#{event}") do |*args|
191
- return send(method, *args)
192
- end
193
- end
194
-
195
- ##
196
- # @see Ripper::SexpBuilderPP#initialize
197
- #
198
- def initialize(code, file = '(ruby-lint)', line = 1)
199
- super
200
-
201
- @file = file
202
- end
203
-
204
- ##
205
- # @return [NilClass]
206
- #
207
- def on_void_stmt
208
- return nil
209
- end
210
-
211
- ##
212
- # Called at the start of a Ruby program.
213
- #
214
- # @param [Array] nodes The various nodes of the program.
215
- # @return [RubyLint::Node]
216
- #
217
- def on_program(nodes)
218
- nodes = [nodes] unless nodes.is_a?(Array)
219
-
220
- return Node.new(:root, nodes, :line => 1, :column => 0, :file => @file)
221
- end
222
-
223
- ##
224
- # @param [String] message The error message.
225
- # @raise [RubyLint::ParserError]
226
- #
227
- def on_parse_error(message)
228
- raise ParserError.new(message, lineno, column, @file)
229
- end
230
-
231
- ##
232
- # Called when a symbol is found.
233
- #
234
- # @param [RubyLint::Node|Array] node The value of the symbol. This
235
- # parameter is set to an Array when parsing code such as `:"hello"`.
236
- # @return [RubyLint::Node]
237
- #
238
- def on_symbol(node)
239
- node = node[0] if node.is_a?(Array)
240
-
241
- return Node.new(:symbol, node.children, metadata(node))
242
- end
243
-
244
- ##
245
- # @param [Array] content The contents of the string.
246
- # @return [RubyLint::Node]
247
- #
248
- def on_string_literal(content)
249
- return content[1] || Node.new(:string, [], metadata)
250
- end
251
-
252
- ##
253
- # Called when a piece of code is embedded using `#expressions` (e.g.
254
- # `#$foo`).
255
- #
256
- # @param [RubyLint::Node] node
257
- # @return [RubyLint::Node]
258
- #
259
- def on_string_dvar(node)
260
- return Node.new(:embed, [node], metadata(node))
261
- end
262
-
263
- ##
264
- # @param [Array] values The values of the array.
265
- # @return [RubyLint::Node]
266
- #
267
- def on_array(values)
268
- values ||= []
269
- values = [values] unless values.is_a?(Array)
270
- children = values.flatten
271
-
272
- return Node.new(:array, children, metadata)
273
- end
274
-
275
- ##
276
- # @param [Array] regexp Array containing the regular expression's body.
277
- # @return [RubyLint::Node] mode The mode for the regular expression.
278
- # @return [RubyLint::Node]
279
- #
280
- def on_regexp_literal(regexp, mode)
281
- return Node.new(:regexp, [regexp[0], mode], metadata)
282
- end
283
-
284
- ##
285
- # @param [RubyLint::Node] params The parameters of the lamda.
286
- # @param [Array] body The body of the lambda.
287
- # @return [RubyLint::Node]
288
- #
289
- def on_lambda(params, body)
290
- return on_brace_block(params, body).updated(:lambda)
291
- end
292
-
293
- ##
294
- # @param [RubyLint::Node] params The parameters of the block.
295
- # @param [Array] body The body of the block.
296
- # @return [RubyLint::Node]
297
- #
298
- def on_brace_block(params, body)
299
- return Node.new(:block, [params || on_params, on_bodystmt(body)], metadata)
300
- end
301
-
302
- ##
303
- # @param [RubyLint::Node] left
304
- # @param [RubyLint::Node] right
305
- # @return [RubyLint::Node]
306
- #
307
- def on_const_path_ref(left, right)
308
- left = left.type == :constant_path ? left.children : left
309
-
310
- return Node.new(:constant_path, [left, right].flatten, metadata)
311
- end
312
-
313
- ##
314
- # @see #on_constant_path_ref
315
- #
316
- def on_const_path_field(left, right)
317
- return on_const_path_ref(left, right)
318
- end
319
-
320
- ##
321
- # Called when a variable is assigned to a start (`*`).
322
- #
323
- # @param [Array|RubyLint::Node] left The variable(s) to the left of the
324
- # star.
325
- # @param [Array|RubyLint::Node] right The variable(s) to the right of the
326
- # star.
327
- # @return [RubyLint::Node]
328
- #
329
- def on_mlhs_add_star(left, right)
330
- if right
331
- left << right.updated(nil, [*right.children, true])
332
- # Add a placeholder for the expander token.
333
- else
334
- left << nil
335
- end
336
-
337
- return left
338
- end
339
-
340
- ##
341
- # @param [RubyLint::Node] variable The data to assign the value to.
342
- # @param [RubyLint::Node] value The value to assign.
343
- # @return [RubyLint::Node]
344
- #
345
- def on_assign(variable, value)
346
- variable = variable.updated(:local_variable) if variable.identifier?
347
-
348
- # When assigning values to array indexes or hash keys the value should
349
- # always be an array. This makes it easier to assign values without
350
- # having to check the type of data we're dealing with.
351
- if variable.type == :aref and !value.is_a?(Array)
352
- value = [value]
353
- end
354
-
355
- return Node.new(:assign, [variable, value], metadata(variable))
356
- end
357
-
358
- ##
359
- # Called when a conditional assignment is found.
360
- #
361
- # @see RubyLint::Parser#on_assign
362
- #
363
- def on_opassign(variable, operator, value)
364
- return on_assign(variable, value).updated(:op_assign)
365
- end
366
-
367
- ##
368
- # @param [Array] variables The variables that are being assigned.
369
- # @param [Array|RubyLint::Node] values The values to assign.
370
- # @return [RubyLint::Node]
371
- #
372
- def on_massign(variables, values)
373
- nodes = []
374
- variables = variables.flatten
375
- before = 0
376
-
377
- if values.is_a?(Node) and values.type == :array
378
- values = values.children.dup
379
- elsif !values.is_a?(Array)
380
- values = [values]
381
- end
382
-
383
- var_length = variables.length
384
- val_length = values.length
385
-
386
- variables.each_with_index do |variable, index|
387
- if !variable
388
- values.shift
389
- next
390
- end
391
-
392
- variable = variable.updated(:local_variable) if variable.identifier?
393
-
394
- # Extract the values for the expander variable based on the amount of
395
- # variables, values and the amount of variables that were assigned
396
- # before the expander.
397
- if variable.children[1]
398
- slice_length = val_length - (var_length - 1)
399
-
400
- value = Node.new(
401
- :array,
402
- values.slice!(index - before, slice_length),
403
- metadata(variable)
404
- )
405
-
406
- variable = variable.updated(nil, [variable.children[0]])
407
- else
408
- before += 1
409
- value = values.shift
410
- end
411
-
412
- unless value
413
- value = Node.new(
414
- :keyword,
415
- ['nil'],
416
- metadata(variable)
417
- )
418
- end
419
-
420
- nodes << Node.new(:assign, [variable, value], metadata(variable))
421
- end
422
-
423
- return Node.new(:mass_assign, nodes, metadata)
424
- end
425
-
426
- ##
427
- # @param [RubyLint::Node] variable The variable that was referenced.
428
- # @return [RubyLint::Node]
429
- #
430
- def on_var_ref(variable)
431
- variable = variable.updated(:local_variable) if variable.identifier?
432
-
433
- return variable
434
- end
435
-
436
- ##
437
- # @param [RubyLint::Node] object The object of the field.
438
- # @param [Symbol] operator The operator used to separate the object and
439
- # field.
440
- # @param [RubyLint::Node] field The field that was referenced.
441
- # @return [RubyLint::Node]
442
- #
443
- def on_field(object, operator, field)
444
- return Node.new(:field, [object, field], metadata)
445
- end
446
-
447
- ##
448
- # Called when a method without parenthesis is called.
449
- #
450
- # @see RubyLint::Parser#on_method_add_arg
451
- #
452
- def on_command(name, params)
453
- return Node.new(
454
- :method,
455
- [name.children[0], on_params(params), nil, nil],
456
- metadata(name)
457
- )
458
- end
459
-
460
- ##
461
- # Called when a method is invoked on an object.
462
- #
463
- # @param [RubyLint::Node] object The object the method was invoked on.
464
- # @param [Symbol] operator The operator used for the method call.
465
- # @param [RubyLint::Node] name The name of the method.
466
- # @return [RubyLint::Node]
467
- #
468
- def on_call(object, operator, name)
469
- return Node.new(
470
- :method,
471
- [name.children[0], on_params, nil, object],
472
- metadata(name)
473
- )
474
- end
475
-
476
- ##
477
- # Called when a method is invoked on an object without the use of
478
- # parenthesis.
479
- #
480
- # @see RubyLint::Parser#on_call
481
- #
482
- def on_command_call(object, operator, name, params)
483
- node = on_call(object, operator, name)
484
- children = node.children.dup
485
- children[1] = on_params(params)
486
-
487
- return node.updated(nil, children)
488
- end
489
-
490
- ##
491
- # @param [RubyLint::Node] method The method that is called.
492
- # @param [RubyLint::Node|Array] params Array of parameters passed to the
493
- # method.
494
- # @return [RubyLint::Node]
495
- #
496
- def on_method_add_arg(method, params)
497
- children = method.children.dup
498
-
499
- if !params.is_a?(Array)
500
- children[1] = params
501
- end
502
-
503
- return method.updated(nil, children)
504
- end
505
-
506
- ##
507
- # @param [Mixed] arguments
508
- # @param [Mixed] block
509
- #
510
- def on_args_add_block(arguments, block)
511
- return on_params(arguments, nil, nil, nil, block)
512
- end
513
-
514
- ##
515
- # @param [Mixed] arguments
516
- # @param [Mixed] splat
517
- # @return [Array]
518
- #
519
- def on_args_add_star(arguments, splat)
520
- # Ripper isn't exactly consistent with its output. In certain cases, such
521
- # `*(foo = something_else)` splat will be set to an Array instead of the
522
- # assignment node.
523
- splat = splat[0] if splat.is_a?(Array)
524
-
525
- return arguments << Node.new(:splat_argument, [splat], metadata(splat))
526
- end
527
-
528
- ##
529
- # @param [RubyLint::Node] method The method node.
530
- # @param [RubyLint::Node] block The block passed to the method.
531
- # @return [RubyLint::Node]
532
- #
533
- def on_method_add_block(method, block)
534
- children = method.children.dup
535
- index = method.type == :super ? 1 : -2
536
- children[index] = block
537
-
538
- return method.updated(nil, children)
539
- end
540
-
541
- ##
542
- # @param [RubyLint::Node] name The name of the method.
543
- # @param [Array] params The parameters of the method.
544
- # @param [Array] body The body of the method.
545
- # @return [RubyLint::Node]
546
- #
547
- def on_def(name, params, body)
548
- return Node.new(
549
- :method_definition,
550
- [name.children[0], params, nil, body],
551
- metadata(name)
552
- )
553
- end
554
-
555
- ##
556
- # Called when a method definition using a receiver is found.
557
- #
558
- # @see RubyLint::Parser#on_def
559
- #
560
- def on_defs(receiver, operator, name, params, body)
561
- return Node.new(
562
- :method_definition,
563
- [name.children[0], params, receiver, body],
564
- metadata(name)
565
- )
566
- end
567
-
568
- ##
569
- # Called when a set of method parameters if found.
570
- #
571
- # @param [Array] params The specified parameters.
572
- # @return [Array]
573
- #
574
- def on_params(*params)
575
- if params[0].is_a?(Node) and params[0].type == :arguments
576
- return params[0]
577
- end
578
-
579
- if params[1]
580
- params[1] = remap_optional_arguments(params[1])
581
- end
582
-
583
- params = group_arguments(params)
584
-
585
- return Node.new(:arguments, params, metadata)
586
- end
587
-
588
- ##
589
- # @param [RubyLint::Node] statement The statement to evaluate.
590
- # @param [Array] body The body of the if statement.
591
- # @param [Array|NilClass] rest The rest of the statement, includes the
592
- # elsif and else statements.
593
- # @return [RubyLint::Node]
594
- #
595
- def on_if(statement, body, rest = nil)
596
- elsif_stmts = []
597
- else_stmt = nil
598
-
599
- rest ||= []
600
- rest = [rest] unless rest.is_a?(Array)
601
-
602
- rest.compact.each do |node|
603
- if node.type == :else
604
- else_stmt = node
605
- else
606
- elsif_stmts << node
607
- end
608
- end
609
-
610
- return Node.new(
611
- :if,
612
- [statement, body, elsif_stmts.reverse, else_stmt],
613
- metadata
614
- )
615
- end
616
-
617
- ##
618
- # Called when a ternary operator is found.
619
- #
620
- # @param [RubyLint::Node] statement The statement to evaluate.
621
- # @param [RubyLint::Node] true_val The value to use when the statement
622
- # evaluates to true.
623
- # @param [RubyLint::Node] false_val The value to use when the statement
624
- # evaluates to false.
625
- # @return [RubyLint::Node]
626
- #
627
- def on_ifop(statement, true_val, false_val)
628
- return Node.new(
629
- :ternary,
630
- [statement, true_val, false_val],
631
- metadata
632
- )
633
- end
634
-
635
- ##
636
- # @param [RubyLint::Node] statement The statement to evaluate.
637
- # @param [Array] body The body of the statement.
638
- # @param [Array] list Array containing the rest of the if statement.
639
- # @return [RubyLint::Node]
640
- #
641
- def on_elsif(statement, body, list)
642
- node = Node.new(:elsif, [statement, body], metadata)
643
- list = [list] unless list.is_a?(Array)
644
-
645
- list << node
646
- end
647
-
648
- ##
649
- # @param [Array|RubyLint::Node] variables The variables to create for each
650
- # iteration.
651
- # @param [RubyLint::Node] enumerator The value to iterate over.
652
- # @param [Array] body The body of the statement.
653
- # @return [RubyLint::Node]
654
- #
655
- def on_for(variables, enumerator, body)
656
- variables = [variables] unless variables.is_a?(Array)
657
- variables.map! { |n| n.updated(:local_variable) if n.identifier? }
658
-
659
- return Node.new(
660
- :for,
661
- [variables, enumerator, body],
662
- metadata(variables[0])
663
- )
664
- end
665
-
666
- ##
667
- # @param [Array] exceptions A list of exceptions to catch.
668
- # @param [RubyLint::Variable|NilClass] variable The variable to store
669
- # information in about the exception.
670
- # @param [Array] body The body of the statement.
671
- # @param [Array] list Array containing all the rescue, else and ensure
672
- # statements.
673
- # @return [RubyLint::Node]
674
- #
675
- def on_rescue(exceptions, variable, body, list)
676
- list = list.is_a?(Array) ? list : [list].compact
677
-
678
- if variable and variable.identifier?
679
- variable = variable.updated(:local_variable)
680
- end
681
-
682
- list.unshift(
683
- Node.new(:rescue, [nil, exceptions, variable, body], metadata)
684
- )
685
- end
686
-
687
- ##
688
- # @param [RubyLint::Node] statement The statement for which to catch
689
- # errors.
690
- # @param [RubyLint::Node] body The code to execute when an error was
691
- # raised.
692
- # @return [RubyLint::Node]
693
- #
694
- def on_rescue_mod(statement, body)
695
- return Node.new(:rescue, [statement, nil, nil, body], metadata)
696
- end
697
-
698
- ##
699
- # @param [RubyLint::Node] statement The statement to evaluate.
700
- # @param [Array] body The body of the case block such as all the when
701
- # statements.
702
- # @return [RubyLint::Node]
703
- #
704
- def on_case(statement, body)
705
- when_statements = []
706
- else_statement = nil
707
-
708
- body.each do |node|
709
- if node.type == :when
710
- when_statements << node
711
- else
712
- else_statement = node
713
- end
714
- end
715
-
716
- return Node.new(
717
- :case,
718
- [statement, when_statements, else_statement],
719
- metadata
720
- )
721
- end
722
-
723
- ##
724
- # @param [RubyLint::Node|Array] values The values to match on.
725
- # @param [RubyLint::Node] body The body of the statement.
726
- # @param [RubyLint::Node|Array] list The list of other when and else nodes.
727
- # @return [RubyLint::Node]
728
- #
729
- def on_when(values, body, list)
730
- list = [list].compact unless list.is_a?(Array)
731
- values = [values] unless values.is_a?(Array)
732
-
733
- node = Node.new(:when, [values, body], metadata)
734
-
735
- list.unshift(node)
736
- end
737
-
738
- ##
739
- # @return [RubyLint::Node]
740
- #
741
- def on_zsuper
742
- return on_super(nil)
743
- end
744
-
745
- private
746
-
747
- ##
748
- # Returns a more readable version of a Ripper type name.
749
- #
750
- # @param [Symbol] type The type to convert.
751
- # @return [Symbol]
752
- #
753
- def readable_type_name(type)
754
- return TYPE_MAPPING.fetch(type, type)
755
- end
756
-
757
- ##
758
- # Returns a Hash containing metadata such as the line number and the file.
759
- #
760
- # @param [RubyLint::Node] node When set the line and column number will be
761
- # extracted from this node.
762
- # @return [Hash]
763
- #
764
- def metadata(node = nil)
765
- line = node ? node.line : lineno
766
- col = node ? node.column : column
767
-
768
- return {:line => line, :column => col, :file => @file}
769
- end
770
-
771
- ##
772
- # Groups a set of parameters into nodes based on the indexes.
773
- #
774
- # @param [Array] nodes
775
- # @return [Array]
776
- #
777
- def group_arguments(nodes)
778
- new_nodes = []
779
-
780
- nodes.each_with_index do |node, index|
781
- if !node or (node.is_a?(Array) and node.empty?)
782
- next
783
- end
784
-
785
- new_nodes << convert_argument_node(node, index)
786
- end
9
+ class Parser
10
+ attr_reader :internal_parser
787
11
 
788
- return new_nodes.flatten
12
+ def initialize
13
+ builder = AST::Builder.new
14
+ @internal_parser = ::Parser::CurrentRuby.new(builder)
789
15
  end
790
16
 
791
17
  ##
792
- # Remaps variable/value pairs of optional arguments into single nodes.
18
+ # Registers the consumer with the internal diagnostics handler.
793
19
  #
794
- # @param [Array] nodes
795
- # @return [Array]
20
+ # @param [#call] consumer
796
21
  #
797
- def remap_optional_arguments(nodes)
798
- return nodes.map do |node|
799
- node[0].updated(nil, [node[0].children[0], node[1]])
800
- end
22
+ def consumer=(consumer)
23
+ internal_parser.diagnostics.consumer = consumer
801
24
  end
802
25
 
803
26
  ##
804
- # Converts a parameter node to a type based on its index.
27
+ # Parses a block of Ruby code and wraps the resulting AST in a root node.
805
28
  #
806
- # @param [RubyLint::Node|Array] node
807
- # @param [Numeric] index
808
- # @return [Mixed]
29
+ # @param [String] code
30
+ # @param [String] file
31
+ # @param [Numeric] line
32
+ # @return [RubyLint::AST::Node]
809
33
  #
810
- def convert_argument_node(node, index)
811
- if node.is_a?(Array)
812
- node = node.map { |n| convert_argument_node(n, index) }
813
- else
814
- if node.identifier?
815
- node = node.updated(:local_variable)
816
- end
34
+ def parse(code, file = '(ruby-lint)', line = 1)
35
+ buffer = ::Parser::Source::Buffer.new(file, line)
36
+ buffer.source = code
37
+ ast = internal_parser.parse(buffer)
817
38
 
818
- if node.type != :splat_argument
819
- node = Node.new(PARAMETER_INDEX_TYPES[index], [node])
820
- end
821
- end
39
+ internal_parser.reset
822
40
 
823
- return node
41
+ return AST::Node.new(:root, [ast])
824
42
  end
825
43
  end # Parser
826
44
  end # RubyLint