ruby-lint 0.0.4 → 0.0.5

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 (317) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.asc +17 -0
  3. data.tar.gz.asc +14 -14
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +0 -1
  6. data/.yardopts +1 -0
  7. data/CONTRIBUTING.md +41 -0
  8. data/MANIFEST +99 -66
  9. data/README.md +36 -10
  10. data/Rakefile +6 -0
  11. data/checksum/ruby-lint-0.0.4.gem.sha512 +1 -0
  12. data/doc/changelog.md +94 -0
  13. data/lib/ruby-lint.rb +18 -1
  14. data/lib/ruby-lint/analysis/argument_amount.rb +43 -10
  15. data/lib/ruby-lint/analysis/base.rb +23 -17
  16. data/lib/ruby-lint/analysis/pedantics.rb +3 -1
  17. data/lib/ruby-lint/analysis/undefined_methods.rb +48 -10
  18. data/lib/ruby-lint/analysis/unused_variables.rb +27 -5
  19. data/lib/ruby-lint/ast/node.rb +10 -0
  20. data/lib/ruby-lint/cli/analyze.rb +22 -4
  21. data/lib/ruby-lint/cli/base.rb +8 -2
  22. data/lib/ruby-lint/configuration.rb +43 -4
  23. data/lib/ruby-lint/definition/constant_proxy.rb +10 -1
  24. data/lib/ruby-lint/definition/ruby_method.rb +45 -31
  25. data/lib/ruby-lint/definition/ruby_object.rb +56 -15
  26. data/lib/ruby-lint/definition_builder/base.rb +4 -0
  27. data/lib/ruby-lint/definition_builder/primitive.rb +1 -1
  28. data/lib/ruby-lint/definition_builder/ruby_array.rb +1 -1
  29. data/lib/ruby-lint/definition_builder/ruby_block.rb +1 -0
  30. data/lib/ruby-lint/definition_builder/ruby_class.rb +1 -1
  31. data/lib/ruby-lint/definition_builder/ruby_hash.rb +1 -1
  32. data/lib/ruby-lint/definition_builder/ruby_module.rb +3 -1
  33. data/lib/ruby-lint/definition_generator.rb +15 -7
  34. data/lib/ruby-lint/definitions/core/arg0.rb +1 -1
  35. data/lib/ruby-lint/definitions/core/argf.rb +1 -1
  36. data/lib/ruby-lint/definitions/core/argument_error.rb +2 -2
  37. data/lib/ruby-lint/definitions/core/argv.rb +1 -1
  38. data/lib/ruby-lint/definitions/core/array.rb +6 -6
  39. data/lib/ruby-lint/definitions/core/autoload.rb +2 -2
  40. data/lib/ruby-lint/definitions/core/basic_object.rb +8 -12
  41. data/lib/ruby-lint/definitions/core/bignum.rb +2 -2
  42. data/lib/ruby-lint/definitions/core/binding.rb +2 -2
  43. data/lib/ruby-lint/definitions/core/class.rb +2 -2
  44. data/lib/ruby-lint/definitions/core/comparable.rb +1 -1
  45. data/lib/ruby-lint/definitions/core/complex.rb +4 -4
  46. data/lib/ruby-lint/definitions/core/condition_variable.rb +2 -2
  47. data/lib/ruby-lint/definitions/core/continuation.rb +2 -2
  48. data/lib/ruby-lint/definitions/core/data.rb +2 -2
  49. data/lib/ruby-lint/definitions/core/date.rb +34 -34
  50. data/lib/ruby-lint/definitions/core/date_time.rb +26 -26
  51. data/lib/ruby-lint/definitions/core/default_record_separator.rb +1 -1
  52. data/lib/ruby-lint/definitions/core/digest.rb +14 -14
  53. data/lib/ruby-lint/definitions/core/dir.rb +34 -34
  54. data/lib/ruby-lint/definitions/core/encoding.rb +237 -237
  55. data/lib/ruby-lint/definitions/core/encoding_error.rb +2 -2
  56. data/lib/ruby-lint/definitions/core/enumerable.rb +15 -15
  57. data/lib/ruby-lint/definitions/core/enumerator.rb +2 -2
  58. data/lib/ruby-lint/definitions/core/env.rb +1 -1
  59. data/lib/ruby-lint/definitions/core/eoferror.rb +2 -2
  60. data/lib/ruby-lint/definitions/core/erb.rb +30 -23
  61. data/lib/ruby-lint/definitions/core/errno.rb +525 -525
  62. data/lib/ruby-lint/definitions/core/etc.rb +6 -6
  63. data/lib/ruby-lint/definitions/core/exception.rb +2 -2
  64. data/lib/ruby-lint/definitions/core/false.rb +1 -1
  65. data/lib/ruby-lint/definitions/core/false_class.rb +2 -2
  66. data/lib/ruby-lint/definitions/core/fatal_error.rb +2 -2
  67. data/lib/ruby-lint/definitions/core/fiber.rb +2 -2
  68. data/lib/ruby-lint/definitions/core/fiber_error.rb +2 -2
  69. data/lib/ruby-lint/definitions/core/file.rb +68 -68
  70. data/lib/ruby-lint/definitions/core/file_list.rb +2 -2
  71. data/lib/ruby-lint/definitions/core/file_test.rb +1 -1
  72. data/lib/ruby-lint/definitions/core/file_utils.rb +16 -16
  73. data/lib/ruby-lint/definitions/core/fixnum.rb +4 -4
  74. data/lib/ruby-lint/definitions/core/float.rb +16 -16
  75. data/lib/ruby-lint/definitions/core/float_domain_error.rb +2 -2
  76. data/lib/ruby-lint/definitions/core/gc.rb +2 -2
  77. data/lib/ruby-lint/definitions/core/gem.rb +119 -119
  78. data/lib/ruby-lint/definitions/core/hash.rb +14 -14
  79. data/lib/ruby-lint/definitions/core/immediate_value.rb +1 -1
  80. data/lib/ruby-lint/definitions/core/index_error.rb +2 -2
  81. data/lib/ruby-lint/definitions/core/integer.rb +2 -2
  82. data/lib/ruby-lint/definitions/core/interrupt.rb +2 -2
  83. data/lib/ruby-lint/definitions/core/io.rb +38 -38
  84. data/lib/ruby-lint/definitions/core/ioerror.rb +2 -2
  85. data/lib/ruby-lint/definitions/core/kernel.rb +113 -60
  86. data/lib/ruby-lint/definitions/core/key_error.rb +2 -2
  87. data/lib/ruby-lint/definitions/core/load_error.rb +6 -6
  88. data/lib/ruby-lint/definitions/core/local_jump_error.rb +2 -2
  89. data/lib/ruby-lint/definitions/core/marshal.rb +35 -35
  90. data/lib/ruby-lint/definitions/core/match_data.rb +2 -2
  91. data/lib/ruby-lint/definitions/core/math.rb +7 -7
  92. data/lib/ruby-lint/definitions/core/memory_segmention_error.rb +2 -2
  93. data/lib/ruby-lint/definitions/core/method.rb +2 -2
  94. data/lib/ruby-lint/definitions/core/module.rb +39 -3
  95. data/lib/ruby-lint/definitions/core/monitor.rb +4 -4
  96. data/lib/ruby-lint/definitions/core/monitor_mixin.rb +5 -5
  97. data/lib/ruby-lint/definitions/core/mutex.rb +2 -2
  98. data/lib/ruby-lint/definitions/core/name_error.rb +2 -2
  99. data/lib/ruby-lint/definitions/core/nil.rb +1 -1
  100. data/lib/ruby-lint/definitions/core/nil_class.rb +2 -2
  101. data/lib/ruby-lint/definitions/core/no_memory_error.rb +2 -2
  102. data/lib/ruby-lint/definitions/core/no_method_error.rb +2 -2
  103. data/lib/ruby-lint/definitions/core/not_implemented_error.rb +2 -2
  104. data/lib/ruby-lint/definitions/core/numeric.rb +2 -2
  105. data/lib/ruby-lint/definitions/core/object.rb +2 -2
  106. data/lib/ruby-lint/definitions/core/object_space.rb +1 -1
  107. data/lib/ruby-lint/definitions/core/open_struct.rb +3 -3
  108. data/lib/ruby-lint/definitions/core/option_parser.rb +83 -83
  109. data/lib/ruby-lint/definitions/core/precision.rb +1 -1
  110. data/lib/ruby-lint/definitions/core/primitive_failure.rb +2 -2
  111. data/lib/ruby-lint/definitions/core/proc.rb +2 -2
  112. data/lib/ruby-lint/definitions/core/process.rb +29 -29
  113. data/lib/ruby-lint/definitions/core/queue.rb +2 -2
  114. data/lib/ruby-lint/definitions/core/rake.rb +117 -117
  115. data/lib/ruby-lint/definitions/core/rake_file_utils.rb +1 -1
  116. data/lib/ruby-lint/definitions/core/rakeversion.rb +1 -1
  117. data/lib/ruby-lint/definitions/core/random.rb +2 -2
  118. data/lib/ruby-lint/definitions/core/range.rb +4 -4
  119. data/lib/ruby-lint/definitions/core/range_error.rb +2 -2
  120. data/lib/ruby-lint/definitions/core/rational.rb +2 -2
  121. data/lib/ruby-lint/definitions/core/rb_config.rb +3 -3
  122. data/lib/ruby-lint/definitions/core/regexp.rb +28 -28
  123. data/lib/ruby-lint/definitions/core/regexp_error.rb +2 -2
  124. data/lib/ruby-lint/definitions/core/ruby_copyright.rb +1 -1
  125. data/lib/ruby-lint/definitions/core/ruby_description.rb +1 -1
  126. data/lib/ruby-lint/definitions/core/ruby_engine.rb +1 -1
  127. data/lib/ruby-lint/definitions/core/ruby_patchlevel.rb +1 -1
  128. data/lib/ruby-lint/definitions/core/ruby_platform.rb +1 -1
  129. data/lib/ruby-lint/definitions/core/ruby_release_date.rb +1 -1
  130. data/lib/ruby-lint/definitions/core/ruby_version.rb +1 -1
  131. data/lib/ruby-lint/definitions/core/runtime_error.rb +2 -2
  132. data/lib/ruby-lint/definitions/core/scan_error.rb +2 -2
  133. data/lib/ruby-lint/definitions/core/script_error.rb +2 -2
  134. data/lib/ruby-lint/definitions/core/security_error.rb +2 -2
  135. data/lib/ruby-lint/definitions/core/shellwords.rb +1 -1
  136. data/lib/ruby-lint/definitions/core/signal.rb +3 -3
  137. data/lib/ruby-lint/definitions/core/signal_exception.rb +2 -2
  138. data/lib/ruby-lint/definitions/core/singleton.rb +2 -2
  139. data/lib/ruby-lint/definitions/core/sized_queue.rb +2 -2
  140. data/lib/ruby-lint/definitions/core/standard_error.rb +2 -2
  141. data/lib/ruby-lint/definitions/core/stderr.rb +3 -2
  142. data/lib/ruby-lint/definitions/core/stdin.rb +3 -2
  143. data/lib/ruby-lint/definitions/core/stdout.rb +3 -2
  144. data/lib/ruby-lint/definitions/core/stop_iteration.rb +2 -2
  145. data/lib/ruby-lint/definitions/core/string.rb +21 -21
  146. data/lib/ruby-lint/definitions/core/string_io.rb +7 -7
  147. data/lib/ruby-lint/definitions/core/string_scanner.rb +4 -4
  148. data/lib/ruby-lint/definitions/core/struct.rb +20 -20
  149. data/lib/ruby-lint/definitions/core/syck.rb +4 -4
  150. data/lib/ruby-lint/definitions/core/symbol.rb +2 -2
  151. data/lib/ruby-lint/definitions/core/syntax_error.rb +2 -2
  152. data/lib/ruby-lint/definitions/core/system_call_error.rb +2 -2
  153. data/lib/ruby-lint/definitions/core/system_exit.rb +2 -2
  154. data/lib/ruby-lint/definitions/core/system_stack_error.rb +2 -2
  155. data/lib/ruby-lint/definitions/core/thread.rb +6 -6
  156. data/lib/ruby-lint/definitions/core/thread_error.rb +2 -2
  157. data/lib/ruby-lint/definitions/core/thread_group.rb +2 -2
  158. data/lib/ruby-lint/definitions/core/time.rb +3 -3
  159. data/lib/ruby-lint/definitions/core/toplevel_binding.rb +1 -1
  160. data/lib/ruby-lint/definitions/core/true.rb +1 -1
  161. data/lib/ruby-lint/definitions/core/true_class.rb +2 -2
  162. data/lib/ruby-lint/definitions/core/type_error.rb +2 -2
  163. data/lib/ruby-lint/definitions/core/unbound_method.rb +2 -2
  164. data/lib/ruby-lint/definitions/core/unmarshalable.rb +1 -1
  165. data/lib/ruby-lint/definitions/core/unsupported_library_error.rb +2 -2
  166. data/lib/ruby-lint/definitions/core/weak_ref.rb +4 -4
  167. data/lib/ruby-lint/definitions/core/yaml.rb +2361 -0
  168. data/lib/ruby-lint/definitions/core/zero_division_error.rb +2 -2
  169. data/lib/ruby-lint/definitions/global_variables.rb +9 -0
  170. data/lib/ruby-lint/definitions/rails/abstract_controller.rb +174 -28
  171. data/lib/ruby-lint/definitions/rails/action_controller.rb +4959 -550
  172. data/lib/ruby-lint/definitions/rails/action_dispatch.rb +2489 -292
  173. data/lib/ruby-lint/definitions/rails/action_mailer.rb +1285 -42
  174. data/lib/ruby-lint/definitions/rails/action_pack.rb +14 -6
  175. data/lib/ruby-lint/definitions/rails/action_view.rb +6941 -445
  176. data/lib/ruby-lint/definitions/rails/active_model.rb +1212 -69
  177. data/lib/ruby-lint/definitions/rails/active_record.rb +10344 -1450
  178. data/lib/ruby-lint/definitions/rails/active_support.rb +4631 -573
  179. data/lib/ruby-lint/definitions/rails/arel.rb +3211 -319
  180. data/lib/ruby-lint/definitions/rails/rails.rb +2922 -84
  181. data/lib/ruby-lint/definitions/rails/sprockets.rb +3048 -277
  182. data/lib/ruby-lint/docstring/mapping.rb +55 -0
  183. data/lib/ruby-lint/docstring/param_tag.rb +29 -0
  184. data/lib/ruby-lint/docstring/parser.rb +133 -0
  185. data/lib/ruby-lint/docstring/return_tag.rb +24 -0
  186. data/lib/ruby-lint/file_loader.rb +96 -0
  187. data/lib/ruby-lint/file_scanner.rb +91 -0
  188. data/lib/ruby-lint/global_scope.rb +56 -0
  189. data/lib/ruby-lint/helper/constant_paths.rb +1 -1
  190. data/lib/ruby-lint/inspector.rb +11 -33
  191. data/lib/ruby-lint/iterator.rb +31 -4
  192. data/lib/ruby-lint/method_call/alias.rb +46 -0
  193. data/lib/ruby-lint/method_call/assign_member.rb +55 -0
  194. data/lib/ruby-lint/method_call/attribute.rb +102 -0
  195. data/lib/ruby-lint/method_call/base.rb +37 -0
  196. data/lib/ruby-lint/method_call/define_method.rb +17 -0
  197. data/lib/ruby-lint/method_call/include.rb +39 -0
  198. data/lib/ruby-lint/parser.rb +9 -4
  199. data/lib/ruby-lint/presenter/text.rb +2 -1
  200. data/lib/ruby-lint/report.rb +19 -42
  201. data/lib/ruby-lint/report/entry.rb +20 -17
  202. data/lib/ruby-lint/runner.rb +92 -11
  203. data/lib/ruby-lint/template/definition.erb +2 -2
  204. data/lib/ruby-lint/variable_predicates.rb +7 -10
  205. data/lib/ruby-lint/version.rb +1 -1
  206. data/lib/ruby-lint/virtual_machine.rb +265 -188
  207. data/ruby-lint.gemspec +4 -4
  208. data/ruby-lint.yml +7 -0
  209. data/spec/fixtures/associating.rb +7 -0
  210. data/spec/fixtures/file_scanner/lib/example/recursive/source.rb +6 -0
  211. data/spec/fixtures/file_scanner/lib/example/recursive/target.rb +8 -0
  212. data/spec/fixtures/file_scanner/lib/example/user.rb +6 -0
  213. data/spec/fixtures/file_scanner/lib/test-dashes/foo.rb +4 -0
  214. data/spec/fixtures/file_scanner/rails/app/models/example/user.rb +6 -0
  215. data/spec/fixtures/file_scanner/rails/app/models/user.rb +4 -0
  216. data/spec/fixtures/uses_external.rb +1 -0
  217. data/spec/fixtures/uses_external_invalid.rb +3 -0
  218. data/spec/fixtures/uses_external_namespace.rb +1 -0
  219. data/spec/ruby-lint/analysis/{argument_amount.rb → argument_amount_spec.rb} +33 -7
  220. data/spec/ruby-lint/analysis/base_spec.rb +12 -0
  221. data/spec/ruby-lint/analysis/{pedantics.rb → pedantics_spec.rb} +24 -4
  222. data/spec/ruby-lint/analysis/{shadowing_variables.rb → shadowing_variables_spec.rb} +6 -6
  223. data/spec/ruby-lint/analysis/undefined_methods_spec.rb +320 -0
  224. data/spec/ruby-lint/analysis/{undefined_variables.rb → undefined_variables_spec.rb} +33 -10
  225. data/spec/ruby-lint/analysis/{unused_variables.rb → unused_variables_spec.rb} +36 -9
  226. data/spec/ruby-lint/ast/{node.rb → node_spec.rb} +12 -6
  227. data/spec/ruby-lint/cli/{analyze.rb → analyze_spec.rb} +16 -5
  228. data/spec/ruby-lint/cli/{ast.rb → ast_spec.rb} +3 -3
  229. data/spec/ruby-lint/configuration_spec.rb +106 -0
  230. data/spec/ruby-lint/definition/constant_proxy_spec.rb +54 -0
  231. data/spec/ruby-lint/definition/{dsl.rb → dsl_spec.rb} +15 -15
  232. data/spec/ruby-lint/definition/{ruby_method.rb → ruby_method_spec.rb} +31 -17
  233. data/spec/ruby-lint/definition/{ruby_object.rb → ruby_object_spec.rb} +28 -23
  234. data/spec/ruby-lint/definition_builder/{primitive.rb → primitive_spec.rb} +9 -9
  235. data/spec/ruby-lint/definition_builder/{ruby_class.rb → ruby_class_spec.rb} +13 -13
  236. data/spec/ruby-lint/definition_builder/{ruby_method.rb → ruby_method_spec.rb} +9 -9
  237. data/spec/ruby-lint/definition_builder/{ruby_module.rb → ruby_module_spec.rb} +12 -10
  238. data/spec/ruby-lint/docstring/mapping.rb +27 -0
  239. data/spec/ruby-lint/docstring/parser_spec.rb +88 -0
  240. data/spec/ruby-lint/extensions/{string.rb → string_spec.rb} +3 -3
  241. data/spec/ruby-lint/file_loader_spec.rb +69 -0
  242. data/spec/ruby-lint/file_scanner_spec.rb +51 -0
  243. data/spec/ruby-lint/inspector_spec.rb +44 -0
  244. data/spec/ruby-lint/{iterator.rb → iterator_spec.rb} +39 -4
  245. data/spec/ruby-lint/{nested_stack.rb → nested_stack_spec.rb} +4 -4
  246. data/spec/ruby-lint/parser_spec.rb +31 -0
  247. data/spec/ruby-lint/presenter/json_spec.rb +58 -0
  248. data/spec/ruby-lint/presenter/text_spec.rb +49 -0
  249. data/spec/ruby-lint/report/entry_spec.rb +58 -0
  250. data/spec/ruby-lint/report_spec.rb +39 -0
  251. data/spec/ruby-lint/runner_spec.rb +52 -0
  252. data/spec/ruby-lint/virtual_machine/alias_spec.rb +55 -0
  253. data/spec/ruby-lint/virtual_machine/assignments/{arrays.rb → arrays_spec.rb} +7 -7
  254. data/spec/ruby-lint/virtual_machine/assignments/{hashes.rb → hashes_spec.rb} +6 -6
  255. data/spec/ruby-lint/virtual_machine/assignments/{optional.rb → optional_spec.rb} +6 -6
  256. data/spec/ruby-lint/virtual_machine/assignments/{return_values.rb → return_values_spec.rb} +11 -11
  257. data/spec/ruby-lint/virtual_machine/assignments/{variables.rb → variables_spec.rb} +38 -7
  258. data/spec/ruby-lint/virtual_machine/associate_nodes_spec.rb +59 -0
  259. data/spec/ruby-lint/virtual_machine/{autoloading.rb → autoloading_spec.rb} +6 -6
  260. data/spec/ruby-lint/virtual_machine/{blocks.rb → blocks_spec.rb} +30 -4
  261. data/spec/ruby-lint/virtual_machine/classes/{class_methods.rb → class_methods_spec.rb} +3 -3
  262. data/spec/ruby-lint/virtual_machine/classes/{extending.rb → extending_spec.rb} +20 -15
  263. data/spec/ruby-lint/virtual_machine/classes/{redefining.rb → redefining_spec.rb} +3 -3
  264. data/spec/ruby-lint/virtual_machine/classes/{sclass.rb → sclass_spec.rb} +7 -7
  265. data/spec/ruby-lint/virtual_machine/classes/{scoping.rb → scoping_spec.rb} +5 -5
  266. data/spec/ruby-lint/virtual_machine/complex/{rails.rb → rails_spec.rb} +3 -3
  267. data/spec/ruby-lint/virtual_machine/complex/{rcap.rb → rcap_spec.rb} +3 -3
  268. data/spec/ruby-lint/virtual_machine/complex/{slop.rb → slop_spec.rb} +3 -3
  269. data/spec/ruby-lint/virtual_machine/constants_spec.rb +31 -0
  270. data/spec/ruby-lint/virtual_machine/{for.rb → for_spec.rb} +3 -3
  271. data/spec/ruby-lint/virtual_machine/{freeze.rb → freeze_spec.rb} +3 -3
  272. data/spec/ruby-lint/virtual_machine/global_variables_spec.rb +12 -0
  273. data/spec/ruby-lint/virtual_machine/inherit_kernel_spec.rb +15 -0
  274. data/spec/ruby-lint/virtual_machine/{interpolation.rb → interpolation_spec.rb} +3 -3
  275. data/spec/ruby-lint/virtual_machine/methods/attr_spec.rb +116 -0
  276. data/spec/ruby-lint/virtual_machine/methods/define_method_spec.rb +41 -0
  277. data/spec/ruby-lint/virtual_machine/methods/{defining.rb → defining_spec.rb} +4 -4
  278. data/spec/ruby-lint/virtual_machine/methods/docstrings_spec.rb +69 -0
  279. data/spec/ruby-lint/virtual_machine/methods/{exporting.rb → exporting_spec.rb} +3 -3
  280. data/spec/ruby-lint/virtual_machine/methods/{parameters.rb → parameters_spec.rb} +17 -5
  281. data/spec/ruby-lint/virtual_machine/methods/{patching.rb → patching_spec.rb} +4 -4
  282. data/spec/ruby-lint/virtual_machine/methods/{scoping.rb → scoping_spec.rb} +5 -5
  283. data/spec/ruby-lint/virtual_machine/methods/{visibility.rb → visibility_spec.rb} +6 -6
  284. data/spec/ruby-lint/virtual_machine/{modules.rb → modules_spec.rb} +39 -9
  285. data/spec/ruby-lint/virtual_machine/reference_amount_spec.rb +61 -0
  286. data/spec/ruby-lint/virtual_machine/{unused.rb → unused_spec.rb} +4 -4
  287. data/spec/{helper.rb → spec_helper.rb} +6 -4
  288. data/spec/support/building.rb +10 -6
  289. data/spec/support/coveralls.rb +1 -1
  290. data/spec/support/parsing.rb +10 -1
  291. data/spec/support/simplecov.rb +1 -1
  292. data/spec/support/versions.rb +9 -0
  293. data/task/test.rake +2 -4
  294. data/task/travis.rake +1 -0
  295. metadata +144 -143
  296. metadata.gz.asc +14 -14
  297. data/.rubocop.yml +0 -59
  298. data/doc/contributing.md +0 -16
  299. data/lib/ruby-lint/analysis/confusing_variables.rb +0 -26
  300. data/lib/ruby-lint/definitions/core/main.rb +0 -25
  301. data/lib/ruby-lint/definitions/core/psych.rb +0 -2231
  302. data/lib/ruby-lint/definitions/core/rubinius.rb +0 -16637
  303. data/lib/ruby-lint/definitions/core/ruby_lint.rb +0 -93
  304. data/spec/ruby-lint/analysis/confusing_variables.rb +0 -46
  305. data/spec/ruby-lint/analysis/undefined_methods.rb +0 -174
  306. data/spec/ruby-lint/configuration.rb +0 -54
  307. data/spec/ruby-lint/definition/constant_proxy.rb +0 -31
  308. data/spec/ruby-lint/parser.rb +0 -14
  309. data/spec/ruby-lint/presenter/json.rb +0 -31
  310. data/spec/ruby-lint/presenter/text.rb +0 -22
  311. data/spec/ruby-lint/report.rb +0 -50
  312. data/spec/ruby-lint/report/entry.rb +0 -28
  313. data/spec/ruby-lint/runner.rb +0 -32
  314. data/spec/ruby-lint/virtual_machine/associate_nodes.rb +0 -17
  315. data/spec/ruby-lint/virtual_machine/reference_amount.rb +0 -33
  316. data/spec/support/bacon.rb +0 -33
  317. data/task/cop.rake +0 -11
@@ -12,6 +12,8 @@ module RubyLint
12
12
  def initialize
13
13
  builder = AST::Builder.new
14
14
  @internal_parser = ::Parser::CurrentRuby.new(builder)
15
+
16
+ internal_parser.diagnostics.all_errors_are_fatal = false
15
17
  end
16
18
 
17
19
  ##
@@ -24,21 +26,24 @@ module RubyLint
24
26
  end
25
27
 
26
28
  ##
27
- # Parses a block of Ruby code and wraps the resulting AST in a root node.
29
+ # Parses a block of Ruby code and returns the AST and a mapping of each AST
30
+ # node and their comments (if there are any). This mapping is returned as a
31
+ # Hash.
28
32
  #
29
33
  # @param [String] code
30
34
  # @param [String] file
31
35
  # @param [Numeric] line
32
- # @return [RubyLint::AST::Node]
36
+ # @return [Array]
33
37
  #
34
38
  def parse(code, file = '(ruby-lint)', line = 1)
35
39
  buffer = ::Parser::Source::Buffer.new(file, line)
36
40
  buffer.source = code
37
- ast = internal_parser.parse(buffer)
41
+ ast, comments = internal_parser.parse_with_comments(buffer)
42
+ associator = ::Parser::Source::Comment::Associator.new(comments, ast)
38
43
 
39
44
  internal_parser.reset
40
45
 
41
- return AST::Node.new(:root, [ast])
46
+ return AST::Node.new(:root, [ast]), associator.associate
42
47
  end
43
48
  end # Parser
44
49
  end # RubyLint
@@ -10,7 +10,8 @@ module RubyLint
10
10
  #
11
11
  # @return [String]
12
12
  #
13
- FORMAT = '%{file}: %{level}: line %{line}, column %{column}: %{message}'
13
+ FORMAT = '%{filename}: %{level}: line %{line}, column %{column}: ' \
14
+ '%{message}'
14
15
 
15
16
  ##
16
17
  # @param [String] format The format to use for each entry.
@@ -15,28 +15,22 @@ module RubyLint
15
15
  # * info
16
16
  #
17
17
  # Unless other levels are specified when creating an instance these levels
18
- # are used for each new instance.
19
- #
20
- # Adding available levels can be done as following:
21
- #
22
- # RubyLint::Report.add_level(:pedantic)
23
- #
24
- # Retrieving a list of available levels in turn is done as following:
25
- #
26
- # RubyLint::Report.levels # => [:error, :warning, :info, :pedantic]
27
- #
28
- # Each level is a Symbol and will be cased to one automatically.
18
+ # are used for each new instance. Extra levels can be specified in the
19
+ # constructor of this class.
29
20
  #
30
21
  # ## Adding Entries
31
22
  #
32
- # Adding entries can be done by either calling {RubyLint::Report#add} or a
33
- # method for the corresponding reporting level:
23
+ # Adding entries can be done by either calling {RubyLint::Report#add}:
34
24
  #
35
25
  # report = RubyLint::Report.new
36
26
  #
37
- # # Both these calls do the same.
38
- # report.add(:info, 'informational message', 1, 2, 'file.rb')
39
- # report.info('informational message', 1, 2, 'file.rb')
27
+ # report.add(
28
+ # :level => :info,
29
+ # :message => 'informational message',
30
+ # :line => 1,
31
+ # :column => 2,
32
+ # :file => 'file.rb'
33
+ # )
40
34
  #
41
35
  # When using {RubyLint::Report#add} any invalid/disabled reporting levels
42
36
  # will be silently ignored. This makes it easier for code to add entries of a
@@ -44,6 +38,7 @@ module RubyLint
44
38
  #
45
39
  # @!attribute [r] entries
46
40
  # @return [Array] The entries of the report.
41
+ #
47
42
  # @!attribute [r] levels
48
43
  # @return [Array] The enabled levels of the report.
49
44
  #
@@ -68,34 +63,16 @@ module RubyLint
68
63
  ##
69
64
  # Adds a new entry to the report.
70
65
  #
71
- # @param [#to_sym] level
72
- # @param [String] message
73
- # @param [Numeric] line
74
- # @param [Numeric] column
75
- # @param [String] file
66
+ # @param [Hash] attributes
67
+ # @option attributes [Symbol] :level The level of the message.
68
+ #
69
+ # @see RubyLint::Report::Entry#initialize
76
70
  #
77
- def add(level, message, line, column, file)
78
- level = level.to_sym
71
+ def add(attributes)
72
+ level = attributes[:level].to_sym
79
73
 
80
74
  if valid_level?(level)
81
- @entries << Entry.new(level, message, line, column, file)
82
- end
83
- end
84
-
85
- ##
86
- # Makes it easier to add entries to a report by calling methods such as
87
- # `#info` instead of `add(:info, ...)`.
88
- #
89
- # @param [Symbol] name
90
- # @param [Array] args
91
- # @param [Proc] block
92
- # @raise [NoMethodError] Raised when an invalid method was called.
93
- #
94
- def method_missing(name, *args, &block)
95
- if valid_level?(name)
96
- return add(name, *args, &block)
97
- else
98
- raise NoMethodError, 'undefined method "%s" for %s' % [name, inspect]
75
+ entries << Entry.new(attributes)
99
76
  end
100
77
  end
101
78
 
@@ -106,7 +83,7 @@ module RubyLint
106
83
  # @return [TrueClass|FalseClass]
107
84
  #
108
85
  def valid_level?(level)
109
- return @levels.include?(level)
86
+ return levels.include?(level)
110
87
  end
111
88
  end # Report
112
89
  end # RubyLint
@@ -6,31 +6,32 @@ module RubyLint
6
6
  #
7
7
  # @!attribute [r] level
8
8
  # @return [Symbol]
9
+ #
9
10
  # @!attribute [r] message
10
11
  # @return [String]
12
+ #
11
13
  # @!attribute [r] line
12
14
  # @return [Numeric]
15
+ #
13
16
  # @!attribute [r] column
14
17
  # @return [Numeric]
18
+ #
15
19
  # @!attribute [r] file
16
20
  # @return [String]
17
21
  #
22
+ # @!attribute [r] node
23
+ # @return [RubyLint::AST::Node]
24
+ #
18
25
  class Entry
19
- attr_reader :level, :message, :line, :column, :file
26
+ attr_reader :level, :message, :line, :column, :file, :node
20
27
 
21
28
  ##
22
- # @param [Symbol] level
23
- # @param [String] message
24
- # @param [Numeric] line
25
- # @param [Numeric] column
26
- # @param [String] file
29
+ # @param [Hash] attributes
27
30
  #
28
- def initialize(level, message, line, column, file)
29
- @level = level
30
- @message = message
31
- @line = line
32
- @column = column
33
- @file = file
31
+ def initialize(attributes = {})
32
+ attributes.each do |key, value|
33
+ instance_variable_set("@#{key}", value)
34
+ end
34
35
  end
35
36
 
36
37
  ##
@@ -47,11 +48,13 @@ module RubyLint
47
48
  #
48
49
  def attributes
49
50
  return {
50
- :level => level,
51
- :message => message,
52
- :line => line,
53
- :column => column,
54
- :file => file
51
+ :level => level,
52
+ :message => message,
53
+ :line => line,
54
+ :column => column,
55
+ :file => file,
56
+ :filename => filename,
57
+ :node => node
55
58
  }
56
59
  end
57
60
 
@@ -14,7 +14,7 @@ module RubyLint
14
14
  # @param [RubyLint::Configuration] configuration
15
15
  #
16
16
  def initialize(configuration)
17
- @configuration = configuration
17
+ @configuration = configuration
18
18
  end
19
19
 
20
20
  ##
@@ -39,13 +39,7 @@ module RubyLint
39
39
  end
40
40
 
41
41
  files.each do |file|
42
- code = File.read(file)
43
- ast = parser.parse(code, file)
44
- vm = RubyLint::VirtualMachine.new
45
-
46
- vm.run(ast)
47
-
48
- run_analysis(ast, vm, report)
42
+ analyze_file(file, parser, report)
49
43
  end
50
44
 
51
45
  return presenter.present(report)
@@ -53,15 +47,102 @@ module RubyLint
53
47
 
54
48
  private
55
49
 
50
+ ##
51
+ # @param [String] file
52
+ # @param [RubyLint::Parser] parser
53
+ # @param [RubyLint::Report] report
54
+ #
55
+ def analyze_file(file, parser, report)
56
+ ast, comments = parse_file(parser, file)
57
+
58
+ extra_ast, extra_comments = process_external_files(ast)
59
+
60
+ extra_ast.push(ast)
61
+
62
+ comments.merge!(extra_comments)
63
+
64
+ autoload_constants(extra_ast)
65
+
66
+ vm = run_vm(extra_ast, comments)
67
+
68
+ run_analysis(ast, vm, report)
69
+ end
70
+
71
+ ##
72
+ # Parses the given file and returns an Array containing all the associated
73
+ # AST nodes and comments.
74
+ #
75
+ # @param [RubyLint::Parser] parser
76
+ # @param [String] file
77
+ # @return [Array]
78
+ #
79
+ def parse_file(parser, file)
80
+ return parser.parse(File.read(file), file)
81
+ end
82
+
83
+ ##
84
+ # Automatically loads definitions using {RubyLint::ConstantLoader}.
85
+ #
86
+ # @param [Array] nodes
87
+ #
88
+ def autoload_constants(nodes)
89
+ nodes.each { |node| GlobalScope.constant_loader.iterate(node) }
90
+ end
91
+
92
+ ##
93
+ # Processes external Ruby files using {RubyLint::FileLoader}. The return
94
+ # value is a collection of AST nodes and a Hash containing all the
95
+ # associated comments.
96
+ #
97
+ # @param [RubyLint::AST::Node] root_ast
98
+ # @return [Array]
99
+ #
100
+ def process_external_files(root_ast)
101
+ loader = FileLoader.new(
102
+ :directories => configuration.directories,
103
+ :ignore_paths => configuration.ignore_paths,
104
+ :debug => configuration.debug
105
+ )
106
+
107
+ nodes = []
108
+ comments = {}
109
+
110
+ loader.iterate(root_ast)
111
+
112
+ loader.nodes.each do |(ast, cmts)|
113
+ nodes << ast
114
+
115
+ comments.merge!(cmts)
116
+ end
117
+
118
+ return nodes, comments
119
+ end
120
+
56
121
  ##
57
122
  # @param [Parser::Diagnostic] diagnostic
58
123
  # @param [RubyLint::Report] report
59
124
  #
60
125
  def report_diagnostic(diagnostic, report)
61
- loc = diagnostic.location
62
- buffer = loc.source_buffer
126
+ report.add(
127
+ :level => :error,
128
+ :message => diagnostic.message,
129
+ :line => diagnostic.location.line,
130
+ :column => diagnostic.location.column,
131
+ :file => diagnostic.location.source_buffer.name
132
+ )
133
+ end
134
+
135
+ ##
136
+ # @param [Array] nodes
137
+ # @param [Hash] comments
138
+ # @return [RubyLint::VirtualMachine]
139
+ #
140
+ def run_vm(nodes, comments)
141
+ vm = RubyLint::VirtualMachine.new(:comments => comments)
142
+
143
+ vm.run(nodes)
63
144
 
64
- report.error(diagnostic.message, loc.line, loc.column, buffer.name)
145
+ return vm
65
146
  end
66
147
 
67
148
  ##
@@ -5,9 +5,9 @@
5
5
  # Platform: <%= RUBY_ENGINE %> <%= Rubinius::VERSION rescue RUBY_VERSION %>
6
6
 
7
7
  <% @constants.each do |constant| %>
8
- RubyLint::VirtualMachine.global_scope.define_constant('<%= constant.name %>') do |klass|
8
+ RubyLint::GlobalScope.definitions.define_constant('<%= constant.name %>') do |klass|
9
9
  <%- if constant.superclass -%>
10
- klass.inherits(RubyLint::VirtualMachine.constant_proxy('<%= constant.superclass %>'))
10
+ klass.inherits(RubyLint::GlobalScope.constant_proxy('<%= constant.superclass %>'))
11
11
  <%- end -%>
12
12
 
13
13
  <%- constant.methods.each do |type, collection| -%>
@@ -4,20 +4,14 @@ module RubyLint
4
4
  # types.
5
5
  #
6
6
  module VariablePredicates
7
- ##
8
- # Array containing various Ruby types that are considered to be scalar
9
- # values.
10
- #
11
- # @return [Array]
12
- #
13
- SCALAR_TYPES = [:int, :float, :str, :sym]
14
-
15
7
  ##
16
8
  # Array containing various predicate methods to create.
17
9
  #
18
10
  # @return [Array]
19
11
  #
20
- PREDICATE_METHODS = [:array, :class, :const, :hash, :module, :self, :block]
12
+ PREDICATE_METHODS = [
13
+ :array, :class, :const, :hash, :module, :self, :block, :gvar
14
+ ]
21
15
 
22
16
  ##
23
17
  # Hash containing various Node types and the associated Ruby classes.
@@ -34,7 +28,10 @@ module RubyLint
34
28
  :hash => 'Hash',
35
29
  :irange => 'Range',
36
30
  :erange => 'Range',
37
- :lambda => 'Proc'
31
+ :lambda => 'Proc',
32
+ :true => 'TrueClass',
33
+ :false => 'FalseClass',
34
+ :nil => 'NilClass'
38
35
  }
39
36
 
40
37
  PREDICATE_METHODS.each do |type|
@@ -1,3 +1,3 @@
1
1
  module RubyLint
2
- VERSION = '0.0.4'
2
+ VERSION = '0.0.5'
3
3
  end # RubyLint
@@ -42,38 +42,44 @@ module RubyLint
42
42
  # {RubyLint::VirtualMachine#associations} with the keys set to the nodes and
43
43
  # the values to the corresponding definitions.
44
44
  #
45
+ # ## Options
46
+ #
47
+ # The following extra options can be set in the constructor:
48
+ #
49
+ # * `:comments`: a Hash containing the comments for various AST nodes.
50
+ #
45
51
  # @!attribute [r] associations
46
52
  # @return [Hash]
53
+ #
54
+ # @!attribute [r] comments
55
+ # @return [Hash]
56
+ #
47
57
  # @!attribute [r] definitions
48
58
  # @return [RubyLint::Definition::RubyObject]
59
+ #
60
+ # @!attribute [r] extra_definitions
61
+ # @return [Array]
62
+ #
49
63
  # @!attribute [r] value_stack
50
64
  # @return [RubyLint::NestedStack]
65
+ #
51
66
  # @!attribute [r] variable_stack
52
67
  # @return [RubyLint::NestedStack]
53
68
  #
69
+ # @!attribute [r] docstring_tags
70
+ # @return [RubyLint::Docstring::Mapping]
71
+ #
54
72
  class VirtualMachine < Iterator
55
73
  include Helper::ConstantPaths
56
74
 
57
- attr_reader :associations, :definitions, :value_stack, :variable_stack
58
-
59
- private :value_stack, :variable_stack
75
+ attr_reader :associations,
76
+ :comments,
77
+ :definitions,
78
+ :docstring_tags,
79
+ :value_stack,
80
+ :variable_stack
60
81
 
61
- ##
62
- # Hash containing the definition types to copy when including/extending a
63
- # module.
64
- #
65
- # @return [Hash]
66
- #
67
- INCLUDE_CALLS = {
68
- 'include' => {
69
- :const => :const,
70
- :instance_method => :instance_method
71
- },
72
- 'extend' => {
73
- :const => :const,
74
- :instance_method => :method
75
- }
76
- }
82
+ private :value_stack, :variable_stack, :docstring_tags
77
83
 
78
84
  ##
79
85
  # Hash containing variable assignment types and the corresponding variable
@@ -93,24 +99,32 @@ module RubyLint
93
99
  #
94
100
  # @return [Array]
95
101
  #
96
- PRIMITIVES = [:int, :float, :str, :sym]
102
+ PRIMITIVES = [:int, :float, :str, :sym, :true, :false, :nil]
97
103
 
98
104
  ##
99
- # Remaps the names for `on_send` callback nodes in cases where the original
100
- # name of a method could not be used. For example, `on_send_[]=` is
101
- # considered to be invalid syntax and thus its mapped to
102
- # `on_send_assign_member`.
105
+ # Returns a Hash containing the method call evaluators to use for `(send)`
106
+ # nodes.
103
107
  #
104
108
  # @return [Hash]
105
109
  #
106
- SEND_MAPPING = {'[]=' => 'assign_member'}
110
+ SEND_MAPPING = {
111
+ '[]=' => MethodCall::AssignMember,
112
+ 'include' => MethodCall::Include,
113
+ 'extend' => MethodCall::Include,
114
+ 'alias_method' => MethodCall::Alias,
115
+ 'attr' => MethodCall::Attribute,
116
+ 'attr_reader' => MethodCall::Attribute,
117
+ 'attr_writer' => MethodCall::Attribute,
118
+ 'attr_accessor' => MethodCall::Attribute,
119
+ 'define_method' => MethodCall::DefineMethod
120
+ }
107
121
 
108
122
  ##
109
123
  # Array containing the various argument types of method definitions.
110
124
  #
111
125
  # @return [Array]
112
126
  #
113
- ARGUMENT_TYPES = [:arg, :optarg, :restarg, :blockarg]
127
+ ARGUMENT_TYPES = [:arg, :optarg, :restarg, :blockarg, :kwoptarg]
114
128
 
115
129
  ##
116
130
  # The types of variables to export outside of a method definition.
@@ -119,13 +133,6 @@ module RubyLint
119
133
  #
120
134
  EXPORT_VARIABLES = [:ivar, :cvar, :const]
121
135
 
122
- ##
123
- # Array containing the directories to use for looking up definition files.
124
- #
125
- # @return [Array]
126
- #
127
- LOAD_PATH = [File.expand_path('../definitions/core', __FILE__)]
128
-
129
136
  ##
130
137
  # The available method visibilities.
131
138
  #
@@ -133,78 +140,34 @@ module RubyLint
133
140
  #
134
141
  VISIBILITIES = [:public, :protected, :private].freeze
135
142
 
136
- ##
137
- # @return [RubyLint::Definition::RubyObject]
138
- #
139
- def self.global_scope
140
- return @global_scope ||= Definition::RubyObject.new(
141
- :name => 'global',
142
- :type => :global
143
- )
144
- end
145
-
146
- ##
147
- # Looks up the given constant in the global scope. If it does not exist
148
- # this method will try to load it from one of the existing definitions.
149
- #
150
- # @param [String] name
151
- # @return [RubyLint::Definition::RubyObject]
152
- #
153
- def self.global_constant(name)
154
- found = global_scope.lookup_constant_path(name)
155
-
156
- if !found and !constant_loader.loaded?(name)
157
- constant_loader.load_constant(name)
158
-
159
- found = global_scope.lookup_constant_path(name)
160
- end
161
-
162
- return found
163
- end
164
-
165
- ##
166
- # Creates a new proxy for a global constant.
167
- #
168
- # @param [String] name The name of the constant, can include an entire
169
- # constant path in the form of `Foo::Bar`.
170
- # @return [RubyLint::Definition::ConstantProxy]
171
- #
172
- def self.constant_proxy(name)
173
- return Definition::ConstantProxy.new(global_scope, name)
174
- end
175
-
176
- ##
177
- # @return [RubyLint::ConstantLoader]
178
- #
179
- def self.constant_loader
180
- return @constant_loader ||= ConstantLoader.new
181
- end
182
-
183
143
  ##
184
144
  # Called after a new instance of the virtual machine has been created.
185
145
  #
186
146
  def after_initialize
187
- @associations = {}
188
- @definitions = initial_definitions
189
- @scopes = [@definitions]
190
- @in_sclass = false
191
- @value_stack = NestedStack.new
192
- @variable_stack = NestedStack.new
193
- @ignored_nodes = []
194
- @visibility = :public
147
+ @comments ||= {}
148
+
149
+ @associations = {}
150
+ @definitions = initial_definitions
151
+ @scopes = [@definitions]
152
+ @value_stack = NestedStack.new
153
+ @variable_stack = NestedStack.new
154
+ @ignored_nodes = []
155
+ @visibility = :public
195
156
 
157
+ reset_docstring_tags
196
158
  reset_method_type
197
159
  end
198
160
 
199
161
  ##
200
- # Processes the given AST. Constants are autoloaded first.
162
+ # Processes the given AST or a collection of AST nodes.
201
163
  #
202
164
  # @see #iterate
165
+ # @param [Array|RubyLint::AST::Node] ast
203
166
  #
204
167
  def run(ast)
205
- self.class.constant_loader.iterate(ast)
168
+ ast = [ast] unless ast.is_a?(Array)
206
169
 
207
- iterate(ast)
170
+ ast.each { |node| iterate(node) }
208
171
 
209
172
  freeze
210
173
  end
@@ -213,11 +176,11 @@ module RubyLint
213
176
  # Freezes the VM along with all the instance variables.
214
177
  #
215
178
  def freeze
216
- super
179
+ @associations.freeze
180
+ @definitions.freeze
181
+ @scopes.freeze
217
182
 
218
- instance_variables.each do |var|
219
- instance_variable_get(var).freeze
220
- end
183
+ super
221
184
  end
222
185
 
223
186
  ##
@@ -309,7 +272,7 @@ module RubyLint
309
272
  def after_masgn(node)
310
273
  variables = variable_stack.pop
311
274
  values = value_stack.pop.first
312
- values = values ? values.value : []
275
+ values = values && values.value ? values.value : []
313
276
 
314
277
  variables.each_with_index do |variable, index|
315
278
  variable.value = values[index].value if values[index]
@@ -374,12 +337,27 @@ module RubyLint
374
337
  end
375
338
  end
376
339
 
340
+ ##
341
+ # Called whenever a magic regexp global variable is referenced (e.g. `$1`).
342
+ #
343
+ # @param [RubyLint::AST::Node] node
344
+ #
345
+ def on_nth_ref(node)
346
+ var = definitions.lookup(:gvar, "$#{node.children[0]}")
347
+
348
+ push_value(var.value)
349
+ end
350
+
377
351
  ##
378
352
  # @param [RubyLint::AST::Node] node
379
353
  #
380
354
  def on_const(node)
381
355
  increment_reference_amount(node)
382
356
  push_variable_value(node)
357
+
358
+ # The root node is also used in such a way that it processes child (=
359
+ # receiver) constants.
360
+ skip_child_nodes!(node)
383
361
  end
384
362
 
385
363
  ##
@@ -488,7 +466,7 @@ module RubyLint
488
466
  parent = evaluate_node(parent_node)
489
467
 
490
468
  if !parent or !parent.const?
491
- raise TypeError, 'classes can only inherit another class'
469
+ parent = current_scope.lookup(:const, 'Object')
492
470
  end
493
471
  end
494
472
 
@@ -576,6 +554,15 @@ module RubyLint
576
554
 
577
555
  associate_node(node, definition)
578
556
 
557
+ buffer_docstring_tags(node)
558
+
559
+ if docstring_tags and docstring_tags.return_tag
560
+ assign_return_value_from_tag(
561
+ docstring_tags.return_tag,
562
+ definition
563
+ )
564
+ end
565
+
579
566
  push_scope(definition)
580
567
  end
581
568
 
@@ -588,29 +575,13 @@ module RubyLint
588
575
  previous = pop_scope
589
576
  current = current_scope
590
577
 
578
+ reset_docstring_tags
579
+
591
580
  EXPORT_VARIABLES.each do |type|
592
581
  current.copy(previous, type)
593
582
  end
594
583
  end
595
584
 
596
- ##
597
- # @param [RubyLint::AST::Node] node
598
- #
599
- def on_args(node)
600
- variable_stack.add_stack
601
- end
602
-
603
- ##
604
- # @param [RubyLint::AST::Node] node
605
- #
606
- def after_args(node)
607
- variables = variable_stack.pop
608
-
609
- variables.each do |variable|
610
- current_scope.add_definition(variable)
611
- end
612
- end
613
-
614
585
  # Creates callbacks for various argument types such as :arg and :optarg.
615
586
  ARGUMENT_TYPES.each do |type|
616
587
  define_method("on_#{type}") do |node|
@@ -620,16 +591,19 @@ module RubyLint
620
591
  define_method("after_#{type}") do |node|
621
592
  value = value_stack.pop.first
622
593
  name = node.children[0].to_s
623
- arg = Definition::RubyObject.new(
624
- :type => type,
594
+ var = Definition::RubyObject.new(
595
+ :type => :lvar,
625
596
  :name => name,
626
597
  :value => value,
627
598
  :instance_type => :instance
628
599
  )
629
600
 
630
- current_scope.add_definition(arg)
601
+ if docstring_tags and docstring_tags.param_tags[name]
602
+ update_parents_from_tag(docstring_tags.param_tags[name], var)
603
+ end
631
604
 
632
- assign_variable(:lvar, name, value)
605
+ current_scope.add(type, name, var)
606
+ current_scope.add_definition(var)
633
607
  end
634
608
  end
635
609
 
@@ -659,65 +633,64 @@ module RubyLint
659
633
  receiver, name, _ = *node
660
634
 
661
635
  name = name.to_s
662
- mapped_name = SEND_MAPPING.fetch(name, name)
663
- callback = "after_send_#{mapped_name}"
636
+ args_length = node.children[2..-1].length
637
+ values = value_stack.pop
638
+ arguments = values.pop(args_length)
639
+ block = nil
640
+
641
+ receiver_definition = values.first
642
+
643
+ if arguments.length != args_length
644
+ raise <<-EOF
645
+ Not enough argument definitions for #{node.inspect_oneline}.
646
+ Location: #{node.file} on line #{node.line}, column #{node.column}
647
+ Expected: #{args_length}
648
+ Received: #{arguments.length}
649
+ EOF
650
+ end
664
651
 
665
- execute_callback(callback, node)
652
+ # If the receiver doesn't exist there's no point in associating a context
653
+ # with it.
654
+ if receiver and !receiver_definition
655
+ push_unknown_value
666
656
 
667
- receiver_and_args = value_stack.pop
657
+ return
658
+ end
668
659
 
669
- if receiver
670
- context = receiver_and_args.shift
660
+ if receiver and receiver_definition
661
+ context = receiver_definition
671
662
  else
672
663
  context = current_scope
673
664
 
674
665
  # `parser` wraps (block) nodes around (send) calls which is a bit
675
666
  # inconvenient
676
- context = previous_scope if context.block?
667
+ if context.block?
668
+ block = context
669
+ context = previous_scope
670
+ end
671
+ end
672
+
673
+ if SEND_MAPPING[name]
674
+ evaluator = SEND_MAPPING[name].new(node, self)
675
+
676
+ evaluator.evaluate(arguments, context, block)
677
677
  end
678
678
 
679
679
  # Associate the receiver node with the context so that it becomes
680
680
  # easier to retrieve later on.
681
- if receiver && context
681
+ if receiver and context
682
682
  associate_node(receiver, context)
683
683
  end
684
684
 
685
685
  if context and context.method_defined?(name)
686
686
  retval = context.call_method(name)
687
687
 
688
- push_value(retval)
689
- end
690
- end
691
-
692
- ##
693
- # @param [RubyLint::AST::Node] node
694
- #
695
- def on_send_include(node)
696
- value_stack.add_stack
697
- end
698
-
699
- ##
700
- # Processes a `include` method call.
701
- #
702
- # @param [RubyLint::AST::Node] node
703
- #
704
- def after_send_include(node)
705
- copy_types = INCLUDE_CALLS[node.children[1].to_s]
706
- scope = current_scope
707
- arguments = value_stack.pop
708
-
709
- arguments.each do |source|
710
- copy_types.each do |from, to|
711
- source.list(from).each do |definition|
712
- scope.add(to, definition.name, definition)
713
- end
714
- end
688
+ retval ? push_value(retval) : push_unknown_value
689
+ else
690
+ push_unknown_value
715
691
  end
716
692
  end
717
693
 
718
- alias_method :on_send_extend, :on_send_include
719
- alias_method :after_send_extend, :after_send_include
720
-
721
694
  VISIBILITIES.each do |vis|
722
695
  define_method("on_send_#{vis}") do |node|
723
696
  @visibility = vis
@@ -727,34 +700,26 @@ module RubyLint
727
700
  ##
728
701
  # @param [RubyLint::AST::Node] node
729
702
  #
730
- def on_send_assign_member(node)
703
+ def on_alias(node)
731
704
  value_stack.add_stack
732
705
  end
733
706
 
734
707
  ##
735
- # Processes the assignment of an object member (array index or hash key).
708
+ # Processes calls to `alias`. Two types of data can be aliased:
736
709
  #
737
- # @param [RubyLint::AST::Node] node
710
+ # 1. Methods (using the syntax `alias ALIAS SOURCE`)
711
+ # 2. Global variables
738
712
  #
739
- def after_send_assign_member(node)
740
- array, *indexes, values = value_stack.pop
741
- index_values = []
742
-
743
- if values and values.array?
744
- index_values = values.list(:member).map(&:value)
745
- elsif values
746
- index_values = [values]
747
- end
748
-
749
- indexes.each do |index|
750
- member = Definition::RubyObject.new(
751
- :name => index.value.to_s,
752
- :type => :member,
753
- :value => index_values.shift
754
- )
713
+ # This method dispatches the alias process to two possible methods:
714
+ #
715
+ # * on_alias_sym: aliasing methods (using symbols)
716
+ # * on_alias_gvar: aliasing global variables
717
+ #
718
+ def after_alias(node)
719
+ arguments = value_stack.pop
720
+ evaluator = MethodCall::Alias.new(node, self)
755
721
 
756
- array.add_definition(member)
757
- end
722
+ evaluator.evaluate(arguments, current_scope)
758
723
  end
759
724
 
760
725
  private
@@ -768,12 +733,10 @@ module RubyLint
768
733
  definitions = Definition::RubyObject.new(
769
734
  :name => 'root',
770
735
  :type => :root,
771
- :parents => [RubyLint::VirtualMachine.global_constant('Kernel')],
736
+ :parents => [GlobalScope.definitions],
772
737
  :instance_type => :instance
773
738
  )
774
739
 
775
- definitions.merge(RubyLint::VirtualMachine.global_scope)
776
-
777
740
  definitions.add(:keyword, 'self', definitions)
778
741
 
779
742
  return definitions
@@ -783,20 +746,22 @@ module RubyLint
783
746
  # Defines a new module/class based on the supplied node.
784
747
  #
785
748
  # @param [RubyLint::Node] node
786
- # @param [Class] definition_builder
749
+ # @param [RubyLint::DefinitionBuilder::Base] definition_builder
787
750
  # @param [Hash] options
788
751
  #
789
752
  def define_module(node, definition_builder, options = {})
790
753
  builder = definition_builder.new(node, current_scope, options)
791
754
  definition = builder.build
792
755
  scope = builder.scope
793
- existing = scope.lookup(definition.type, definition.name)
756
+ existing = scope.lookup(definition.type, definition.name, false)
794
757
 
795
758
  if existing
796
759
  definition = existing
797
760
 
798
761
  inherit_definition(definition, current_scope)
799
762
  else
763
+ definition.add_definition(definition)
764
+
800
765
  scope.add_definition(definition)
801
766
  end
802
767
 
@@ -881,6 +846,13 @@ module RubyLint
881
846
  value_stack.push(definition) if definition && !value_stack.empty?
882
847
  end
883
848
 
849
+ ##
850
+ # Pushes an unknown value object onto the value stack.
851
+ #
852
+ def push_unknown_value
853
+ push_value(Definition::RubyObject.create_unknown)
854
+ end
855
+
884
856
  ##
885
857
  # Adds a new variable and value stack.
886
858
  #
@@ -897,11 +869,14 @@ module RubyLint
897
869
  # @param [RubyLint::Definition::RubyObject] value
898
870
  #
899
871
  def assign_variable(type, name, value)
900
- variable = Definition::RubyObject.new(
901
- :type => type,
902
- :name => name,
903
- :value => value,
904
- :instance_type => :instance
872
+ existing = current_scope.lookup(type, name)
873
+ ref_amount = existing ? existing.reference_amount + 1 : 0
874
+ variable = Definition::RubyObject.new(
875
+ :type => type,
876
+ :name => name,
877
+ :value => value,
878
+ :instance_type => :instance,
879
+ :reference_amount => ref_amount
905
880
  )
906
881
 
907
882
  buffer_assignment_value(variable.value)
@@ -975,6 +950,8 @@ module RubyLint
975
950
  # will be overwritten.
976
951
  #
977
952
  def conditional_assignment(variable, value, bool = true)
953
+ variable.reference_amount += 1
954
+
978
955
  if current_scope.has_definition?(variable.type, variable.name) == bool
979
956
  variable.value = value
980
957
 
@@ -997,6 +974,8 @@ module RubyLint
997
974
  definition = current_scope.lookup(node.type, node.name)
998
975
  end
999
976
 
977
+ definition = Definition::RubyObject.create_unknown unless definition
978
+
1000
979
  return definition
1001
980
  end
1002
981
 
@@ -1040,5 +1019,103 @@ module RubyLint
1040
1019
  definition.parents << inherit
1041
1020
  end
1042
1021
  end
1022
+
1023
+ ##
1024
+ # Extracts all the docstring tags from the documentation of the given
1025
+ # node, retrieves the corresponding types and stores them for later use.
1026
+ #
1027
+ # @param [RubyLint::AST::Node] node
1028
+ #
1029
+ def buffer_docstring_tags(node)
1030
+ return unless comments[node]
1031
+
1032
+ parser = Docstring::Parser.new
1033
+ tags = parser.parse(comments[node].map(&:text))
1034
+
1035
+ @docstring_tags = Docstring::Mapping.new(tags)
1036
+ end
1037
+
1038
+ ##
1039
+ # Resets the docstring tags collection back to its initial value.
1040
+ #
1041
+ def reset_docstring_tags
1042
+ @docstring_tags = nil
1043
+ end
1044
+
1045
+ ##
1046
+ # Updates the parents of a definition according to the types of a `@param`
1047
+ # tag.
1048
+ #
1049
+ # @param [RubyLint::Docstring::ParamTag] tag
1050
+ # @param [RubyLint::Definition::RubyObject] definition
1051
+ #
1052
+ def update_parents_from_tag(tag, definition)
1053
+ extra_parents = definitions_for_types(tag.types)
1054
+
1055
+ definition.parents.concat(extra_parents)
1056
+ end
1057
+
1058
+ ##
1059
+ # Creates an "unknown" definition with the given method in it.
1060
+ #
1061
+ # @param [String] name The name of the method to add.
1062
+ # @return [RubyLint::Definition::RubyObject]
1063
+ #
1064
+ def create_unknown_with_method(name)
1065
+ definition = Definition::RubyObject.create_unknown
1066
+
1067
+ definition.send("define_#{@method_type}", name)
1068
+
1069
+ return definition
1070
+ end
1071
+
1072
+ ##
1073
+ # Returns a collection of definitions for a set of YARD types.
1074
+ #
1075
+ # @param [Array] types
1076
+ # @return [Array]
1077
+ #
1078
+ def definitions_for_types(types)
1079
+ definitions = []
1080
+
1081
+ # There are basically two type signatures: either the name(s) of a
1082
+ # constant or a method in the form of `#method_name`.
1083
+ types.each do |type|
1084
+ if type[0] == '#'
1085
+ found = create_unknown_with_method(type[1..-1])
1086
+ else
1087
+ found = lookup_type_definition(type)
1088
+ end
1089
+
1090
+ definitions << found if found
1091
+ end
1092
+
1093
+ return definitions
1094
+ end
1095
+
1096
+ ##
1097
+ # Tries to look up the given type/constant in the current scope and falls
1098
+ # back to the global scope if it couldn't be found in the former.
1099
+ #
1100
+ # @param [String] name
1101
+ # @return [RubyLint::Definition::RubyObject]
1102
+ #
1103
+ def lookup_type_definition(name)
1104
+ return current_scope.lookup(:const, name) ||
1105
+ GlobalScope.global_constant(name)
1106
+ end
1107
+
1108
+ ##
1109
+ # @param [RubyLint::Docstring::ReturnTag] tag
1110
+ # @param [RubyLint::Definition::RubyMethod] definition
1111
+ #
1112
+ def assign_return_value_from_tag(tag, definition)
1113
+ definitions = definitions_for_types(tag.types)
1114
+
1115
+ # THINK: currently ruby-lint assumes methods always return a single type
1116
+ # but YARD allows you to specify multiple ones. For now we'll take the
1117
+ # first one but there should be a nicer way to do this.
1118
+ definition.returns(definitions[0]) if definitions[0]
1119
+ end
1043
1120
  end # VirtualMachine
1044
1121
  end # RubyLint