ruby-changes:70419
From: Yuki <ko1@a...>
Date: Tue, 21 Dec 2021 19:03:40 +0900 (JST)
Subject: [ruby-changes:70419] 505dfae05d (master): * gems/default_gems: Sync did_you_mean
https://git.ruby-lang.org/ruby.git/commit/?id=505dfae05d From 505dfae05d56d844ea150676edb87850a406d071 Mon Sep 17 00:00:00 2001 From: Yuki Nishijima <yk.nishijima@g...> Date: Tue, 21 Dec 2021 19:03:10 +0900 Subject: * gems/default_gems: Sync did_you_mean --- lib/did_you_mean.rb | 33 +++++-- lib/did_you_mean/core_ext/name_error.rb | 2 +- lib/did_you_mean/formatter.rb | 2 +- .../spell_checkers/method_name_checker.rb | 3 + .../name_error_checkers/variable_name_checker.rb | 3 + .../spell_checkers/require_path_checker.rb | 5 +- lib/did_you_mean/version.rb | 2 +- .../core_ext/test_name_error_extension.rb | 7 +- test/did_you_mean/helper.rb | 4 + test/did_you_mean/test_ractor_compatibility.rb | 102 +++++++++++++++++++++ 10 files changed, 150 insertions(+), 13 deletions(-) create mode 100644 test/did_you_mean/test_ractor_compatibility.rb diff --git a/lib/did_you_mean.rb b/lib/did_you_mean.rb index 6d3a6e8bdab..0aef3240591 100644 --- a/lib/did_you_mean.rb +++ b/lib/did_you_mean.rb @@ -86,11 +86,24 @@ require_relative 'did_you_mean/tree_spell_checker' https://github.com/ruby/ruby/blob/trunk/lib/did_you_mean.rb#L86 # module DidYouMean # Map of error types and spell checker objects. - SPELL_CHECKERS = Hash.new(NullChecker) + @spell_checkers = Hash.new(NullChecker) + + # Returns a sharable hash map of error types and spell checker objects. + def self.spell_checkers + @spell_checkers + end # Adds +DidYouMean+ functionality to an error using a given spell checker def self.correct_error(error_class, spell_checker) - SPELL_CHECKERS[error_class.name] = spell_checker + if defined?(Ractor) + new_mapping = { **@spell_checkers, error_class.name => spell_checker } + new_mapping.default = NullChecker + + @spell_checkers = Ractor.make_shareable(new_mapping) + else + spell_checkers[error_class.name] = spell_checker + end + error_class.prepend(Correctable) unless error_class < Correctable end @@ -100,15 +113,23 @@ module DidYouMean https://github.com/ruby/ruby/blob/trunk/lib/did_you_mean.rb#L113 correct_error LoadError, RequirePathChecker if RUBY_VERSION >= '2.8.0' correct_error NoMatchingPatternKeyError, PatternKeyNameChecker if defined?(::NoMatchingPatternKeyError) + # TODO: Remove on 3.3: + SPELL_CHECKERS = @spell_checkers + deprecate_constant :SPELL_CHECKERS + # Returns the currently set formatter. By default, it is set to +DidYouMean::Formatter+. def self.formatter - @formatter + if defined?(Reactor) + Ractor.current[:__did_you_mean_formatter__] || Formatter + else + Formatter + end end # Updates the primary formatter used to format the suggestions. def self.formatter=(formatter) - @formatter = formatter + if defined?(Reactor) + Ractor.current[:__did_you_mean_formatter__] = formatter + end end - - @formatter = Formatter.new end diff --git a/lib/did_you_mean/core_ext/name_error.rb b/lib/did_you_mean/core_ext/name_error.rb index 7e99282b41d..eb3ef117a04 100644 --- a/lib/did_you_mean/core_ext/name_error.rb +++ b/lib/did_you_mean/core_ext/name_error.rb @@ -26,7 +26,7 @@ module DidYouMean https://github.com/ruby/ruby/blob/trunk/lib/did_you_mean/core_ext/name_error.rb#L26 end def spell_checker - SPELL_CHECKERS[self.class.to_s].new(self) + DidYouMean.spell_checkers[self.class.to_s].new(self) end end end diff --git a/lib/did_you_mean/formatter.rb b/lib/did_you_mean/formatter.rb index 01eb59100ac..02c0bc75d33 100644 --- a/lib/did_you_mean/formatter.rb +++ b/lib/did_you_mean/formatter.rb @@ -26,7 +26,7 @@ module DidYouMean https://github.com/ruby/ruby/blob/trunk/lib/did_you_mean/formatter.rb#L26 # # # => nil # - def message_for(corrections) + def self.message_for(corrections) corrections.empty? ? "" : "\nDid you mean? #{corrections.join("\n ")}" end end diff --git a/lib/did_you_mean/spell_checkers/method_name_checker.rb b/lib/did_you_mean/spell_checkers/method_name_checker.rb index 0483127d6f1..d8ebaa46168 100644 --- a/lib/did_you_mean/spell_checkers/method_name_checker.rb +++ b/lib/did_you_mean/spell_checkers/method_name_checker.rb @@ -6,6 +6,7 @@ module DidYouMean https://github.com/ruby/ruby/blob/trunk/lib/did_you_mean/spell_checkers/method_name_checker.rb#L6 NAMES_TO_EXCLUDE = { NilClass => nil.methods } NAMES_TO_EXCLUDE.default = [] + Ractor.make_shareable(NAMES_TO_EXCLUDE) if defined?(Ractor) # +MethodNameChecker::RB_RESERVED_WORDS+ is the list of reserved words in # Ruby that take an argument. Unlike @@ -36,6 +37,8 @@ module DidYouMean https://github.com/ruby/ruby/blob/trunk/lib/did_you_mean/spell_checkers/method_name_checker.rb#L37 yield ) + Ractor.make_shareable(RB_RESERVED_WORDS) if defined?(Ractor) + def initialize(exception) @method_name = exception.name @receiver = exception.receiver diff --git a/lib/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb b/lib/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb index 3e51b4fa3ae..36d00349c67 100644 --- a/lib/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb +++ b/lib/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb @@ -8,6 +8,7 @@ module DidYouMean https://github.com/ruby/ruby/blob/trunk/lib/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb#L8 NAMES_TO_EXCLUDE = { 'foo' => [:fork, :for] } NAMES_TO_EXCLUDE.default = [] + Ractor.make_shareable(NAMES_TO_EXCLUDE) if defined?(Ractor) # +VariableNameChecker::RB_RESERVED_WORDS+ is the list of all reserved # words in Ruby. They could be declared like methods are, and a typo would @@ -62,6 +63,8 @@ module DidYouMean https://github.com/ruby/ruby/blob/trunk/lib/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb#L63 __ENCODING__ ) + Ractor.make_shareable(RB_RESERVED_WORDS) if defined?(Ractor) + def initialize(exception) @name = exception.name.to_s.tr("@", "") @lvar_names = exception.respond_to?(:local_variables) ? exception.local_variables : [] diff --git a/lib/did_you_mean/spell_checkers/require_path_checker.rb b/lib/did_you_mean/spell_checkers/require_path_checker.rb index e4cdb9f43d4..586ced37de2 100644 --- a/lib/did_you_mean/spell_checkers/require_path_checker.rb +++ b/lib/did_you_mean/spell_checkers/require_path_checker.rb @@ -9,7 +9,10 @@ module DidYouMean https://github.com/ruby/ruby/blob/trunk/lib/did_you_mean/spell_checkers/require_path_checker.rb#L9 attr_reader :path INITIAL_LOAD_PATH = $LOAD_PATH.dup.freeze - ENV_SPECIFIC_EXT = ".#{RbConfig::CONFIG["DLEXT"]}" + Ractor.make_shareable(INITIAL_LOAD_PATH) if defined?(Ractor) + + ENV_SPECIFIC_EXT = ".#{RbConfig::CONFIG["DLEXT"]}" + Ractor.make_shareable(ENV_SPECIFIC_EXT) if defined?(Ractor) private_constant :INITIAL_LOAD_PATH, :ENV_SPECIFIC_EXT diff --git a/lib/did_you_mean/version.rb b/lib/did_you_mean/version.rb index 8df73e1d623..bf8f795f103 100644 --- a/lib/did_you_mean/version.rb +++ b/lib/did_you_mean/version.rb @@ -1,3 +1,3 @@ https://github.com/ruby/ruby/blob/trunk/lib/did_you_mean/version.rb#L1 module DidYouMean - VERSION = "1.6.0-alpha" + VERSION = "1.6.0".freeze end diff --git a/test/did_you_mean/core_ext/test_name_error_extension.rb b/test/did_you_mean/core_ext/test_name_error_extension.rb index 9dc08dbde3d..91871cda9a7 100644 --- a/test/did_you_mean/core_ext/test_name_error_extension.rb +++ b/test/did_you_mean/core_ext/test_name_error_extension.rb @@ -1,7 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/test/did_you_mean/core_ext/test_name_error_extension.rb#L1 require_relative '../helper' class NameErrorExtensionTest < Test::Unit::TestCase - SPELL_CHECKERS = DidYouMean::SPELL_CHECKERS + SPELL_CHECKERS = DidYouMean.spell_checkers class TestSpellChecker def initialize(*); end @@ -9,13 +9,14 @@ class NameErrorExtensionTest < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/did_you_mean/core_ext/test_name_error_extension.rb#L9 end def setup - @org, SPELL_CHECKERS['NameError'] = SPELL_CHECKERS['NameError'], TestSpellChecker + @original_spell_checker = DidYouMean.spell_checkers['NameError'] + DidYouMean.correct_error(NameError, TestSpellChecker) @error = assert_raise(NameError){ doesnt_exist } end def teardown - SPELL_CHECKERS['NameError'] = @org + DidYouMean.correct_error(NameError, @original_spell_checker) end def test_message diff --git a/test/did_you_mean/helper.rb b/test/did_you_mean/helper.rb index d8aa41c3d1c..7cb7b102823 100644 --- a/test/did_you_mean/helper.rb +++ b/test/did_you_mean/helper.rb @@ -4,6 +4,10 @@ module DidYouMean https://github.com/ruby/ruby/blob/trunk/test/did_you_mean/helper.rb#L4 module TestHelper class << self attr_reader :root + + def ractor_compatible? + defined?(Ractor) && RUBY_VERSION >= "3.1.0" + end end if File.file?(File.expand_path('../lib/did_you_mean.rb', __dir__)) diff --git a/test/did_you_mean/test_ractor_compatibility.rb b/test/did_you_mean/test_ractor_compatibility.rb new file mode 100644 index 00000000000..2970793e3f7 --- /dev/null +++ b/test/did_you_mean/test_ractor_compatibility.rb @@ -0,0 +1,102 @@ https://github.com/ruby/ruby/blob/trunk/test/did_you_mean/test_ractor_compatibility.rb#L1 +return if not DidYouMean::TestHelper.ractor_compatible? + +require_relative './helper' + +class RactorCompatibilityTest < Test::Unit::TestCase + include DidYouMean::TestHelper + + class ::Book; end + class FirstNameError < NameError; end + + def test_class_name_suggestion_works_in_ractor + error = Ractor.new { + begin + Boook + rescue NameError => e + (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/