katakata_irb 0.1.2 → 0.1.4

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: 5d3d6ff924cd8fa8f05b097253525517a988c377d59e63ed1e5c6e5867cfde88
4
- data.tar.gz: af6afd4a833e2b9bfd08a05877db80e45faadcac845be5148b53e3266d5539d8
3
+ metadata.gz: 6e13d1b43d98e8be7595125b4e1e27533d83da1ee4d87df0dfb613d8fb8adee4
4
+ data.tar.gz: ae508bc65cd1049100fe4811b1d2b27036b30131cab13821d52b637e91e2ed41
5
5
  SHA512:
6
- metadata.gz: 35b76a766b99913226c5888b00efcc1c88c35ecb1bbb38338cf69a47772153caecb204bf5cad0a4f7affb475a179b0bd084ecd673c793260165731eef88a258b
7
- data.tar.gz: e2dc520f4d5fe10a95795d5cbcdb784289e674c415a8eddea2c06883262f02847a5fd5b4fb7dc83d219e8a2add95e5fb5ed7c3d7000b4c83ea539825d50c5f20
6
+ metadata.gz: be9ed49c8de27772f7ec154df136134e9d5319a851fe392656a67d3c49069ed040a41b2af8deb6e81577c0c59c6d5bc0918a8165e09ccab2bce15fd6f09abba8
7
+ data.tar.gz: 8d9554e6532488742e156d39e7ee63c3c2461900db42badfd0d49990e35769b1e0f34a8cd746d5aab57839d3f31e894a081ec42389cd2383dafab5043d3fa578
data/Gemfile.lock CHANGED
@@ -1,15 +1,21 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- katakata_irb (0.1.2)
4
+ katakata_irb (0.1.4)
5
+ irb (>= 1.4.0)
5
6
  rbs
6
7
 
7
8
  GEM
8
9
  remote: https://rubygems.org/
9
10
  specs:
11
+ io-console (0.6.0)
12
+ irb (1.6.2)
13
+ reline (>= 0.3.0)
10
14
  minitest (5.16.3)
11
15
  rake (13.0.6)
12
16
  rbs (2.7.0)
17
+ reline (0.3.2)
18
+ io-console (~> 0.5)
13
19
 
14
20
  PLATFORMS
15
21
  x86_64-darwin-20
@@ -20,4 +26,4 @@ DEPENDENCIES
20
26
  rake (~> 13.0)
21
27
 
22
28
  BUNDLED WITH
23
- 2.4.0.dev
29
+ 2.4.5
data/README.md CHANGED
@@ -9,9 +9,15 @@ gem install katakata_irb
9
9
  ```
10
10
  ## Usage
11
11
 
12
+ Just require katakata_irb or write it to your `.irbrc` file.
13
+ ```ruby
14
+ require 'katakata_irb'
15
+ ```
16
+
12
17
  ```
13
- % kirb
14
- irb(main):001:0> [1,'a'].sample.a█
18
+ irb(main):001:0> require 'katakata_irb'
19
+ => true
20
+ irb(main):002:0> [1,'a'].sample.a█
15
21
  |[1,'a'].sample.abs |
16
22
  |[1,'a'].sample.abs2 |
17
23
  |[1,'a'].sample.allbits? |
@@ -22,30 +28,14 @@ irb(main):001:0> [1,'a'].sample.a█
22
28
  ```
23
29
 
24
30
  ```
25
- % kirb
26
- irb(main):001:0> a = 10
31
+ irb(main):001:0> require 'katakata_irb'
32
+ => true
33
+ irb(main):002:0> a = 10
27
34
  => 10
28
- irb(main):002:1* if true
29
- irb(main):003:2* b = a.times.map do
30
- irb(main):004:2* _1.to_s
31
- irb(main):005:1* end
32
- irb(main):006:1* b[0].a█
35
+ irb(main):003:1* if true
36
+ irb(main):004:2* b = a.times.map do
37
+ irb(main):005:2* _1.to_s
38
+ irb(main):006:1* end
39
+ irb(main):007:1* b[0].a█
33
40
  |b[0].ascii_only?|
34
41
  ```
35
-
36
- ```ruby
37
- require 'katakata_irb/completor'
38
- KatakataIrb::Completor.setup
39
- 10.times do |i|
40
- binding.irb
41
- end
42
- ```
43
-
44
- ## Options
45
-
46
- ### `kirb --debug-output`
47
- Show debug output if it meets unimplemented syntax or something
48
-
49
- ### `kirb --without-patch`
50
- `kirb` will apply some patches to reline and irb/ruby-lex.rb by default. This option will disable it.
51
- See `lib/katakata_irb/ruby_lex_patch.rb` and `lib/katakata_irb/reline_patches/*.patch`
data/bin/console CHANGED
@@ -1,10 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- require_relative '../lib/katakata_irb'
3
- require_relative '../lib/katakata_irb/reline_patch'
4
- KatakataIrb.log_output = STDERR
5
- KatakataIrb::RelinePatch.require_patched_reline
6
2
  require 'bundler/setup'
7
3
  require 'katakata_irb'
8
- require 'katakata_irb/ruby_lex_patch'
9
- KatakataIrb::RubyLexPatch.patch_to_ruby_lex
10
- KatakataIrb.repl
4
+ KatakataIrb.log_output = STDERR
5
+ IRB.start(__FILE__)
data/katakata_irb.gemspec CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
  spec.description = "IRB with Typed Completion"
13
13
  spec.homepage = "http://github.com/tompng/katakata_irb"
14
14
  spec.license = "MIT"
15
- spec.required_ruby_version = ">= 3.1.0"
15
+ spec.required_ruby_version = ">= 3.0.0" # recommend >= 3.1.0
16
16
 
17
17
  spec.metadata["homepage_uri"] = spec.homepage
18
18
  spec.metadata["source_code_uri"] = "http://github.com/tompng/katakata_irb"
@@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
29
29
  spec.require_paths = ["lib"]
30
30
 
31
31
  # Uncomment to register a new dependency of your gem
32
+ spec.add_dependency 'irb', '>= 1.4.0'
32
33
  spec.add_dependency 'rbs'
33
34
 
34
35
  # For more information and examples about making a new gem, check out our
@@ -1,4 +1,4 @@
1
- require_relative 'trex'
1
+ require_relative 'nesting_parser'
2
2
  require_relative 'type_simulator'
3
3
  require 'rbs'
4
4
  require 'rbs/cli'
@@ -6,15 +6,17 @@ require 'irb'
6
6
 
7
7
  module KatakataIrb::Completor
8
8
  using KatakataIrb::TypeSimulator::LexerElemMatcher
9
-
10
9
  HIDDEN_METHODS = %w[Namespace TypeName] # defined by rbs, should be hidden
10
+ singleton_class.attr_accessor :prev_analyze_result
11
11
 
12
12
  def self.setup
13
13
  completion_proc = ->(target, preposing = nil, postposing = nil) do
14
14
  code = "#{preposing}#{target}"
15
15
  irb_context = IRB.conf[:MAIN_CONTEXT]
16
16
  binding = irb_context.workspace.binding
17
- candidates = case analyze code, binding
17
+ result = analyze code, binding
18
+ KatakataIrb::Completor.prev_analyze_result = result
19
+ candidates = case result
18
20
  in [:require | :require_relative => method, name]
19
21
  if method == :require
20
22
  IRB::InputCompletor.retrieve_files_to_require_from_load_path
@@ -57,6 +59,44 @@ module KatakataIrb::Completor
57
59
  KatakataIrb.log_puts "#{e.inspect} stored to $error"
58
60
  KatakataIrb.log_puts
59
61
  end
62
+
63
+ IRB::InputCompletor.singleton_class.prepend Module.new{
64
+ def retrieve_completion_data(input, _bind: IRB.conf[:MAIN_CONTEXT].workspace.binding, doc_namespace: false)
65
+ return super unless doc_namespace
66
+ name = input[/[a-zA-Z_0-9]+[!?=]?\z/]
67
+ method_doc = -> type do
68
+ type = type.types.find { _1.all_methods.include? name.to_sym }
69
+ if type in KatakataIrb::Types::SingletonType
70
+ "#{type.module_or_class.name}.#{name}"
71
+ elsif type in KatakataIrb::Types::InstanceType
72
+ "#{type.klass.name}##{name}"
73
+ end
74
+ end
75
+ call_or_const_doc = -> type do
76
+ if name =~ /\A[A-Z]/
77
+ type = type.types.grep(KatakataIrb::Types::SingletonType).find { _1.module_or_class.const_defined?(name) }
78
+ type.module_or_class == Object ? name : "#{type.module_or_class.name}::#{name}" if type
79
+ else
80
+ method_doc.call(type)
81
+ end
82
+ end
83
+
84
+ case KatakataIrb::Completor.prev_analyze_result
85
+ in [:call_or_const, type, _name, _self_call]
86
+ call_or_const_doc.call type
87
+ in [:const, type, _name]
88
+ # when prev_analyze_result is const, current analyze result might be call
89
+ call_or_const_doc.call type
90
+ in [:gvar, _name]
91
+ name
92
+ in [:call, type, _name, _self_call]
93
+ method_doc.call type
94
+ in [:lvar_or_method, _name, scope]
95
+ method_doc.call scope.self_type unless scope.local_variables.include?(name)
96
+ else
97
+ end
98
+ end
99
+ }
60
100
  end
61
101
 
62
102
  def self.analyze(code, binding = Kernel.binding)
@@ -65,8 +105,8 @@ module KatakataIrb::Completor
65
105
  end.join + "nil;\n"
66
106
  code = lvars_code + code
67
107
  tokens = RubyLex.ripper_lex_without_warning code
68
- tokens = KatakataIrb::TRex.interpolate_ripper_ignored_tokens code, tokens
69
- last_opens = KatakataIrb::TRex.parse(tokens)
108
+ tokens = KatakataIrb::NestingParser.interpolate_ripper_ignored_tokens code, tokens
109
+ last_opens = KatakataIrb::NestingParser.parse(tokens)
70
110
  closings = last_opens.map do |t|
71
111
  case t.tok
72
112
  when /\A%.[<>]\z/
@@ -89,7 +129,6 @@ module KatakataIrb::Completor
89
129
  end
90
130
  end
91
131
 
92
- return if code =~ /[!?]\z/
93
132
  case tokens.last
94
133
  in { event: :on_ignored_by_ripper, tok: '.' }
95
134
  suffix = 'method'
@@ -1,5 +1,4 @@
1
- module KatakataIrb; end
2
- module KatakataIrb::TRex
1
+ module KatakataIrb::NestingParser
3
2
  def self.interpolate_ripper_ignored_tokens(code, tokens)
4
3
  line_positions = code.lines.reduce([0]) { _1 << _1.last + _2.bytesize }
5
4
  prev_byte_pos = 0
@@ -31,81 +30,102 @@ module KatakataIrb::TRex
31
30
  opens = []
32
31
  pending_heredocs = []
33
32
  first_token_on_line = true
34
- tokens.each_with_index do |t, index|
33
+ tokens.each do |t|
35
34
  skip = false
36
35
  last_tok, state, args = opens.last
37
36
  case state
38
37
  when :in_unquoted_symbol
39
- opens.pop
40
- skip = true if %i[on_ident on_const on_op on_cvar on_ivar on_gvar on_kw on_int on_backtick].include? t.event
38
+ unless t.event == :on_sp
39
+ opens.pop
40
+ skip = true
41
+ end
42
+ when :in_lambda_head
43
+ opens.pop if t.event == :on_tlambeg || (t.event == :on_kw && t.tok == 'do')
41
44
  when :in_method_head
42
- unless %i[on_sp on_ignored_nl].include?(t.event)
45
+ unless %i[on_sp on_ignored_nl on_comment on_embdoc_beg on_embdoc on_embdoc_end].include?(t.event)
43
46
  next_args = []
44
47
  body = nil
45
- if args.include? :receiver
48
+ if args.include?(:receiver)
46
49
  case t.event
47
50
  when :on_lparen, :on_ivar, :on_gvar, :on_cvar
51
+ # def (receiver). | def @ivar. | def $gvar. | def @@cvar.
48
52
  next_args << :dot
49
53
  when :on_kw
50
- if t.tok in 'self' | 'true' | 'false' | 'nil'
51
- next_args.push :arg, :dot
54
+ case t.tok
55
+ when 'self', 'true', 'false', 'nil'
56
+ # def self(arg) | def self.
57
+ next_args.push(:arg, :dot)
52
58
  else
59
+ # def if(arg)
53
60
  skip = true
54
61
  next_args << :arg
55
62
  end
56
- when :on_op
63
+ when :on_op, :on_backtick
64
+ # def +(arg)
57
65
  skip = true
58
66
  next_args << :arg
59
67
  when :on_ident, :on_const
60
- next_args.push :arg, :dot
68
+ # def a(arg) | def a.
69
+ next_args.push(:arg, :dot)
61
70
  end
62
71
  end
63
- if args.include? :dot
72
+ if args.include?(:dot)
73
+ # def receiver.name
64
74
  next_args << :name if t.event == :on_period || (t.event == :on_op && t.tok == '::')
65
75
  end
66
- if args.include? :name
67
- if %i[on_ident on_const on_op on_kw].include? t.event
76
+ if args.include?(:name)
77
+ if %i[on_ident on_const on_op on_kw on_backtick].include?(t.event)
78
+ # def name(arg) | def receiver.name(arg)
68
79
  next_args << :arg
69
80
  skip = true
70
81
  end
71
82
  end
72
- if args.include? :arg
83
+ if args.include?(:arg)
73
84
  case t.event
74
- when :on_op
75
- body = :oneliner if t.tok == '='
76
85
  when :on_nl, :on_semicolon
86
+ # def recever.f;
77
87
  body = :normal
78
88
  when :on_lparen
89
+ # def recever.f()
79
90
  next_args << :eq
80
91
  else
81
- next_args << :arg_without_paren
92
+ if t.event == :on_op && t.tok == '='
93
+ # def receiver.f =
94
+ body = :oneliner
95
+ else
96
+ # def recever.f arg
97
+ next_args << :arg_without_paren
98
+ end
82
99
  end
83
100
  end
84
- if args.include? :eq
101
+ if args.include?(:eq)
85
102
  if t.event == :on_op && t.tok == '='
86
103
  body = :oneliner
87
- elsif t.event != :on_embdoc_beg
104
+ else
88
105
  body = :normal
89
106
  end
90
107
  end
91
- if args.include? :args_without_paren
92
- body = :normal if %i[on_semicolon on_nl].include? t.event
108
+ if args.include?(:arg_without_paren)
109
+ if %i[on_semicolon on_nl].include?(t.event)
110
+ # def f a;
111
+ body = :normal
112
+ else
113
+ # def f a, b
114
+ next_args << :arg_without_paren
115
+ end
93
116
  end
94
117
  if body == :oneliner
95
118
  opens.pop
96
119
  elsif body
97
- opens.pop
98
- opens << [last_tok, nil]
120
+ opens[-1] = [last_tok, nil]
99
121
  else
100
- opens.pop
101
- opens << [last_tok, :in_method_head, next_args]
122
+ opens[-1] = [last_tok, :in_method_head, next_args]
102
123
  end
103
124
  end
104
125
  when :in_for_while_until_condition
105
126
  if t.event == :on_semicolon || t.event == :on_nl || (t.event == :on_kw && t.tok == 'do')
106
127
  skip = true if t.event == :on_kw && t.tok == 'do'
107
- opens.pop
108
- opens << [last_tok, nil]
128
+ opens[-1] = [last_tok, nil]
109
129
  end
110
130
  end
111
131
 
@@ -143,6 +163,8 @@ module KatakataIrb::TRex
143
163
  opens << [t, nil]
144
164
  end
145
165
  end
166
+ when :on_tlambda
167
+ opens << [t, :in_lambda_head]
146
168
  when :on_lparen, :on_lbracket, :on_lbrace, :on_tlambeg, :on_embexpr_beg, :on_embdoc_beg
147
169
  opens << [t, nil]
148
170
  when :on_rparen, :on_rbracket, :on_rbrace, :on_embexpr_end, :on_embdoc_end
@@ -171,10 +193,10 @@ module KatakataIrb::TRex
171
193
  first_token_on_line = false
172
194
  end
173
195
  if pending_heredocs.any? && t.tok.include?("\n")
174
- pending_heredocs.reverse_each { opens << [_1, nil] }
196
+ pending_heredocs.reverse_each { |t| opens << [t, nil] }
175
197
  pending_heredocs = []
176
198
  end
177
- yield t, index, opens if block_given?
199
+ yield t, opens if block_given?
178
200
  end
179
201
  opens.map(&:first) + pending_heredocs.reverse
180
202
  end
@@ -184,10 +206,10 @@ module KatakataIrb::TRex
184
206
  prev_opens = []
185
207
  min_depth = 0
186
208
  output = []
187
- last_opens = KatakataIrb::TRex.parse(tokens) do |t, _index, opens|
209
+ last_opens = parse(tokens) do |t, opens|
188
210
  depth = t == opens.last&.first ? opens.size - 1 : opens.size
189
211
  min_depth = depth if depth < min_depth
190
- if t.tok.include? "\n"
212
+ if t.tok.include?("\n")
191
213
  t.tok.each_line do |line|
192
214
  line_tokens << [t, line]
193
215
  next if line[-1] != "\n"
@@ -31,13 +31,13 @@ class KatakataIrb::TypeSimulator
31
31
  fallback = KatakataIrb::Types::NIL
32
32
  case BaseScope.type_by_name name
33
33
  when :cvar
34
- KatakataIrb::TypeSimulator.type_of(fallback:) { @self_object.class_variable_get name }
34
+ KatakataIrb::TypeSimulator.type_of(fallback: fallback) { @self_object.class_variable_get name }
35
35
  when :ivar
36
- KatakataIrb::TypeSimulator.type_of(fallback:) { @self_object.instance_variable_get name }
36
+ KatakataIrb::TypeSimulator.type_of(fallback: fallback) { @self_object.instance_variable_get name }
37
37
  when :lvar
38
- KatakataIrb::TypeSimulator.type_of(fallback:) { @binding.local_variable_get(name) }
38
+ KatakataIrb::TypeSimulator.type_of(fallback: fallback) { @binding.local_variable_get(name) }
39
39
  when :const
40
- KatakataIrb::TypeSimulator.type_of(fallback:) { @binding.eval name }
40
+ KatakataIrb::TypeSimulator.type_of(fallback: fallback) { @binding.eval name }
41
41
  end
42
42
  )
43
43
  end
@@ -85,7 +85,7 @@ class KatakataIrb::TypeSimulator
85
85
  class Scope
86
86
  attr_reader :parent, :jump_branches
87
87
 
88
- def self.from_binding(binding) = new BaseScope.new(binding, binding.eval('self'))
88
+ def self.from_binding(binding) = new(BaseScope.new(binding, binding.eval('self')))
89
89
 
90
90
  def initialize(parent, table = {}, trace_cvar: true, trace_ivar: true, trace_lvar: true, passthrough: false)
91
91
  @tables = [table]
@@ -243,8 +243,8 @@ class KatakataIrb::TypeSimulator
243
243
  refine Ripper::Lexer::Elem do
244
244
  def deconstruct_keys(_keys)
245
245
  {
246
- tok:,
247
- event:,
246
+ tok: tok,
247
+ event: event,
248
248
  label: state.allbits?(Ripper::EXPR_LABEL),
249
249
  beg: state.allbits?(Ripper::EXPR_BEG),
250
250
  dot: state.allbits?(Ripper::EXPR_DOT)
@@ -280,7 +280,7 @@ class KatakataIrb::TypeSimulator
280
280
  end
281
281
 
282
282
  def simulate_evaluate(sexp, scope, case_target: nil)
283
- result = simulate_evaluate_inner(sexp, scope, case_target:)
283
+ result = simulate_evaluate_inner(sexp, scope, case_target: case_target)
284
284
  @dig_targets.resolve result, scope if @dig_targets.target?(sexp)
285
285
  result
286
286
  end
@@ -293,7 +293,7 @@ class KatakataIrb::TypeSimulator
293
293
  sexp in [:def, _method_name_exp, params, body_stmt]
294
294
  sexp in [:defs, receiver_exp, _dot_exp, _method_name_exp, params, body_stmt]
295
295
  if receiver_exp
296
- receiver_exp in [:paren, receiver_exp]
296
+ receiver_exp in [:paren, receiver_exp]
297
297
  self_type = simulate_evaluate receiver_exp, scope
298
298
  else
299
299
  current_self_types = scope.self_type.types
@@ -407,6 +407,9 @@ class KatakataIrb::TypeSimulator
407
407
  KatakataIrb::Types::InstanceType.new Hash, K: KatakataIrb::Types::UnionType[*keys], V: KatakataIrb::Types::UnionType[*values]
408
408
  in [:hash, nil]
409
409
  KatakataIrb::Types::InstanceType.new Hash
410
+ in [:paren, [Symbol,] | false => statement]
411
+ # workaround for `p ()` and `p (foo)`
412
+ simulate_evaluate statement, scope if statement
410
413
  in [:paren | :ensure | :else, statements]
411
414
  statements.map { simulate_evaluate _1, scope }.last
412
415
  in [:const_path_ref, receiver, [:@const, name,]]
@@ -574,6 +577,7 @@ class KatakataIrb::TypeSimulator
574
577
  simulate_evaluate target, scope
575
578
  simulate_evaluate value, scope
576
579
  in [:massign, targets, value]
580
+ targets in [:mlhs, *targets] # (a,b) = value
577
581
  rhs = simulate_evaluate value, scope
578
582
  evaluate_massign targets, rhs, scope
579
583
  rhs
@@ -631,6 +635,8 @@ class KatakataIrb::TypeSimulator
631
635
  KatakataIrb::Types::OBJECT
632
636
  in [:redo | :retry]
633
637
  scope.terminate
638
+ in [:zsuper]
639
+ KatakataIrb::Types::OBJECT
634
640
  in [:super, args]
635
641
  args, kwargs, _block = retrieve_method_args args
636
642
  args.each do |arg|
@@ -717,7 +723,7 @@ class KatakataIrb::TypeSimulator
717
723
  end
718
724
  else_branch = lambda do
719
725
  pattern.each { simulate_evaluate _1, scope }
720
- simulate_evaluate(else_statement, scope, case_target:)
726
+ simulate_evaluate(else_statement, scope, case_target: case_target)
721
727
  end
722
728
  if if_statements && else_statement
723
729
  KatakataIrb::Types::UnionType[*scope.run_branches(if_branch, else_branch)]
@@ -737,7 +743,7 @@ class KatakataIrb::TypeSimulator
737
743
  },
738
744
  -> {
739
745
  pattern_scope.merge_jumps
740
- else_statement ? simulate_evaluate(else_statement, scope, case_target:) : KatakataIrb::Types::NIL
746
+ else_statement ? simulate_evaluate(else_statement, scope, case_target: case_target) : KatakataIrb::Types::NIL
741
747
  }
742
748
  )
743
749
  KatakataIrb::Types::UnionType[*results]
@@ -1037,6 +1043,14 @@ class KatakataIrb::TypeSimulator
1037
1043
  types = type_breaks.map(&:first)
1038
1044
  breaks = type_breaks.map(&:last).compact
1039
1045
  types << OBJECT_METHODS[method_name.to_sym] if name_match && OBJECT_METHODS.has_key?(method_name.to_sym)
1046
+
1047
+ if method_name.to_sym == :new
1048
+ receiver.types.each do |type|
1049
+ if (type in KatakataIrb::Types::SingletonType) && type.module_or_class.is_a?(Class)
1050
+ types << KatakataIrb::Types::InstanceType.new(type.module_or_class)
1051
+ end
1052
+ end
1053
+ end
1040
1054
  KatakataIrb::Types::UnionType[*types, *breaks]
1041
1055
  end
1042
1056
 
@@ -85,23 +85,26 @@ module KatakataIrb::Types
85
85
 
86
86
  def self.type_from_object(object, max_level: 4)
87
87
  max_level -= 1
88
+ sample_size = 1000
88
89
  case object
89
90
  when Array
91
+ values = object.size > sample_size ? object.sample(sample_size) : object
90
92
  if max_level > 0
91
- values = object.map { type_from_object(_1, max_level:) }
92
- InstanceType.new Array, { Elem: UnionType[*values] }
93
+ InstanceType.new Array, { Elem: UnionType[*values.map { type_from_object(_1, max_level: max_level) }] }
93
94
  else
94
- InstanceType.new Array, { Elem: UnionType[*object.map(&:class).uniq.map { InstanceType.new _1 }] }
95
+ InstanceType.new Array, { Elem: UnionType[*values.map(&:class).uniq.map { InstanceType.new _1 }] }
95
96
  end
96
97
  when Hash
98
+ keys = object.size > sample_size ? object.keys.sample(sample_size) : object.keys
99
+ values = object.size > sample_size ? object.values.sample(sample_size) : object.values
97
100
  if max_level > 0
98
- keys = object.keys.map { type_from_object(_1, max_level:) }
99
- values = object.values.map { type_from_object(_1, max_level:) }
100
- InstanceType.new Hash, { K: UnionType[*keys], V: UnionType[*values] }
101
+ key_types = keys.map { type_from_object(_1, max_level: max_level) }
102
+ value_types = values.map { type_from_object(_1, max_level: max_level) }
103
+ InstanceType.new Hash, { K: UnionType[*key_types], V: UnionType[*value_types] }
101
104
  else
102
- keys = object.keys.map(&:class).uniq.map { InstanceType.new _1 }
103
- values = object.values.map(&:class).uniq.map { InstanceType.new _1 }
104
- InstanceType.new Hash, { K: UnionType[*keys], V: UnionType[*values] }
105
+ key_types = keys.map(&:class).uniq.map { InstanceType.new _1 }
106
+ value_types = values.map(&:class).uniq.map { InstanceType.new _1 }
107
+ InstanceType.new Hash, { K: UnionType[*key_types], V: UnionType[*value_types] }
105
108
  end
106
109
  when Module
107
110
  SingletonType.new object
@@ -117,7 +120,7 @@ module KatakataIrb::Types
117
120
  end
118
121
  def transform() = yield(self)
119
122
  def methods() = @module_or_class.methods
120
- def all_methods() = methods
123
+ def all_methods() = methods | Kernel.methods
121
124
  def constants() = @module_or_class.constants
122
125
  def types() = [self]
123
126
  end
@@ -294,19 +297,13 @@ module KatakataIrb::Types
294
297
  # unimplemented
295
298
  OBJECT
296
299
  when RBS::Types::ClassInstance
297
- classes = self_type.types.filter_map do |type|
298
- type.module_or_class if (type in SingletonType) && type.module_or_class.is_a?(Class)
299
- end
300
- if classes.empty?
301
- klass = return_type.name.to_namespace.path.reduce(Object) { _1.const_get _2 }
302
- classes << klass if klass in Class
303
- end
300
+ klass = return_type.name.to_namespace.path.reduce(Object) { _1.const_get _2 }
304
301
  if return_type.args
305
302
  args = return_type.args.map { from_rbs_type _1, self_type, extra_vars }
306
303
  names = rbs_builder.build_singleton(return_type.name).type_params
307
304
  params = names.map.with_index { [_1, args[_2] || OBJECT] }.to_h
308
305
  end
309
- UnionType[*classes.map { InstanceType.new _1, params || {} }]
306
+ InstanceType.new klass, params || {}
310
307
  end
311
308
  end
312
309
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KatakataIrb
4
- VERSION = "0.1.2"
4
+ VERSION = "0.1.4"
5
5
  end
data/lib/katakata_irb.rb CHANGED
@@ -1,11 +1,7 @@
1
- require 'io/console'
2
- module KatakataIrb
3
- def self.repl
4
- require 'katakata_irb/completor'
5
- KatakataIrb::Completor.setup
6
- IRB.start(__FILE__)
7
- end
1
+ require 'katakata_irb/version'
2
+ require 'katakata_irb/completor'
8
3
 
4
+ module KatakataIrb
9
5
  def self.log_output=(output)
10
6
  @log_output = output
11
7
  end
@@ -14,3 +10,5 @@ module KatakataIrb
14
10
  STDOUT.cooked { @log_output&.puts(...) }
15
11
  end
16
12
  end
13
+
14
+ KatakataIrb::Completor.setup
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: katakata_irb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - tompng
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-12-20 00:00:00.000000000 Z
11
+ date: 2023-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: irb
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.4.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.4.0
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rbs
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -27,8 +41,7 @@ dependencies:
27
41
  description: IRB with Typed Completion
28
42
  email:
29
43
  - tomoyapenguin@gmail.com
30
- executables:
31
- - kirb
44
+ executables: []
32
45
  extensions: []
33
46
  extra_rdoc_files: []
34
47
  files:
@@ -39,19 +52,10 @@ files:
39
52
  - Rakefile
40
53
  - bin/console
41
54
  - bin/setup
42
- - exe/kirb
43
55
  - katakata_irb.gemspec
44
56
  - lib/katakata_irb.rb
45
57
  - lib/katakata_irb/completor.rb
46
- - lib/katakata_irb/reline_patch.rb
47
- - lib/katakata_irb/reline_patches/escapeseq.patch
48
- - lib/katakata_irb/reline_patches/fullwidth.patch
49
- - lib/katakata_irb/reline_patches/indent.patch
50
- - lib/katakata_irb/reline_patches/raw.patch
51
- - lib/katakata_irb/reline_patches/scrollbar.patch
52
- - lib/katakata_irb/reline_patches/wholelines.patch
53
- - lib/katakata_irb/ruby_lex_patch.rb
54
- - lib/katakata_irb/trex.rb
58
+ - lib/katakata_irb/nesting_parser.rb
55
59
  - lib/katakata_irb/type_simulator.rb
56
60
  - lib/katakata_irb/types.rb
57
61
  - lib/katakata_irb/version.rb
@@ -70,14 +74,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
70
74
  requirements:
71
75
  - - ">="
72
76
  - !ruby/object:Gem::Version
73
- version: 3.1.0
77
+ version: 3.0.0
74
78
  required_rubygems_version: !ruby/object:Gem::Requirement
75
79
  requirements:
76
80
  - - ">="
77
81
  - !ruby/object:Gem::Version
78
82
  version: '0'
79
83
  requirements: []
80
- rubygems_version: 3.3.3
84
+ rubygems_version: 3.4.5
81
85
  signing_key:
82
86
  specification_version: 4
83
87
  summary: IRB with Typed Completion