katakata_irb 0.1.9 → 0.1.10
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/lib/katakata_irb/completor.rb +41 -28
- data/lib/katakata_irb/nesting_parser.rb +29 -35
- data/lib/katakata_irb/type_simulator.rb +2 -2
- data/lib/katakata_irb/types.rb +14 -6
- data/lib/katakata_irb/version.rb +1 -1
- data/lib/katakata_irb.rb +1 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 297457c829dac09ddee68c1cc5365acfcc2583e0282fb1070ebae8fa138523ba
|
4
|
+
data.tar.gz: a45663afa386d4093814a3ea2a49c98cb03e90004e2a42c0dc723f4686500a51
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e66cd04bba34272f585adb1a6dde686a49d064604a48b1c0d14093474857b30537f6b05dd965eaf7ae822b174e373122479c05a643cc951fe4ecea3009a625c6
|
7
|
+
data.tar.gz: 4cb475b48b8e73db73340a1a11c97b087f99d2d6159e235d93a8845e4a718e9b18deb4e693d86059ba98bdbecbf41f24c13cb70d969fdd6d18f9cb171c76478b
|
@@ -10,6 +10,7 @@ module KatakataIrb::Completor
|
|
10
10
|
singleton_class.attr_accessor :prev_analyze_result
|
11
11
|
|
12
12
|
def self.setup
|
13
|
+
KatakataIrb::Types.preload_in_thread
|
13
14
|
completion_proc = ->(target, preposing = nil, postposing = nil) do
|
14
15
|
code = "#{preposing}#{target}"
|
15
16
|
irb_context = IRB.conf[:MAIN_CONTEXT]
|
@@ -61,7 +62,7 @@ module KatakataIrb::Completor
|
|
61
62
|
end
|
62
63
|
|
63
64
|
IRB::InputCompletor.singleton_class.prepend Module.new{
|
64
|
-
def retrieve_completion_data(input,
|
65
|
+
def retrieve_completion_data(input, doc_namespace: false, **)
|
65
66
|
return super unless doc_namespace
|
66
67
|
name = input[/[a-zA-Z_0-9]+[!?=]?\z/]
|
67
68
|
method_doc = -> type do
|
@@ -100,32 +101,39 @@ module KatakataIrb::Completor
|
|
100
101
|
setup_type_dialog
|
101
102
|
end
|
102
103
|
|
104
|
+
def self.type_dialog_content
|
105
|
+
receiver_type = (
|
106
|
+
case KatakataIrb::Completor.prev_analyze_result
|
107
|
+
in [:call_or_const, type, name, _self_call] if name.empty?
|
108
|
+
type
|
109
|
+
in [:call, type, name, _self_call] if name.empty?
|
110
|
+
type
|
111
|
+
else
|
112
|
+
return
|
113
|
+
end
|
114
|
+
)
|
115
|
+
if KatakataIrb::Types.rbs_builder.nil? && !KatakataIrb::Types.rbs_load_error
|
116
|
+
return [' Loading ', ' RBS... ']
|
117
|
+
end
|
118
|
+
types = receiver_type.types
|
119
|
+
contents = types.filter_map do |type|
|
120
|
+
case type
|
121
|
+
when KatakataIrb::Types::InstanceType
|
122
|
+
type.inspect_without_params
|
123
|
+
else
|
124
|
+
type.inspect
|
125
|
+
end
|
126
|
+
end.uniq
|
127
|
+
contents if contents.any?
|
128
|
+
end
|
129
|
+
|
103
130
|
def self.setup_type_dialog
|
104
131
|
type_dialog_proc = -> {
|
105
132
|
return if just_cursor_moving && completion_journey_data
|
106
133
|
cursor_pos_to_render, _result, pointer, autocomplete_dialog = context.last(4)
|
107
134
|
return unless cursor_pos_to_render && autocomplete_dialog&.width && pointer.nil?
|
108
|
-
|
109
|
-
|
110
|
-
in [:call_or_const, type, name, _self_call] if name.empty?
|
111
|
-
type
|
112
|
-
in [:call, type, name, _self_call] if name.empty?
|
113
|
-
type
|
114
|
-
else
|
115
|
-
return
|
116
|
-
end
|
117
|
-
)
|
118
|
-
return unless receiver_type
|
119
|
-
types = type.types
|
120
|
-
contents = types.filter_map do |type|
|
121
|
-
case type
|
122
|
-
when KatakataIrb::Types::InstanceType
|
123
|
-
type.inspect_without_params
|
124
|
-
else
|
125
|
-
type.inspect
|
126
|
-
end
|
127
|
-
end.uniq
|
128
|
-
return if contents.empty?
|
135
|
+
contents = KatakataIrb::Completor.type_dialog_content
|
136
|
+
return unless contents&.any?
|
129
137
|
|
130
138
|
width = contents.map { Reline::Unicode.calculate_width _1 }.max
|
131
139
|
x = cursor_pos_to_render.x + autocomplete_dialog.width
|
@@ -145,12 +153,11 @@ module KatakataIrb::Completor
|
|
145
153
|
"#{name}="
|
146
154
|
end.join + "nil;\n"
|
147
155
|
code = lvars_code + code
|
148
|
-
tokens =
|
149
|
-
|
150
|
-
last_opens = KatakataIrb::NestingParser.parse(tokens)
|
156
|
+
tokens = KatakataIrb::NestingParser.tokenize code
|
157
|
+
last_opens = KatakataIrb::NestingParser.open_tokens(tokens)
|
151
158
|
closings = last_opens.map do |t|
|
152
159
|
case t.tok
|
153
|
-
when /\A
|
160
|
+
when /\A%.?[<>]\z/
|
154
161
|
$/ + '>'
|
155
162
|
when '{', '#{', /\A%.?[{}]\z/
|
156
163
|
$/ + '}'
|
@@ -271,9 +278,15 @@ module KatakataIrb::Completor
|
|
271
278
|
[:ivar, name, calculate_scope.call.self_type] if icvar_available
|
272
279
|
in [:var_ref, [:@cvar,]]
|
273
280
|
[:cvar, name, calculate_scope.call.self_type] if icvar_available
|
274
|
-
in [:call, receiver, [:@
|
281
|
+
in [:call, receiver, [:@op, '::',] | :'::', [:@ident | :@const,]]
|
282
|
+
self_call = (receiver in [:var_ref, [:@kw, 'self',]])
|
283
|
+
[:call_or_const, calculate_receiver.call(receiver), name, self_call]
|
284
|
+
in [:call, receiver, [:@period,], [:@ident | :@const,]]
|
285
|
+
self_call = (receiver in [:var_ref, [:@kw, 'self',]])
|
286
|
+
[:call, calculate_receiver.call(receiver), name, self_call]
|
287
|
+
in [:call, receiver, [:@op, '&.',], [:@ident | :@const,]]
|
275
288
|
self_call = (receiver in [:var_ref, [:@kw, 'self',]])
|
276
|
-
[
|
289
|
+
[:call, calculate_receiver.call(receiver).nonnillable, name, self_call]
|
277
290
|
in [:const_path_ref, receiver, [:@const,]]
|
278
291
|
[:const, calculate_receiver.call(receiver), name]
|
279
292
|
in [:top_const_ref, [:@const,]]
|
@@ -1,4 +1,18 @@
|
|
1
1
|
module KatakataIrb::NestingParser
|
2
|
+
ERROR_TOKENS = %i[
|
3
|
+
on_parse_error
|
4
|
+
compile_error
|
5
|
+
on_assign_error
|
6
|
+
on_alias_error
|
7
|
+
on_class_name_error
|
8
|
+
on_param_error
|
9
|
+
]
|
10
|
+
|
11
|
+
def self.tokenize(code)
|
12
|
+
tokens = Ripper::Lexer.new(code).scan.reject { ERROR_TOKENS.include? _1.event }
|
13
|
+
KatakataIrb::NestingParser.interpolate_ripper_ignored_tokens code, tokens
|
14
|
+
end
|
15
|
+
|
2
16
|
def self.interpolate_ripper_ignored_tokens(code, tokens)
|
3
17
|
line_positions = code.lines.reduce([0]) { _1 << _1.last + _2.bytesize }
|
4
18
|
prev_byte_pos = 0
|
@@ -26,9 +40,10 @@ module KatakataIrb::NestingParser
|
|
26
40
|
interpolated
|
27
41
|
end
|
28
42
|
|
29
|
-
|
43
|
+
IGNORE_TOKENS = %i[on_sp on_ignored_nl on_comment on_embdoc_beg on_embdoc on_embdoc_end]
|
30
44
|
|
31
|
-
|
45
|
+
# Scan each token and call the given block with array of token and other information for parsing
|
46
|
+
def self.scan_opens(tokens)
|
32
47
|
opens = []
|
33
48
|
pending_heredocs = []
|
34
49
|
first_token_on_line = true
|
@@ -37,14 +52,14 @@ module KatakataIrb::NestingParser
|
|
37
52
|
last_tok, state, args = opens.last
|
38
53
|
case state
|
39
54
|
when :in_unquoted_symbol
|
40
|
-
unless t.event
|
55
|
+
unless IGNORE_TOKENS.include?(t.event)
|
41
56
|
opens.pop
|
42
57
|
skip = true
|
43
58
|
end
|
44
59
|
when :in_lambda_head
|
45
60
|
opens.pop if t.event == :on_tlambeg || (t.event == :on_kw && t.tok == 'do')
|
46
61
|
when :in_method_head
|
47
|
-
unless
|
62
|
+
unless IGNORE_TOKENS.include?(t.event)
|
48
63
|
next_args = []
|
49
64
|
body = nil
|
50
65
|
if args.include?(:receiver)
|
@@ -133,7 +148,7 @@ module KatakataIrb::NestingParser
|
|
133
148
|
if t.event == :on_op && t.tok == '|'
|
134
149
|
opens[-1] = [last_tok, nil]
|
135
150
|
opens << [t, :in_block_args]
|
136
|
-
elsif !
|
151
|
+
elsif !IGNORE_TOKENS.include?(t.event)
|
137
152
|
opens[-1] = [last_tok, nil]
|
138
153
|
end
|
139
154
|
when :in_block_args
|
@@ -201,6 +216,12 @@ module KatakataIrb::NestingParser
|
|
201
216
|
opens << [t, nil]
|
202
217
|
when :on_tstring_end, :on_regexp_end, :on_label_end
|
203
218
|
opens.pop
|
219
|
+
when :on_symbeg
|
220
|
+
if t.tok == ':'
|
221
|
+
opens << [t, :in_unquoted_symbol]
|
222
|
+
else
|
223
|
+
opens << [t, nil]
|
224
|
+
end
|
204
225
|
when :on_op
|
205
226
|
case t.tok
|
206
227
|
when '?'
|
@@ -210,12 +231,6 @@ module KatakataIrb::NestingParser
|
|
210
231
|
# closing of `cond ? value : value``
|
211
232
|
opens.pop
|
212
233
|
end
|
213
|
-
when :on_symbeg
|
214
|
-
if t.tok == ':'
|
215
|
-
opens << [t, :in_unquoted_symbol]
|
216
|
-
else
|
217
|
-
opens << [t, nil]
|
218
|
-
end
|
219
234
|
end
|
220
235
|
end
|
221
236
|
if t.event == :on_nl || t.event == :on_semicolon
|
@@ -232,29 +247,8 @@ module KatakataIrb::NestingParser
|
|
232
247
|
opens.map(&:first) + pending_heredocs.reverse
|
233
248
|
end
|
234
249
|
|
235
|
-
def self.
|
236
|
-
|
237
|
-
|
238
|
-
min_depth = 0
|
239
|
-
output = []
|
240
|
-
last_opens = parse(tokens) do |t, opens|
|
241
|
-
depth = t == opens.last&.first ? opens.size - 1 : opens.size
|
242
|
-
min_depth = depth if depth < min_depth
|
243
|
-
if t.tok.include?("\n")
|
244
|
-
t.tok.each_line do |line|
|
245
|
-
line_tokens << [t, line]
|
246
|
-
next if line[-1] != "\n"
|
247
|
-
next_opens = opens.map(&:first)
|
248
|
-
output << [line_tokens, prev_opens, next_opens, min_depth]
|
249
|
-
prev_opens = next_opens
|
250
|
-
min_depth = prev_opens.size
|
251
|
-
line_tokens = []
|
252
|
-
end
|
253
|
-
else
|
254
|
-
line_tokens << [t, t.tok]
|
255
|
-
end
|
256
|
-
end
|
257
|
-
output << [line_tokens, prev_opens, last_opens, min_depth] if line_tokens.any?
|
258
|
-
output
|
250
|
+
def self.open_tokens(tokens)
|
251
|
+
# scan_opens without block will return a list of open tokens at last token position
|
252
|
+
scan_opens(tokens)
|
259
253
|
end
|
260
254
|
end
|
@@ -769,9 +769,9 @@ class KatakataIrb::TypeSimulator
|
|
769
769
|
case sexp
|
770
770
|
in [:fcall | :vcall, [:@ident | :@const | :@kw | :@op, method,]] # hoge
|
771
771
|
[nil, method, [], [], nil, false]
|
772
|
-
in [:call, receiver, [:@period,] | [:@op, '&.',] | :'::' => dot, :call]
|
772
|
+
in [:call, receiver, [:@period,] | [:@op, '&.',] | [:@op, '::',] | :'::' => dot, :call]
|
773
773
|
[receiver, :call, [], [], nil, optional[dot]]
|
774
|
-
in [:call, receiver, [:@period,] | [:@op, '&.',] | :'::' => dot, method]
|
774
|
+
in [:call, receiver, [:@period,] | [:@op, '&.',] | [:@op, '::',] | :'::' => dot, method]
|
775
775
|
method => [:@ident | :@const | :@kw | :@op, method,] unless method == :call
|
776
776
|
[receiver, method, [], [], nil, optional[dot]]
|
777
777
|
in [:command, [:@ident | :@const | :@kw | :@op, method,], args] # hoge 1, 2
|
data/lib/katakata_irb/types.rb
CHANGED
@@ -3,8 +3,12 @@ require 'rbs/cli'
|
|
3
3
|
|
4
4
|
module KatakataIrb; end
|
5
5
|
module KatakataIrb::Types
|
6
|
-
|
7
|
-
|
6
|
+
singleton_class.attr_reader :rbs_builder, :rbs_load_error
|
7
|
+
|
8
|
+
def self.preload_in_thread
|
9
|
+
@loader_thread ||= Thread.new do
|
10
|
+
@rbs_builder = load_rbs_builder
|
11
|
+
end
|
8
12
|
end
|
9
13
|
|
10
14
|
def self.load_rbs_builder
|
@@ -12,8 +16,10 @@ module KatakataIrb::Types
|
|
12
16
|
loader.add path: Pathname('sig')
|
13
17
|
RBS::DefinitionBuilder.new env: RBS::Environment.from_loader(loader).resolve_type_names
|
14
18
|
rescue => e
|
15
|
-
|
16
|
-
|
19
|
+
@rbs_load_error = e
|
20
|
+
puts "\r\nKatakataIRB failed to initialize RBS::DefinitionBuilder: #{e.class}\r\n"
|
21
|
+
puts "See `KatakataIrb::Types.rbs_load_error` for more details.\r\n"
|
22
|
+
nil
|
17
23
|
end
|
18
24
|
|
19
25
|
Splat = Struct.new :item
|
@@ -59,6 +65,8 @@ module KatakataIrb::Types
|
|
59
65
|
end
|
60
66
|
|
61
67
|
def self.rbs_methods(type, method_name, args_types, kwargs_type, has_block)
|
68
|
+
return [] unless rbs_builder
|
69
|
+
|
62
70
|
receivers = type.types.map do |t|
|
63
71
|
case t
|
64
72
|
in ProcType
|
@@ -397,8 +405,8 @@ module KatakataIrb::Types
|
|
397
405
|
|
398
406
|
def self.match_free_variables(vars, types, values)
|
399
407
|
accumulator = {}
|
400
|
-
types.zip
|
401
|
-
_match_free_variable(vars, t, v, accumulator)
|
408
|
+
types.zip values do |t, v|
|
409
|
+
_match_free_variable(vars, t, v, accumulator) if v
|
402
410
|
end
|
403
411
|
accumulator.transform_values { UnionType[*_1] }
|
404
412
|
end
|
data/lib/katakata_irb/version.rb
CHANGED
data/lib/katakata_irb.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: katakata_irb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- tompng
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: irb
|
@@ -95,7 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
requirements: []
|
98
|
-
rubygems_version: 3.4.
|
98
|
+
rubygems_version: 3.4.10
|
99
99
|
signing_key:
|
100
100
|
specification_version: 4
|
101
101
|
summary: IRB with Typed Completion
|