From fb31c8ffd417ce9e4dee6ae0b1b40b93cdfc4606 Mon Sep 17 00:00:00 2001 From: ksss Date: Sun, 15 Jan 2023 14:39:26 +0900 Subject: [PATCH] Fix errors caused by non-ascii variable names --- lib/steep/type_inference/type_env.rb | 8 +++++++- test/type_env_test.rb | 26 +++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/lib/steep/type_inference/type_env.rb b/lib/steep/type_inference/type_env.rb index 58f7d4d4d..ccb66ede0 100644 --- a/lib/steep/type_inference/type_env.rb +++ b/lib/steep/type_inference/type_env.rb @@ -308,7 +308,13 @@ def invalidated_pure_nodes(invalidated_node) end def local_variable_name?(name) - name.start_with?(/[a-z_]/) && name != :_ && name != :__skip__ && name != :__any__ + # Ruby constants start with Uppercase_Letter or Titlecase_Letter in the unicode property. + # If name start with `@`, it is instance variable or class instance variable. + # If name start with `$`, it is global variable. + return false if name.start_with?(/[\p{Uppercase_Letter}\p{Titlecase_Letter}@$]/) + return false if TypeConstruction::SPECIAL_LVAR_NAMES.include?(name) + + true end def local_variable_name!(name) diff --git a/test/type_env_test.rb b/test/type_env_test.rb index 5c47016bd..155fd68d5 100644 --- a/test/type_env_test.rb +++ b/test/type_env_test.rb @@ -23,10 +23,34 @@ def test_local_variable with_factory do env = TypeEnv.new(constant_env) - env = env.assign_local_variables({ :x => parse_type("::String") }) + env = env.assign_local_variables({ + :x => parse_type("::String"), + :ä => parse_type("::Integer") + }) + assert_raises(RuntimeError) do + env.assign_local_variables({ :Dz => parse_type("::Integer") }) + end assert_equal parse_type("::String"), env[:x] + assert_equal parse_type("::Integer"), env[:ä] assert_nil env.enforced_type(:x) + assert_nil env.enforced_type(:ä) + end + end + + def test_local_variable_name_p + with_factory do + env = TypeEnv.new(constant_env) + assert_equal true, env.local_variable_name?(:abc) + assert_equal true, env.local_variable_name?(:_abc) + assert_equal false, env.local_variable_name?(:@abc) + assert_equal false, env.local_variable_name?(:$abc) + assert_equal false, env.local_variable_name?(:_) + assert_equal false, env.local_variable_name?(:__skip__) + assert_equal false, env.local_variable_name?(:__any__) + assert_equal true, env.local_variable_name?(:dz) # Lowercase_Letter + assert_equal false, env.local_variable_name?(:DZ) # Uppercase_Letter + assert_equal false, env.local_variable_name?(:Dz) # Titlecase_Letter end end