irb 1.7.0 → 1.7.1

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: fa3c9603f48d730988d34f454a10b58021caa677ab8832d9764e39e61bb49abb
4
- data.tar.gz: c46d1e32c81a8f22593e174af095070159af6a61508c97b3ef4b0b9d28301d58
3
+ metadata.gz: d8dc3e14a57010a1ece61f5ca0111e98742f29daea5ab1ad1bdc48e0de6e55b2
4
+ data.tar.gz: 7da9b8c9e3e3c68384c0f65eb030d7874c8f0d07c20ce651ab7b54f5bfdfb9bd
5
5
  SHA512:
6
- metadata.gz: 3e99185c909180d01a3310f7db11437181268b930d267f2fe365c06cd7a442ad3a8cdf7d5863fb19e17885a23aad46b993a2e5c21fb8632ff2f91285e469be4b
7
- data.tar.gz: 44978be86d00d0fc435e81e4cadc5abad08d47519a189db02e34d7eb3435e9ac0cc0adf470e845edba1e7d866574298e1b7b8bba5190d8be538c396cd0179d07
6
+ metadata.gz: 73173c7af8ffa50bfa26a49ad1c2b7a2db12a89b006980b2b0d649bc6a03b776359ce03d20a9a7dde493c3c64e70e85864809436b546b571f23e77774748f35e
7
+ data.tar.gz: 371777b42d560af3196092e98555a46d9c93c4efa592e8f38365dd0f5be6863ea4a50d6160baedf7d7d7c6914087394cde33e0fd57e17bec68a63f64f8265a89
@@ -11,24 +11,20 @@ module IRB
11
11
  description "Show information about IRB."
12
12
 
13
13
  def execute
14
- Class.new {
15
- def inspect
16
- str = "Ruby version: #{RUBY_VERSION}\n"
17
- str += "IRB version: #{IRB.version}\n"
18
- str += "InputMethod: #{IRB.CurrentContext.io.inspect}\n"
19
- str += ".irbrc path: #{IRB.rc_file}\n" if File.exist?(IRB.rc_file)
20
- str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n"
21
- str += "LANG env: #{ENV["LANG"]}\n" if ENV["LANG"] && !ENV["LANG"].empty?
22
- str += "LC_ALL env: #{ENV["LC_ALL"]}\n" if ENV["LC_ALL"] && !ENV["LC_ALL"].empty?
23
- str += "East Asian Ambiguous Width: #{Reline.ambiguous_width.inspect}\n"
24
- if RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
25
- codepage = `chcp`.b.sub(/.*: (\d+)\n/, '\1')
26
- str += "Code page: #{codepage}\n"
27
- end
28
- str
29
- end
30
- alias_method :to_s, :inspect
31
- }.new
14
+ str = "Ruby version: #{RUBY_VERSION}\n"
15
+ str += "IRB version: #{IRB.version}\n"
16
+ str += "InputMethod: #{IRB.CurrentContext.io.inspect}\n"
17
+ str += ".irbrc path: #{IRB.rc_file}\n" if File.exist?(IRB.rc_file)
18
+ str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n"
19
+ str += "LANG env: #{ENV["LANG"]}\n" if ENV["LANG"] && !ENV["LANG"].empty?
20
+ str += "LC_ALL env: #{ENV["LC_ALL"]}\n" if ENV["LC_ALL"] && !ENV["LC_ALL"].empty?
21
+ str += "East Asian Ambiguous Width: #{Reline.ambiguous_width.inspect}\n"
22
+ if RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
23
+ codepage = `chcp`.b.sub(/.*: (\d+)\n/, '\1')
24
+ str += "Code page: #{codepage}\n"
25
+ end
26
+ puts str
27
+ nil
32
28
  end
33
29
  end
34
30
  end
data/lib/irb/cmd/nop.rb CHANGED
@@ -30,23 +30,19 @@ module IRB
30
30
  end
31
31
  end
32
32
 
33
- def self.execute(conf, *opts, **kwargs, &block)
34
- command = new(conf)
33
+ def self.execute(irb_context, *opts, **kwargs, &block)
34
+ command = new(irb_context)
35
35
  command.execute(*opts, **kwargs, &block)
36
36
  rescue CommandArgumentError => e
37
37
  puts e.message
38
38
  end
39
39
 
40
- def initialize(conf)
41
- @irb_context = conf
40
+ def initialize(irb_context)
41
+ @irb_context = irb_context
42
42
  end
43
43
 
44
44
  attr_reader :irb_context
45
45
 
46
- def irb
47
- @irb_context.irb
48
- end
49
-
50
46
  def execute(*opts)
51
47
  #nop
52
48
  end
@@ -58,9 +58,9 @@ module IRB
58
58
  tokens.chunk { |tok| tok.pos[0] }.each do |lnum, chunk|
59
59
  code = lines[0..lnum].join
60
60
  prev_tokens.concat chunk
61
- continue = lex.process_continue(prev_tokens)
62
- code_block_open = lex.check_code_block(code, prev_tokens)
63
- if !continue && !code_block_open
61
+ continue = lex.should_continue?(prev_tokens)
62
+ syntax = lex.check_code_syntax(code)
63
+ if !continue && syntax == :valid
64
64
  return first_line + lnum
65
65
  end
66
66
  end
@@ -218,7 +218,7 @@ module IRB
218
218
  else
219
219
  sym = $1
220
220
  candidates = Symbol.all_symbols.collect do |s|
221
- ":" + s.id2name.encode(Encoding.default_external)
221
+ s.inspect
222
222
  rescue EncodingError
223
223
  # ignore
224
224
  end
@@ -233,7 +233,7 @@ module IRB
233
233
  if doc_namespace
234
234
  candidates.find { |i| i == receiver }
235
235
  else
236
- candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
236
+ candidates.grep(/^#{Regexp.quote(receiver)}/).collect{|e| "::" + e}
237
237
  end
238
238
 
239
239
  when /^([A-Z].*)::([^:.]*)$/
data/lib/irb/context.rb CHANGED
@@ -473,28 +473,31 @@ module IRB
473
473
  @inspect_mode
474
474
  end
475
475
 
476
- def evaluate(line, line_no, exception: nil) # :nodoc:
476
+ def evaluate(line, line_no) # :nodoc:
477
477
  @line_no = line_no
478
- if exception
479
- line_no -= 1
480
- line = "begin ::Kernel.raise _; rescue _.class\n#{line}\n""end"
481
- @workspace.local_variable_set(:_, exception)
482
- end
478
+ result = nil
483
479
 
484
- # Transform a non-identifier alias (@, $) or keywords (next, break)
485
- command, args = line.split(/\s/, 2)
486
- if original = command_aliases[command.to_sym]
487
- line = line.gsub(/\A#{Regexp.escape(command)}/, original.to_s)
488
- command = original
480
+ if IRB.conf[:MEASURE] && IRB.conf[:MEASURE_CALLBACKS].empty?
481
+ IRB.set_measure_callback
489
482
  end
490
483
 
491
- # Hook command-specific transformation
492
- command_class = ExtendCommandBundle.load_command(command)
493
- if command_class&.respond_to?(:transform_args)
494
- line = "#{command} #{command_class.transform_args(args)}"
484
+ if IRB.conf[:MEASURE] && !IRB.conf[:MEASURE_CALLBACKS].empty?
485
+ last_proc = proc do
486
+ result = @workspace.evaluate(line, irb_path, line_no)
487
+ end
488
+ IRB.conf[:MEASURE_CALLBACKS].inject(last_proc) do |chain, item|
489
+ _name, callback, arg = item
490
+ proc do
491
+ callback.(self, line, line_no, arg) do
492
+ chain.call
493
+ end
494
+ end
495
+ end.call
496
+ else
497
+ result = @workspace.evaluate(line, irb_path, line_no)
495
498
  end
496
499
 
497
- set_last_value(@workspace.evaluate(line, irb_path, line_no))
500
+ set_last_value(result)
498
501
  end
499
502
 
500
503
  def inspect_last_value # :nodoc:
@@ -42,6 +42,7 @@ module IRB # :nodoc:
42
42
  #
43
43
  # See Irb#suspend_input_method for more information.
44
44
  def source_file(path)
45
+ irb = irb_context.irb
45
46
  irb.suspend_name(path, File.basename(path)) do
46
47
  FileInputMethod.open(path) do |io|
47
48
  irb.suspend_input_method(io) do
@@ -66,6 +67,7 @@ module IRB # :nodoc:
66
67
  #
67
68
  # See Irb#suspend_input_method for more information.
68
69
  def load_file(path, priv = nil)
70
+ irb = irb_context.irb
69
71
  irb.suspend_name(path, File.basename(path)) do
70
72
 
71
73
  if priv
@@ -289,7 +289,7 @@ module IRB # :nodoc:
289
289
  alias_method to, from
290
290
  }
291
291
  else
292
- Kernel.print "irb: warn: can't alias #{to} from #{from}.\n"
292
+ Kernel.warn "irb: warn: can't alias #{to} from #{from}.\n"
293
293
  end
294
294
  end
295
295
 
@@ -0,0 +1,227 @@
1
+ # frozen_string_literal: true
2
+ module IRB
3
+ module NestingParser
4
+ IGNORE_TOKENS = %i[on_sp on_ignored_nl on_comment on_embdoc_beg on_embdoc on_embdoc_end]
5
+
6
+ # Scan each token and call the given block with array of token and other information for parsing
7
+ def self.scan_opens(tokens)
8
+ opens = []
9
+ pending_heredocs = []
10
+ first_token_on_line = true
11
+ tokens.each do |t|
12
+ skip = false
13
+ last_tok, state, args = opens.last
14
+ case state
15
+ when :in_unquoted_symbol
16
+ unless IGNORE_TOKENS.include?(t.event)
17
+ opens.pop
18
+ skip = true
19
+ end
20
+ when :in_lambda_head
21
+ opens.pop if t.event == :on_tlambeg || (t.event == :on_kw && t.tok == 'do')
22
+ when :in_method_head
23
+ unless IGNORE_TOKENS.include?(t.event)
24
+ next_args = []
25
+ body = nil
26
+ if args.include?(:receiver)
27
+ case t.event
28
+ when :on_lparen, :on_ivar, :on_gvar, :on_cvar
29
+ # def (receiver). | def @ivar. | def $gvar. | def @@cvar.
30
+ next_args << :dot
31
+ when :on_kw
32
+ case t.tok
33
+ when 'self', 'true', 'false', 'nil'
34
+ # def self(arg) | def self.
35
+ next_args.push(:arg, :dot)
36
+ else
37
+ # def if(arg)
38
+ skip = true
39
+ next_args << :arg
40
+ end
41
+ when :on_op, :on_backtick
42
+ # def +(arg)
43
+ skip = true
44
+ next_args << :arg
45
+ when :on_ident, :on_const
46
+ # def a(arg) | def a.
47
+ next_args.push(:arg, :dot)
48
+ end
49
+ end
50
+ if args.include?(:dot)
51
+ # def receiver.name
52
+ next_args << :name if t.event == :on_period || (t.event == :on_op && t.tok == '::')
53
+ end
54
+ if args.include?(:name)
55
+ if %i[on_ident on_const on_op on_kw on_backtick].include?(t.event)
56
+ # def name(arg) | def receiver.name(arg)
57
+ next_args << :arg
58
+ skip = true
59
+ end
60
+ end
61
+ if args.include?(:arg)
62
+ case t.event
63
+ when :on_nl, :on_semicolon
64
+ # def recever.f;
65
+ body = :normal
66
+ when :on_lparen
67
+ # def recever.f()
68
+ next_args << :eq
69
+ else
70
+ if t.event == :on_op && t.tok == '='
71
+ # def receiver.f =
72
+ body = :oneliner
73
+ else
74
+ # def recever.f arg
75
+ next_args << :arg_without_paren
76
+ end
77
+ end
78
+ end
79
+ if args.include?(:eq)
80
+ if t.event == :on_op && t.tok == '='
81
+ body = :oneliner
82
+ else
83
+ body = :normal
84
+ end
85
+ end
86
+ if args.include?(:arg_without_paren)
87
+ if %i[on_semicolon on_nl].include?(t.event)
88
+ # def f a;
89
+ body = :normal
90
+ else
91
+ # def f a, b
92
+ next_args << :arg_without_paren
93
+ end
94
+ end
95
+ if body == :oneliner
96
+ opens.pop
97
+ elsif body
98
+ opens[-1] = [last_tok, nil]
99
+ else
100
+ opens[-1] = [last_tok, :in_method_head, next_args]
101
+ end
102
+ end
103
+ when :in_for_while_until_condition
104
+ if t.event == :on_semicolon || t.event == :on_nl || (t.event == :on_kw && t.tok == 'do')
105
+ skip = true if t.event == :on_kw && t.tok == 'do'
106
+ opens[-1] = [last_tok, nil]
107
+ end
108
+ end
109
+
110
+ unless skip
111
+ case t.event
112
+ when :on_kw
113
+ case t.tok
114
+ when 'begin', 'class', 'module', 'do', 'case'
115
+ opens << [t, nil]
116
+ when 'end'
117
+ opens.pop
118
+ when 'def'
119
+ opens << [t, :in_method_head, [:receiver, :name]]
120
+ when 'if', 'unless'
121
+ unless t.state.allbits?(Ripper::EXPR_LABEL)
122
+ opens << [t, nil]
123
+ end
124
+ when 'while', 'until'
125
+ unless t.state.allbits?(Ripper::EXPR_LABEL)
126
+ opens << [t, :in_for_while_until_condition]
127
+ end
128
+ when 'ensure', 'rescue'
129
+ unless t.state.allbits?(Ripper::EXPR_LABEL)
130
+ opens.pop
131
+ opens << [t, nil]
132
+ end
133
+ when 'elsif', 'else', 'when'
134
+ opens.pop
135
+ opens << [t, nil]
136
+ when 'for'
137
+ opens << [t, :in_for_while_until_condition]
138
+ when 'in'
139
+ if last_tok&.event == :on_kw && %w[case in].include?(last_tok.tok) && first_token_on_line
140
+ opens.pop
141
+ opens << [t, nil]
142
+ end
143
+ end
144
+ when :on_tlambda
145
+ opens << [t, :in_lambda_head]
146
+ when :on_lparen, :on_lbracket, :on_lbrace, :on_tlambeg, :on_embexpr_beg, :on_embdoc_beg
147
+ opens << [t, nil]
148
+ when :on_rparen, :on_rbracket, :on_rbrace, :on_embexpr_end, :on_embdoc_end
149
+ opens.pop
150
+ when :on_heredoc_beg
151
+ pending_heredocs << t
152
+ when :on_heredoc_end
153
+ opens.pop
154
+ when :on_backtick
155
+ opens << [t, nil] if t.state.allbits?(Ripper::EXPR_BEG)
156
+ when :on_tstring_beg, :on_words_beg, :on_qwords_beg, :on_symbols_beg, :on_qsymbols_beg, :on_regexp_beg
157
+ opens << [t, nil]
158
+ when :on_tstring_end, :on_regexp_end, :on_label_end
159
+ opens.pop
160
+ when :on_symbeg
161
+ if t.tok == ':'
162
+ opens << [t, :in_unquoted_symbol]
163
+ else
164
+ opens << [t, nil]
165
+ end
166
+ end
167
+ end
168
+ if t.event == :on_nl || t.event == :on_semicolon
169
+ first_token_on_line = true
170
+ elsif t.event != :on_sp
171
+ first_token_on_line = false
172
+ end
173
+ if pending_heredocs.any? && t.tok.include?("\n")
174
+ pending_heredocs.reverse_each { |t| opens << [t, nil] }
175
+ pending_heredocs = []
176
+ end
177
+ yield t, opens if block_given?
178
+ end
179
+ opens.map(&:first) + pending_heredocs.reverse
180
+ end
181
+
182
+ def self.open_tokens(tokens)
183
+ # scan_opens without block will return a list of open tokens at last token position
184
+ scan_opens(tokens)
185
+ end
186
+
187
+ # Calculates token information [line_tokens, prev_opens, next_opens, min_depth] for each line.
188
+ # Example code
189
+ # ["hello
190
+ # world"+(
191
+ # First line
192
+ # line_tokens: [[lbracket, '['], [tstring_beg, '"'], [tstring_content("hello\nworld"), "hello\n"]]
193
+ # prev_opens: []
194
+ # next_tokens: [lbracket, tstring_beg]
195
+ # min_depth: 0 (minimum at beginning of line)
196
+ # Second line
197
+ # line_tokens: [[tstring_content("hello\nworld"), "world"], [tstring_end, '"'], [op, '+'], [lparen, '(']]
198
+ # prev_opens: [lbracket, tstring_beg]
199
+ # next_tokens: [lbracket, lparen]
200
+ # min_depth: 1 (minimum just after tstring_end)
201
+ def self.parse_by_line(tokens)
202
+ line_tokens = []
203
+ prev_opens = []
204
+ min_depth = 0
205
+ output = []
206
+ last_opens = scan_opens(tokens) do |t, opens|
207
+ depth = t == opens.last&.first ? opens.size - 1 : opens.size
208
+ min_depth = depth if depth < min_depth
209
+ if t.tok.include?("\n")
210
+ t.tok.each_line do |line|
211
+ line_tokens << [t, line]
212
+ next if line[-1] != "\n"
213
+ next_opens = opens.map(&:first)
214
+ output << [line_tokens, prev_opens, next_opens, min_depth]
215
+ prev_opens = next_opens
216
+ min_depth = prev_opens.size
217
+ line_tokens = []
218
+ end
219
+ else
220
+ line_tokens << [t, t.tok]
221
+ end
222
+ end
223
+ output << [line_tokens, prev_opens, last_opens, min_depth] if line_tokens.any?
224
+ output
225
+ end
226
+ end
227
+ end