katakata_irb 0.2.0 → 0.2.1
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 +4 -4
- data/katakata_irb.gemspec +1 -1
- data/lib/katakata_irb/completor.rb +37 -13
- data/lib/katakata_irb/scope.rb +53 -15
- data/lib/katakata_irb/type_analyzer.rb +1168 -0
- data/lib/katakata_irb/types.rb +8 -8
- data/lib/katakata_irb/version.rb +1 -1
- metadata +5 -5
- data/lib/katakata_irb/type_simulator.rb +0 -990
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 034055ed4a5fcf5bde6a1b86723c2963f82ace7c5b0411cd9a3e09fd734b10d2
|
4
|
+
data.tar.gz: 3e04438496f0241815cf7b674db57f7b644360520d9d829d75d5be61b63b78e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4b406ecd5c611cdc86220efa506c403dff220db4be5fb1bc1fab10eeb70931f0d7eaee8a45a702a6addb5de793e0c219562975d769fe31616305cd87fe4cfa4a
|
7
|
+
data.tar.gz: 147b09a36c68a66c917fff2157797d1124ec06e0333ee7cec26ef83b9d726c398bb83bbdce81f88c1706067ecc3f9bf99506d5706d3b22ccc3c8aa2ee6ce5cb1
|
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.
|
34
|
+
spec.add_dependency 'prism', '>= 0.14.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 '
|
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 = ->
|
81
|
-
name = input[/[a-zA-Z_0-9]
|
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,44 @@ 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
|
+
when KatakataIrb::Types::ProcType
|
106
|
+
return 'Proc'
|
107
|
+
end
|
108
|
+
end
|
109
|
+
nil
|
110
|
+
end
|
111
|
+
|
99
112
|
case KatakataIrb::Completor.prev_analyze_result
|
100
113
|
in [:call_or_const, type, _name, _self_call]
|
101
114
|
call_or_const_doc.call type
|
102
115
|
in [:const, type, _name, scope]
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
116
|
+
if type
|
117
|
+
call_or_const_doc.call type
|
118
|
+
else
|
119
|
+
value_doc.call scope[name]
|
120
|
+
end
|
121
|
+
in [:gvar, _name, scope]
|
122
|
+
value_doc.call scope["$#{name}"]
|
123
|
+
in [:ivar, _name, scope]
|
124
|
+
value_doc.call scope["@#{name}"]
|
125
|
+
in [:cvar, _name, scope]
|
126
|
+
value_doc.call scope["@@#{name}"]
|
107
127
|
in [:call, type, _name, _self_call]
|
108
128
|
method_doc.call type
|
109
129
|
in [:lvar_or_method, _name, scope]
|
110
|
-
|
130
|
+
if scope.local_variables.include?(name)
|
131
|
+
value_doc.call scope[name]
|
132
|
+
else
|
133
|
+
method_doc.call scope.self_type
|
134
|
+
end
|
111
135
|
else
|
112
136
|
end
|
113
137
|
end
|
@@ -193,12 +217,12 @@ module KatakataIrb::Completor
|
|
193
217
|
end.join + "nil;\n"
|
194
218
|
code = lvars_code + code
|
195
219
|
ast = Prism.parse(code).value
|
196
|
-
name = code[/(@@|@|\$)?\w
|
220
|
+
name = code[/(@@|@|\$)?\w*[!?=]?\z/]
|
197
221
|
*parents, target_node = find_target ast, code.bytesize - name.bytesize
|
198
222
|
return unless target_node
|
199
223
|
|
200
|
-
calculate_scope = -> { KatakataIrb::
|
201
|
-
calculate_type_scope = ->(node) { KatakataIrb::
|
224
|
+
calculate_scope = -> { KatakataIrb::TypeAnalyzer.calculate_target_type_scope(binding, parents, target_node).last }
|
225
|
+
calculate_type_scope = ->(node) { KatakataIrb::TypeAnalyzer.calculate_target_type_scope binding, [*parents, target_node], node }
|
202
226
|
|
203
227
|
if target_node.is_a?(Prism::StringNode) || target_node.is_a?(Prism::InterpolatedStringNode)
|
204
228
|
args_node = parents[-1]
|
data/lib/katakata_irb/scope.rb
CHANGED
@@ -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 = {},
|
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 == :
|
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
|
-
|
198
|
-
|
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.
|
289
|
-
cvars |= @parent.table_class_variables if @parent.mutable?
|
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
|
|