katakata_irb 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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