From 006138a5fe4f472fb5cdf1634cf17ba6a8e84ffb Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Mon, 6 Jun 2022 20:38:10 -0400 Subject: [PATCH 1/2] Move `valid_method_name?` into `RBIHelper` And provide a better implementation. Signed-off-by: Alexandre Terrasa --- lib/tapioca/gem/listeners/methods.rb | 13 +------------ lib/tapioca/helpers/rbi_helper.rb | 6 ++++++ lib/tapioca/rbi_ext/model.rb | 15 +------------- sorbet/rbi/gems/rbi@0.0.14.rbi | 5 ----- spec/tapioca/helpers/rbi_helper_spec.rb | 26 +++++++++++++++++++++++++ 5 files changed, 34 insertions(+), 31 deletions(-) create mode 100644 spec/tapioca/helpers/rbi_helper_spec.rb diff --git a/lib/tapioca/gem/listeners/methods.rb b/lib/tapioca/gem/listeners/methods.rb index cc8cebc9d..938e8a39f 100644 --- a/lib/tapioca/gem/listeners/methods.rb +++ b/lib/tapioca/gem/listeners/methods.rb @@ -7,13 +7,9 @@ module Listeners class Methods < Base extend T::Sig + include RBIHelper include Runtime::Reflection - SPECIAL_METHOD_NAMES = T.let([ - "!", "~", "+@", "**", "-@", "*", "/", "%", "+", "-", "<<", ">>", "&", "|", "^", - "<", "<=", "=>", ">", ">=", "==", "===", "!=", "=~", "!~", "<=>", "[]", "[]=", "`", - ], T::Array[String]) - private sig { override.params(event: ScopeNodeAdded).void } @@ -184,13 +180,6 @@ def struct_method?(constant, method_name) .include?(method_name.gsub(/=$/, "").to_sym) end - sig { params(name: String).returns(T::Boolean) } - def valid_method_name?(name) - return true if SPECIAL_METHOD_NAMES.include?(name) - - !!name.match(/^[[:word:]]+[?!=]?$/) - end - sig { params(name: String).returns(T::Boolean) } def valid_parameter_name?(name) name.match?(/^[[[:alnum:]]_]+$/) diff --git a/lib/tapioca/helpers/rbi_helper.rb b/lib/tapioca/helpers/rbi_helper.rb index d50b636c6..7491c426b 100644 --- a/lib/tapioca/helpers/rbi_helper.rb +++ b/lib/tapioca/helpers/rbi_helper.rb @@ -6,6 +6,7 @@ module RBIHelper extend T::Sig include SorbetHelper extend SorbetHelper + extend self sig { params(name: String, type: String).returns(RBI::TypedParam) } def create_param(name, type:) @@ -89,5 +90,10 @@ def self.serialize_type_variable(type, variance, fixed, upper, lower) serialized << " { { #{block.join(", ")} } }" unless block.empty? serialized end + + sig { params(name: String).returns(T::Boolean) } + def valid_method_name?(name) + !name.to_sym.inspect.start_with?(':"', ":@", ":$") + end end end diff --git a/lib/tapioca/rbi_ext/model.rb b/lib/tapioca/rbi_ext/model.rb index f3dcba679..511e16c47 100644 --- a/lib/tapioca/rbi_ext/model.rb +++ b/lib/tapioca/rbi_ext/model.rb @@ -86,7 +86,7 @@ def create_type_variable(name, type:, variance: :invariant, fixed: nil, upper: n ).void end def create_method(name, parameters: [], return_type: "T.untyped", class_method: false, visibility: RBI::Public.new) - return unless valid_method_name?(name) + return unless Tapioca::RBIHelper.valid_method_name?(name) sig = RBI::Sig.new(return_type: return_type) method = RBI::Method.new(name, sigs: [sig], is_singleton: class_method, visibility: visibility) @@ -99,19 +99,6 @@ def create_method(name, parameters: [], return_type: "T.untyped", class_method: private - SPECIAL_METHOD_NAMES = T.let( - ["!", "~", "+@", "**", "-@", "*", "/", "%", "+", "-", "<<", ">>", "&", "|", "^", "<", "<=", "=>", ">", ">=", - "==", "===", "!=", "=~", "!~", "<=>", "[]", "[]=", "`",].freeze, - T::Array[String] - ) - - sig { params(name: String).returns(T::Boolean) } - def valid_method_name?(name) - return true if SPECIAL_METHOD_NAMES.include?(name) - - !!name.match(/^[a-zA-Z_][[:word:]]*[?!=]?$/) - end - sig { returns(T::Hash[String, RBI::Node]) } def nodes_cache T.must(@nodes_cache ||= T.let({}, T.nilable(T::Hash[String, Node]))) diff --git a/sorbet/rbi/gems/rbi@0.0.14.rbi b/sorbet/rbi/gems/rbi@0.0.14.rbi index 6a6132e59..e86cc92f3 100644 --- a/sorbet/rbi/gems/rbi@0.0.14.rbi +++ b/sorbet/rbi/gems/rbi@0.0.14.rbi @@ -2147,13 +2147,8 @@ class RBI::Tree < ::RBI::NodeWithComments sig { returns(T::Hash[::String, ::RBI::Node]) } def nodes_cache; end - - sig { params(name: ::String).returns(T::Boolean) } - def valid_method_name?(name); end end -RBI::Tree::SPECIAL_METHOD_NAMES = T.let(T.unsafe(nil), Array) - class RBI::TreeBuilder < ::RBI::ASTVisitor sig do params( diff --git a/spec/tapioca/helpers/rbi_helper_spec.rb b/spec/tapioca/helpers/rbi_helper_spec.rb new file mode 100644 index 000000000..766ad4471 --- /dev/null +++ b/spec/tapioca/helpers/rbi_helper_spec.rb @@ -0,0 +1,26 @@ +# typed: strict +# frozen_string_literal: true + +require "spec_helper" + +class Tapioca::RBIHelperSpec < Minitest::Spec + include Tapioca::RBIHelper + + describe Tapioca::RBIHelper do + it "accepts valid method names" do + [ + "f", "foo", "_foo", "foo_", "fOO", "f00", "foo!", "foo=", "foo?", "Foo", "éxéctôr", "❨╯°□°❩╯︵┻━┻", + "!", "~", "+@", "**", "-@", "*", "/", "%", "+", "-", "<<", ">>", "&", "|", "^", + "<", "<=", ">", ">=", "==", "===", "!=", "=~", "!~", "<=>", "[]", "[]=", "`", + ].each do |name| + assert(valid_method_name?(name)) + end + end + + it "rejects invalid method names" do + ["", "42", "42foo", "!foo", "-@foo", "foo-", "foo-bar", "foo.bar", "=>"].each do |name| + refute(valid_method_name?(name)) + end + end + end +end From 51f1bdb6b3935606df818e4245e956c528aa56a8 Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Mon, 13 Jun 2022 17:43:35 -0400 Subject: [PATCH 2/2] Move `valid_parameter_name?` to `RBIHelper` Signed-off-by: Alexandre Terrasa --- lib/tapioca/dsl/compiler.rb | 5 ----- lib/tapioca/gem/listeners/methods.rb | 5 ----- lib/tapioca/helpers/rbi_helper.rb | 5 +++++ spec/tapioca/helpers/rbi_helper_spec.rb | 16 ++++++++++++++++ 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/lib/tapioca/dsl/compiler.rb b/lib/tapioca/dsl/compiler.rb index f98f15649..88b3ef71b 100644 --- a/lib/tapioca/dsl/compiler.rb +++ b/lib/tapioca/dsl/compiler.rb @@ -168,11 +168,6 @@ def as_nilable_type(type) "T.nilable(#{type})" end end - - sig { params(name: String).returns(T::Boolean) } - def valid_parameter_name?(name) - name.match?(/^[[[:alnum:]]_]+$/) - end end end end diff --git a/lib/tapioca/gem/listeners/methods.rb b/lib/tapioca/gem/listeners/methods.rb index 938e8a39f..57d2cb2b0 100644 --- a/lib/tapioca/gem/listeners/methods.rb +++ b/lib/tapioca/gem/listeners/methods.rb @@ -180,11 +180,6 @@ def struct_method?(constant, method_name) .include?(method_name.gsub(/=$/, "").to_sym) end - sig { params(name: String).returns(T::Boolean) } - def valid_parameter_name?(name) - name.match?(/^[[[:alnum:]]_]+$/) - end - sig { params(constant: Module).returns(T.nilable(UnboundMethod)) } def initialize_method_for(constant) constant.instance_method(:initialize) diff --git a/lib/tapioca/helpers/rbi_helper.rb b/lib/tapioca/helpers/rbi_helper.rb index 7491c426b..6564b9979 100644 --- a/lib/tapioca/helpers/rbi_helper.rb +++ b/lib/tapioca/helpers/rbi_helper.rb @@ -95,5 +95,10 @@ def self.serialize_type_variable(type, variance, fixed, upper, lower) def valid_method_name?(name) !name.to_sym.inspect.start_with?(':"', ":@", ":$") end + + sig { params(name: String).returns(T::Boolean) } + def valid_parameter_name?(name) + /^([[:lower:]]|_|[^[[:ascii:]]])([[:alnum:]]|_|[^[[:ascii:]]])*$/.match?(name) + end end end diff --git a/spec/tapioca/helpers/rbi_helper_spec.rb b/spec/tapioca/helpers/rbi_helper_spec.rb index 766ad4471..5e70495a0 100644 --- a/spec/tapioca/helpers/rbi_helper_spec.rb +++ b/spec/tapioca/helpers/rbi_helper_spec.rb @@ -22,5 +22,21 @@ class Tapioca::RBIHelperSpec < Minitest::Spec refute(valid_method_name?(name)) end end + + it "accepts valid parameter names" do + ["f", "foo", "_foo", "foo_", "fOO", "f00", "éxéctôr", "❨╯°□°❩╯︵┻━┻"].each do |name| + assert(valid_parameter_name?(name)) + end + end + + it "rejects invalid parameter names" do + [ + "", "42", "42foo", "foo!", "foo=", "foo?", "Foo", "!foo", "-@foo", "foo-", "foo-bar", "foo.bar", + "!", "~", "+@", "**", "-@", "*", "/", "%", "+", "-", "<<", ">>", "&", "|", "^", + "<", "<=", "=>", ">", ">=", "==", "===", "!=", "=~", "!~", "<=>", "[]", "[]=", "`", + ].each do |name| + refute(valid_parameter_name?(name)) + end + end end end