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