ruby-lint 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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