katakata_irb 0.2.0 → 0.2.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 46f9fc2dd4b85529dff8a278f183954e48d7c7386944672d588e09315f6151ef
4
- data.tar.gz: ae0dbe97feb4f1150f16bd061ea346ac2ff45a19eb1d38be4b6ffa25941418ce
3
+ metadata.gz: ad93f43d988f169816f4e842bdb70eda5a866574664f6afb5c015ae60b2f2d3b
4
+ data.tar.gz: 700e29af39db9a73fb71f0f2e76cf4d87bcf801e31fddaef3514416e6d3699e1
5
5
  SHA512:
6
- metadata.gz: a0306fd41b676ba4b65d3e739704f258950f7406deb4022455c11b4a1b6d42e98d5dceeb5a51e464e1fba36b42705ae6a87b237a2cd24d206f132ca9baa26125
7
- data.tar.gz: 6eddf48f22628cd2ce4bb44e56be931b137f68b4d3194e374600c8e420eb2c84765021c5678bb30cabc0e8ce5f4229d0993c6cfa8502e5aaead8274cf4fd156c
6
+ metadata.gz: d53414d13852cd4d88a92b841fcd20d85a19efd7cb2dd15faac245e0cd944f10e12e5176ca6b03aa82ca3bd66981c56a0a6ad228a73f9e149b1a4ee9077c4f39
7
+ data.tar.gz: 734aa26486a262b1feaf059290d7526fb061a71cd584c8ec4fa4fdbeb3f8a2b1d29b9e5dd64549e33d87e9987e736aeb1be0ae366033af9533914ca38981c4a8
data/katakata_irb.gemspec CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
31
31
  # Uncomment to register a new dependency of your gem
32
32
  spec.add_dependency 'irb', '>= 1.4.0'
33
33
  spec.add_dependency 'reline', '>= 0.3.0'
34
- spec.add_dependency 'prism', '>= 0.13.0'
34
+ spec.add_dependency 'prism', '>= 0.16.0'
35
35
  spec.add_dependency 'rbs'
36
36
 
37
37
  # For more information and examples about making a new gem, check out our
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'type_simulator'
4
- require 'rbs'
5
- require 'rbs/cli'
3
+ require_relative 'type_analyzer'
6
4
  require 'irb'
7
5
  require 'prism'
8
6
 
@@ -77,8 +75,8 @@ module KatakataIrb::Completor
77
75
  $VERBOSE = verbose
78
76
  end
79
77
 
80
- doc_namespace_proc = ->(input) do
81
- name = input[/[a-zA-Z_0-9]+[!?=]?\z/]
78
+ doc_namespace_proc = -> input do
79
+ name = input[/[a-zA-Z_0-9]*[!?=]?\z/]
82
80
  method_doc = -> type do
83
81
  type = type.types.find { _1.all_methods.include? name.to_sym }
84
82
  if type.is_a? KatakataIrb::Types::SingletonType
@@ -96,18 +94,42 @@ module KatakataIrb::Completor
96
94
  end
97
95
  end
98
96
 
97
+ value_doc = -> type do
98
+ return unless type
99
+ type.types.each do |t|
100
+ case t
101
+ when KatakataIrb::Types::SingletonType
102
+ return KatakataIrb::Types.class_name_of(t.module_or_class)
103
+ when KatakataIrb::Types::InstanceType
104
+ return KatakataIrb::Types.class_name_of(t.klass)
105
+ end
106
+ end
107
+ nil
108
+ end
109
+
99
110
  case KatakataIrb::Completor.prev_analyze_result
100
111
  in [:call_or_const, type, _name, _self_call]
101
112
  call_or_const_doc.call type
102
113
  in [:const, type, _name, scope]
103
- # when prev_analyze_result is const, current analyze result might be call
104
- call_or_const_doc.call type if type
105
- in [:gvar, _name, _scope]
106
- name
114
+ if type
115
+ call_or_const_doc.call type
116
+ else
117
+ value_doc.call scope[name]
118
+ end
119
+ in [:gvar, _name, scope]
120
+ value_doc.call scope["$#{name}"]
121
+ in [:ivar, _name, scope]
122
+ value_doc.call scope["@#{name}"]
123
+ in [:cvar, _name, scope]
124
+ value_doc.call scope["@@#{name}"]
107
125
  in [:call, type, _name, _self_call]
108
126
  method_doc.call type
109
127
  in [:lvar_or_method, _name, scope]
110
- method_doc.call scope.self_type unless scope.local_variables.include?(name)
128
+ if scope.local_variables.include?(name)
129
+ value_doc.call scope[name]
130
+ else
131
+ method_doc.call scope.self_type
132
+ end
111
133
  else
112
134
  end
113
135
  end
@@ -193,22 +215,25 @@ module KatakataIrb::Completor
193
215
  end.join + "nil;\n"
194
216
  code = lvars_code + code
195
217
  ast = Prism.parse(code).value
196
- name = code[/(@@|@|\$)?\w*\z/]
218
+ name = code[/(@@|@|\$)?\w*[!?=]?\z/]
197
219
  *parents, target_node = find_target ast, code.bytesize - name.bytesize
198
220
  return unless target_node
199
221
 
200
- calculate_scope = -> { KatakataIrb::TypeSimulator.calculate_target_type_scope(binding, parents, target_node).last }
201
- calculate_type_scope = ->(node) { KatakataIrb::TypeSimulator.calculate_target_type_scope binding, [*parents, target_node], node }
222
+ calculate_scope = -> { KatakataIrb::TypeAnalyzer.calculate_target_type_scope(binding, parents, target_node).last }
223
+ calculate_type_scope = ->(node) { KatakataIrb::TypeAnalyzer.calculate_target_type_scope binding, [*parents, target_node], node }
202
224
 
203
- if target_node.is_a?(Prism::StringNode) || target_node.is_a?(Prism::InterpolatedStringNode)
204
- args_node = parents[-1]
205
- call_node = parents[-2]
225
+ case target_node
226
+ when Prism::StringNode, Prism::InterpolatedStringNode
227
+ call_node, args_node = parents.last(2)
228
+ return unless call_node.is_a?(Prism::CallNode) && call_node.receiver.nil?
206
229
  return unless args_node.is_a?(Prism::ArgumentsNode) && args_node.arguments.size == 1
207
- return unless call_node.is_a?(Prism::CallNode) && call_node.receiver.nil? && (call_node.message == 'require' || call_node.message == 'require_relative')
208
- return [call_node.message.to_sym, name.rstrip]
209
- end
210
230
 
211
- case target_node
231
+ case call_node.name
232
+ when :require
233
+ [:require, name.rstrip]
234
+ when :require_relative
235
+ [:require_relative, name.rstrip]
236
+ end
212
237
  when Prism::SymbolNode
213
238
  if parents.last.is_a? Prism::BlockArgumentNode # method(&:target)
214
239
  receiver_type, _scope = calculate_type_scope.call target_node
@@ -263,8 +288,7 @@ module KatakataIrb::Completor
263
288
  )
264
289
  return [node] if location&.start_offset == position
265
290
 
266
- node.child_nodes.each do |n|
267
- next unless n.is_a? Prism::Node
291
+ node.compact_child_nodes.each do |n|
268
292
  match = find_target(n, position)
269
293
  next unless match
270
294
  match.unshift node
@@ -38,6 +38,8 @@ module KatakataIrb
38
38
  end
39
39
 
40
40
  def get_const(nesting, path, _key = nil)
41
+ return unless nesting
42
+
41
43
  result = path.reduce nesting do |mod, name|
42
44
  return nil unless mod.is_a?(Module) && module_own_constant?(mod, name)
43
45
  mod.const_get name
@@ -45,18 +47,25 @@ module KatakataIrb
45
47
  KatakataIrb::Types.type_from_object result
46
48
  end
47
49
 
50
+ def get_cvar(nesting, path, name, _key = nil)
51
+ return KatakataIrb::Types::NIL unless nesting
52
+
53
+ result = path.reduce nesting do |mod, n|
54
+ return KatakataIrb::Types::NIL unless mod.is_a?(Module) && module_own_constant?(mod, n)
55
+ mod.const_get n
56
+ end
57
+ value = result.class_variable_get name if result.is_a?(Module) && name.size >= 3 && result.class_variable_defined?(name)
58
+ Types.type_from_object value
59
+ end
60
+
48
61
  def [](name)
49
62
  @cache[name] ||= (
50
63
  fallback = KatakataIrb::Types::NIL
51
64
  case BaseScope.type_by_name name
52
- when :cvar
53
- BaseScope.type_of(fallback: fallback) { @self_object.class_variable_get name }
54
65
  when :ivar
55
66
  BaseScope.type_of(fallback: fallback) { @self_object.instance_variable_get name }
56
67
  when :lvar
57
68
  BaseScope.type_of(fallback: fallback) { @binding.local_variable_get(name) }
58
- when :const
59
- BaseScope.type_of(fallback: fallback) { @binding.eval name }
60
69
  when :gvar
61
70
  BaseScope.type_of(fallback: fallback) { @binding.eval name if @global_variables.include? name }
62
71
  end
@@ -81,6 +90,7 @@ module KatakataIrb
81
90
 
82
91
  def self.type_by_name(name)
83
92
  if name.start_with? '@@'
93
+ # "@@cvar" or "@@cvar::[module_id]::[module_path]"
84
94
  :cvar
85
95
  elsif name.start_with? '@'
86
96
  :ivar
@@ -88,7 +98,8 @@ module KatakataIrb
88
98
  :gvar
89
99
  elsif name.start_with? '%'
90
100
  :internal
91
- elsif name[0].downcase != name[0]
101
+ elsif name[0].downcase != name[0] || name[0].match?(/\d/)
102
+ # "ConstName" or "[module_id]::[const_path]"
92
103
  :const
93
104
  else
94
105
  :lvar
@@ -101,10 +112,9 @@ module KatakataIrb
101
112
 
102
113
  def self.from_binding(binding, locals) = new(BaseScope.new(binding, binding.eval('self'), locals))
103
114
 
104
- def initialize(parent, table = {}, trace_cvar: true, trace_ivar: true, trace_lvar: true, self_type: nil, nesting: nil)
115
+ def initialize(parent, table = {}, trace_ivar: true, trace_lvar: true, self_type: nil, nesting: nil)
105
116
  @parent = parent
106
117
  @level = parent.level + 1
107
- @trace_cvar = trace_cvar
108
118
  @trace_ivar = trace_ivar
109
119
  @trace_lvar = trace_lvar
110
120
  @module_nesting = nesting ? [nesting, *parent.module_nesting] : parent.module_nesting
@@ -145,15 +155,13 @@ module KatakataIrb
145
155
  def trace?(name)
146
156
  return false unless @parent
147
157
  type = BaseScope.type_by_name(name)
148
- type == :cvar ? @trace_cvar : type == :ivar ? @trace_ivar : type == :lvar ? @trace_lvar : true
158
+ type == :ivar ? @trace_ivar : type == :lvar ? @trace_lvar : true
149
159
  end
150
160
 
151
161
  def level_of(name, var_type)
152
162
  case var_type
153
163
  when :ivar
154
164
  return level unless @trace_ivar
155
- when :cvar
156
- return level unless @trace_cvar
157
165
  when :gvar
158
166
  return 0
159
167
  end
@@ -167,14 +175,27 @@ module KatakataIrb
167
175
  value || @parent.get_const(nesting, path, key)
168
176
  end
169
177
 
178
+ def get_cvar(nesting, path, name, key = nil)
179
+ key ||= [name, nesting.__id__, path].join('::')
180
+ _l, value = @table[key]
181
+ value || @parent.get_cvar(nesting, path, name, key)
182
+ end
183
+
170
184
  def [](name)
171
185
  type = BaseScope.type_by_name(name)
172
186
  if type == :const
187
+ return get_const(nil, nil, name) || KatakataIrb::Types::NIL if name.include?('::')
188
+
173
189
  module_nesting.each do |(nesting, path)|
174
190
  value = get_const nesting, [*path, name]
175
191
  return value if value
176
192
  end
177
- KatakataIrb::Types::NIL
193
+ return KatakataIrb::Types::NIL
194
+ elsif type == :cvar
195
+ return get_cvar(nil, nil, nil, name) if name.include?('::')
196
+
197
+ nesting, path = module_nesting.first
198
+ return get_cvar(nesting, path, name)
178
199
  end
179
200
  level, value = @table[name]
180
201
  if level
@@ -191,11 +212,28 @@ module KatakataIrb
191
212
  @table[key] = [0, value]
192
213
  end
193
214
 
215
+ def set_cvar(nesting, path, name, value)
216
+ key = [name, nesting.__id__, path].join('::')
217
+ @table[key] = [0, value]
218
+ end
219
+
194
220
  def []=(name, value)
195
221
  type = BaseScope.type_by_name(name)
196
222
  if type == :const
197
- parent_module, parent_path = module_nesting.first
198
- set_const parent_module, [*parent_path, name], value
223
+ if name.include?('::')
224
+ @table[name] = [0, value]
225
+ else
226
+ parent_module, parent_path = module_nesting.first
227
+ set_const parent_module, [*parent_path, name], value
228
+ end
229
+ return
230
+ elsif type == :cvar
231
+ if name.include?('::')
232
+ @table[name] = [0, value]
233
+ else
234
+ parent_module, parent_path = module_nesting.first
235
+ set_cvar parent_module, parent_path, name, value
236
+ end
199
237
  return
200
238
  end
201
239
  variable_level = level_of name, type
@@ -285,8 +323,8 @@ module KatakataIrb
285
323
  end
286
324
 
287
325
  def table_class_variables
288
- cvars = @table.keys.select { BaseScope.type_by_name(_1) == :cvar }
289
- cvars |= @parent.table_class_variables if @parent.mutable? && @trace_cvar
326
+ cvars = @table.keys.filter_map { _1.split('::', 2).first if BaseScope.type_by_name(_1) == :cvar }
327
+ cvars |= @parent.table_class_variables if @parent.mutable?
290
328
  cvars
291
329
  end
292
330