diff --git a/.rubocop.yml b/.rubocop.yml index 3323c741..4dbeeb33 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -13,6 +13,9 @@ AllCops: Layout/LineLength: Max: 80 +Lint/AmbiguousBlockAssociation: + Enabled: false + Lint/DuplicateBranch: Enabled: false diff --git a/CHANGELOG.md b/CHANGELOG.md index c4558185..dc5dc7d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a ## [Unreleased] +## [4.0.1] - 2022-10-18 + +### Changed + +- [#172](https://github.com/ruby-syntax-tree/syntax_tree/pull/172) - Use a refinement for `Symbol#name` addition so that other runtimes or tools don't get confused by its availability. +- [#173](https://github.com/ruby-syntax-tree/syntax_tree/pull/173) - Fix the `current_environment` usage to use the method instead of the instance variable. +- [#175](https://github.com/ruby-syntax-tree/syntax_tree/pull/175) - Update `prettier_print` requirement since v1.0.0 had a bug with `#breakable_return`. + ## [4.0.0] - 2022-10-17 ### Added diff --git a/Gemfile.lock b/Gemfile.lock index 00ae409b..f55c7768 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,8 +1,8 @@ PATH remote: . specs: - syntax_tree (4.0.0) - prettier_print (>= 1.0.0) + syntax_tree (4.0.1) + prettier_print (>= 1.0.1) GEM remote: https://rubygems.org/ @@ -14,7 +14,7 @@ GEM parallel (1.22.1) parser (3.1.2.1) ast (~> 2.4.1) - prettier_print (1.0.0) + prettier_print (1.0.1) rainbow (3.1.1) rake (13.0.6) regexp_parser (2.6.0) @@ -29,7 +29,7 @@ GEM rubocop-ast (>= 1.20.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.21.0) + rubocop-ast (1.22.0) parser (>= 3.1.1.0) ruby-progressbar (1.11.0) simplecov (0.21.2) diff --git a/lib/syntax_tree.rb b/lib/syntax_tree.rb index 52ec700b..fbd4fcef 100644 --- a/lib/syntax_tree.rb +++ b/lib/syntax_tree.rb @@ -22,16 +22,6 @@ require_relative "syntax_tree/parser" -# We rely on Symbol#name being available, which is only available in Ruby 3.0+. -# In case we're running on an older Ruby version, we polyfill it here. -unless :+.respond_to?(:name) - class Symbol # rubocop:disable Style/Documentation - def name - to_s.freeze - end - end -end - # Syntax Tree is a suite of tools built on top of the internal CRuby parser. It # provides the ability to generate a syntax tree from source, as well as the # tools necessary to inspect and manipulate that syntax tree. It can be used to diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index dcdd0275..5162655e 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -1651,6 +1651,20 @@ def format(q) # array << value # class Binary < Node + # Since Binary's operator is a symbol, it's better to use the `name` method + # than to allocate a new string every time. This is a tiny performance + # optimization, but enough that it shows up in the profiler. Adding this in + # for older Ruby versions. + unless :+.respond_to?(:name) + using Module.new { + refine Symbol do + def name + to_s.freeze + end + end + } + end + # [untyped] the left-hand side of the expression attr_reader :left diff --git a/lib/syntax_tree/version.rb b/lib/syntax_tree/version.rb index 8456abd4..695f4c88 100644 --- a/lib/syntax_tree/version.rb +++ b/lib/syntax_tree/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module SyntaxTree - VERSION = "4.0.0" + VERSION = "4.0.1" end diff --git a/lib/syntax_tree/visitor/with_environment.rb b/lib/syntax_tree/visitor/with_environment.rb index 62e59c98..ad101e0a 100644 --- a/lib/syntax_tree/visitor/with_environment.rb +++ b/lib/syntax_tree/visitor/with_environment.rb @@ -64,19 +64,19 @@ def visit_def_endless(node) # arguments def visit_params(node) node.requireds.each do |param| - @current_environment.add_local_definition(param, :argument) + current_environment.add_local_definition(param, :argument) end node.posts.each do |param| - @current_environment.add_local_definition(param, :argument) + current_environment.add_local_definition(param, :argument) end node.keywords.each do |param| - @current_environment.add_local_definition(param.first, :argument) + current_environment.add_local_definition(param.first, :argument) end node.optionals.each do |param| - @current_environment.add_local_definition(param.first, :argument) + current_environment.add_local_definition(param.first, :argument) end super @@ -84,21 +84,21 @@ def visit_params(node) def visit_rest_param(node) name = node.name - @current_environment.add_local_definition(name, :argument) if name + current_environment.add_local_definition(name, :argument) if name super end def visit_kwrest_param(node) name = node.name - @current_environment.add_local_definition(name, :argument) if name + current_environment.add_local_definition(name, :argument) if name super end def visit_blockarg(node) name = node.name - @current_environment.add_local_definition(name, :argument) if name + current_environment.add_local_definition(name, :argument) if name super end @@ -108,7 +108,7 @@ def visit_var_field(node) value = node.value if value.is_a?(SyntaxTree::Ident) - @current_environment.add_local_definition(value, :variable) + current_environment.add_local_definition(value, :variable) end super @@ -119,7 +119,7 @@ def visit_var_field(node) # Visits for keeping track of variable and argument usages def visit_aref_field(node) name = node.collection.value - @current_environment.add_local_usage(name, :variable) if name + current_environment.add_local_usage(name, :variable) if name super end @@ -128,10 +128,10 @@ def visit_var_ref(node) value = node.value if value.is_a?(SyntaxTree::Ident) - definition = @current_environment.find_local(value.value) + definition = current_environment.find_local(value.value) if definition - @current_environment.add_local_usage(value, definition.type) + current_environment.add_local_usage(value, definition.type) end end diff --git a/syntax_tree.gemspec b/syntax_tree.gemspec index ec7d57ef..fe74c7e7 100644 --- a/syntax_tree.gemspec +++ b/syntax_tree.gemspec @@ -25,7 +25,7 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = %w[lib] - spec.add_dependency "prettier_print", ">= 1.0.0" + spec.add_dependency "prettier_print", ">= 1.0.1" spec.add_development_dependency "bundler" spec.add_development_dependency "minitest" diff --git a/test/visitor_with_environment_test.rb b/test/visitor_with_environment_test.rb index 915b2143..302dbfbe 100644 --- a/test/visitor_with_environment_test.rb +++ b/test/visitor_with_environment_test.rb @@ -406,5 +406,25 @@ def foo(a) assert_equal(2, argument.usages[0].start_line) assert_equal(4, argument.usages[1].start_line) end + + def test_variables_in_the_top_level + tree = SyntaxTree.parse(<<~RUBY) + a = 123 + a + RUBY + + visitor = Collector.new + visitor.visit(tree) + + assert_equal(0, visitor.arguments.length) + assert_equal(1, visitor.variables.length) + + variable = visitor.variables["a"] + assert_equal(1, variable.definitions.length) + assert_equal(1, variable.usages.length) + + assert_equal(1, variable.definitions[0].start_line) + assert_equal(2, variable.usages[0].start_line) + end end end