Skip to content

Commit 77a144d

Browse files
committed
[GR-27687] Update to irb 1.3.3 and reline 0.2.3
PullRequest: truffleruby/2478
2 parents 6026ead + 15cdf9a commit 77a144d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+4676
-1835
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ Performance:
7575
* We now create a single call target per block by default instead of two.
7676
* Some uses of class variables are now much better optimized (#2259, @chrisseaton).
7777
* Several methods that need the caller frame are now always inlined in their caller, which speeds up the interpreter and reduces footprint.
78+
* Pasting code in IRB should be reasonably fast, by updating to `irb` 1.3.3 and `reline` 0.2.3 (#2233).
7879

7980
Changes:
8081

doc/contributor/updating-ruby.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@ have to MRI source code while updating.
88
You can re-run these instructions at any time to compare against unmodified
99
MRI files.
1010

11+
## Updating a specific default gem
12+
13+
To update a specific default gem to a newer version than in the MRI release, run:
14+
```
15+
cd ruby
16+
git checkout -b truffleruby-updates-$VERSION vn_n_n
17+
ruby tool/sync_default_gems.rb $GEM
18+
```
19+
to update the default gem in MRI.
20+
Then follow the instructions below to reimport MRI files and to update default gems.
21+
1122
## Setup
1223

1324
Set the environment variable `$VERSION` to the target version:
File renamed without changes.

lib/gems/specifications/default/irb-1.2.6.gemspec renamed to lib/gems/specifications/default/irb-1.3.3.gemspec

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
# -*- encoding: utf-8 -*-
2-
# stub: irb 1.2.6 ruby lib
2+
# stub: irb 1.3.3 ruby lib
33

44
Gem::Specification.new do |s|
55
s.name = "irb".freeze
6-
s.version = "1.2.6"
6+
s.version = "1.3.3"
77

88
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
99
s.require_paths = ["lib".freeze]
1010
s.authors = ["Keiju ISHITSUKA".freeze]
1111
s.bindir = "exe".freeze
12-
s.date = "2020-11-04"
12+
s.date = "2021-03-08"
1313
s.description = "Interactive Ruby command-line tool for REPL (Read Eval Print Loop).".freeze
1414
s.email = ["[email protected]".freeze]
1515
s.executables = ["irb".freeze]
16-
s.files = ["exe/irb".freeze, "irb.rb".freeze, "irb/cmd/chws.rb".freeze, "irb/cmd/fork.rb".freeze, "irb/cmd/help.rb".freeze, "irb/cmd/info.rb".freeze, "irb/cmd/load.rb".freeze, "irb/cmd/nop.rb".freeze, "irb/cmd/pushws.rb".freeze, "irb/cmd/subirb.rb".freeze, "irb/color.rb".freeze, "irb/completion.rb".freeze, "irb/context.rb".freeze, "irb/easter-egg.rb".freeze, "irb/ext/change-ws.rb".freeze, "irb/ext/history.rb".freeze, "irb/ext/loader.rb".freeze, "irb/ext/multi-irb.rb".freeze, "irb/ext/save-history.rb".freeze, "irb/ext/tracer.rb".freeze, "irb/ext/use-loader.rb".freeze, "irb/ext/workspaces.rb".freeze, "irb/extend-command.rb".freeze, "irb/frame.rb".freeze, "irb/help.rb".freeze, "irb/init.rb".freeze, "irb/input-method.rb".freeze, "irb/inspector.rb".freeze, "irb/lc/error.rb".freeze, "irb/lc/ja/encoding_aliases.rb".freeze, "irb/lc/ja/error.rb".freeze, "irb/locale.rb".freeze, "irb/magic-file.rb".freeze, "irb/notifier.rb".freeze, "irb/output-method.rb".freeze, "irb/ruby-lex.rb".freeze, "irb/src_encoding.rb".freeze, "irb/version.rb".freeze, "irb/workspace.rb".freeze, "irb/ws-for-case-2.rb".freeze, "irb/xmp.rb".freeze]
16+
s.files = ["exe/irb".freeze, "irb.rb".freeze, "irb/cmd/chws.rb".freeze, "irb/cmd/fork.rb".freeze, "irb/cmd/help.rb".freeze, "irb/cmd/info.rb".freeze, "irb/cmd/load.rb".freeze, "irb/cmd/measure.rb".freeze, "irb/cmd/nop.rb".freeze, "irb/cmd/pushws.rb".freeze, "irb/cmd/subirb.rb".freeze, "irb/color.rb".freeze, "irb/color_printer.rb".freeze, "irb/completion.rb".freeze, "irb/context.rb".freeze, "irb/easter-egg.rb".freeze, "irb/ext/change-ws.rb".freeze, "irb/ext/history.rb".freeze, "irb/ext/loader.rb".freeze, "irb/ext/multi-irb.rb".freeze, "irb/ext/save-history.rb".freeze, "irb/ext/tracer.rb".freeze, "irb/ext/use-loader.rb".freeze, "irb/ext/workspaces.rb".freeze, "irb/extend-command.rb".freeze, "irb/frame.rb".freeze, "irb/help.rb".freeze, "irb/init.rb".freeze, "irb/input-method.rb".freeze, "irb/inspector.rb".freeze, "irb/lc/error.rb".freeze, "irb/lc/ja/encoding_aliases.rb".freeze, "irb/lc/ja/error.rb".freeze, "irb/locale.rb".freeze, "irb/magic-file.rb".freeze, "irb/notifier.rb".freeze, "irb/output-method.rb".freeze, "irb/ruby-lex.rb".freeze, "irb/src_encoding.rb".freeze, "irb/version.rb".freeze, "irb/workspace.rb".freeze, "irb/ws-for-case-2.rb".freeze, "irb/xmp.rb".freeze]
1717
s.homepage = "https://github.com/ruby/irb".freeze
1818
s.licenses = ["Ruby".freeze, "BSD-2-Clause".freeze]
1919
s.required_ruby_version = Gem::Requirement.new(">= 2.5".freeze)

lib/gems/specifications/default/reline-0.1.5.gemspec renamed to lib/gems/specifications/default/reline-0.2.3.gemspec

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# -*- encoding: utf-8 -*-
2-
# stub: reline 0.1.5 ruby lib
2+
# stub: reline 0.2.3 ruby lib
33

44
Gem::Specification.new do |s|
55
s.name = "reline".freeze
6-
s.version = "0.1.5"
6+
s.version = "0.2.3"
77

88
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
99
s.require_paths = ["lib".freeze]
1010
s.authors = ["aycabta".freeze]
11-
s.date = "2020-11-04"
11+
s.date = "2021-03-08"
1212
s.description = "Alternative GNU Readline or Editline implementation by pure Ruby.".freeze
1313
s.email = ["[email protected]".freeze]
1414
s.files = ["reline.rb".freeze, "reline/ansi.rb".freeze, "reline/config.rb".freeze, "reline/general_io.rb".freeze, "reline/history.rb".freeze, "reline/key_actor.rb".freeze, "reline/key_actor/base.rb".freeze, "reline/key_actor/emacs.rb".freeze, "reline/key_actor/vi_command.rb".freeze, "reline/key_actor/vi_insert.rb".freeze, "reline/key_stroke.rb".freeze, "reline/kill_ring.rb".freeze, "reline/line_editor.rb".freeze, "reline/unicode.rb".freeze, "reline/unicode/east_asian_width.rb".freeze, "reline/version.rb".freeze, "reline/windows.rb".freeze]
@@ -27,10 +27,12 @@ Gem::Specification.new do |s|
2727
s.add_development_dependency(%q<bundler>.freeze, [">= 0"])
2828
s.add_development_dependency(%q<rake>.freeze, [">= 0"])
2929
s.add_development_dependency(%q<test-unit>.freeze, [">= 0"])
30+
s.add_development_dependency(%q<yamatanooroti>.freeze, [">= 0.0.6"])
3031
else
3132
s.add_dependency(%q<io-console>.freeze, ["~> 0.5"])
3233
s.add_dependency(%q<bundler>.freeze, [">= 0"])
3334
s.add_dependency(%q<rake>.freeze, [">= 0"])
3435
s.add_dependency(%q<test-unit>.freeze, [">= 0"])
36+
s.add_dependency(%q<yamatanooroti>.freeze, [">= 0.0.6"])
3537
end
3638
end

lib/mri/irb.rb

Lines changed: 81 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ def IRB.start(ap_path = nil)
400400
irb.run(@CONF)
401401
end
402402

403-
# Calls each event hook of <code>IRB.conf[:TA_EXIT]</code> when the current session quits.
403+
# Calls each event hook of <code>IRB.conf[:AT_EXIT]</code> when the current session quits.
404404
def IRB.irb_at_exit
405405
@CONF[:AT_EXIT].each{|hook| hook.call}
406406
end
@@ -525,7 +525,7 @@ def eval_input
525525
printf "Use \"exit\" to leave %s\n", @context.ap_name
526526
end
527527
else
528-
print "\n"
528+
print "\n" if @context.prompting?
529529
end
530530
end
531531
l
@@ -538,11 +538,28 @@ def eval_input
538538
signal_status(:IN_EVAL) do
539539
begin
540540
line.untaint if RUBY_VERSION < '2.7'
541-
@context.evaluate(line, line_no, exception: exc)
541+
if IRB.conf[:MEASURE] && IRB.conf[:MEASURE_CALLBACKS].empty?
542+
IRB.set_measure_callback
543+
end
544+
if IRB.conf[:MEASURE] && !IRB.conf[:MEASURE_CALLBACKS].empty?
545+
result = nil
546+
last_proc = proc{ result = @context.evaluate(line, line_no, exception: exc) }
547+
IRB.conf[:MEASURE_CALLBACKS].inject(last_proc) { |chain, item|
548+
_name, callback, arg = item
549+
proc {
550+
callback.(@context, line, line_no, arg, exception: exc) do
551+
chain.call
552+
end
553+
}
554+
}.call
555+
@context.set_last_value(result)
556+
else
557+
@context.evaluate(line, line_no, exception: exc)
558+
end
542559
if @context.echo?
543560
if assignment_expression?(line)
544561
if @context.echo_on_assignment?
545-
output_value(@context.omit_on_assignment?)
562+
output_value(@context.echo_on_assignment? == :truncate)
546563
end
547564
else
548565
output_value
@@ -557,10 +574,35 @@ def eval_input
557574
next
558575
end
559576
handle_exception(exc)
577+
@context.workspace.local_variable_set(:_, exc)
578+
exc = nil
560579
end
561580
end
562581
end
563582

583+
def convert_invalid_byte_sequence(str)
584+
str = str.force_encoding(Encoding::ASCII_8BIT)
585+
conv = Encoding::Converter.new(Encoding::ASCII_8BIT, Encoding::UTF_8)
586+
dst = String.new
587+
begin
588+
ret = conv.primitive_convert(str, dst)
589+
case ret
590+
when :invalid_byte_sequence
591+
conv.insert_output(conf.primitive_errinfo[3].dump[1..-2])
592+
redo
593+
when :undefined_conversion
594+
c = conv.primitive_errinfo[3].dup.force_encoding(conv.primitive_errinfo[1])
595+
conv.insert_output(c.dump[1..-2])
596+
redo
597+
when :incomplete_input
598+
conv.insert_output(conv.primitive_errinfo[3].dump[1..-2])
599+
when :finished
600+
end
601+
break
602+
end while nil
603+
dst
604+
end
605+
564606
def handle_exception(exc)
565607
if exc.backtrace && exc.backtrace[0] =~ /\/irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
566608
!(SyntaxError === exc) && !(EncodingError === exc)
@@ -570,49 +612,44 @@ def handle_exception(exc)
570612
irb_bug = false
571613
end
572614

573-
if STDOUT.tty?
574-
attr = ATTR_TTY
575-
print "#{attr[1]}Traceback#{attr[]} (most recent call last):\n"
576-
else
577-
attr = ATTR_PLAIN
578-
end
579-
messages = []
580-
lasts = []
581-
levels = 0
582615
if exc.backtrace
583-
count = 0
584-
exc.backtrace.each do |m|
585-
m = @context.workspace.filter_backtrace(m) or next unless irb_bug
586-
count += 1
587-
if attr == ATTR_TTY
588-
m = sprintf("%9d: from %s", count, m)
616+
order = nil
617+
if '2.5.0' == RUBY_VERSION
618+
# Exception#full_message doesn't have keyword arguments.
619+
message = exc.full_message # the same of (highlight: true, order: bottom)
620+
order = :bottom
621+
elsif '2.5.1' <= RUBY_VERSION && RUBY_VERSION < '3.0.0'
622+
if STDOUT.tty?
623+
message = exc.full_message(order: :bottom)
624+
order = :bottom
589625
else
590-
m = "\tfrom #{m}"
626+
message = exc.full_message(order: :top)
627+
order = :top
591628
end
592-
if messages.size < @context.back_trace_limit
593-
messages.push(m)
594-
elsif lasts.size < @context.back_trace_limit
595-
lasts.push(m).shift
596-
levels += 1
597-
end
598-
end
599-
end
600-
if attr == ATTR_TTY
601-
unless lasts.empty?
602-
puts lasts.reverse
603-
printf "... %d levels...\n", levels if levels > 0
604-
end
605-
puts messages.reverse
606-
end
607-
m = exc.to_s.split(/\n/)
608-
print "#{attr[1]}#{exc.class} (#{attr[4]}#{m.shift}#{attr[0, 1]})#{attr[]}\n"
609-
puts m.map {|s| "#{attr[1]}#{s}#{attr[]}\n"}
610-
if attr == ATTR_PLAIN
611-
puts messages
612-
unless lasts.empty?
613-
puts lasts
614-
printf "... %d levels...\n", levels if levels > 0
629+
else # '3.0.0' <= RUBY_VERSION
630+
message = exc.full_message(order: :top)
631+
order = :top
615632
end
633+
message = convert_invalid_byte_sequence(message)
634+
message = message.gsub(/((?:^\t.+$\n)+)/) { |m|
635+
case order
636+
when :top
637+
lines = m.split("\n")
638+
when :bottom
639+
lines = m.split("\n").reverse
640+
end
641+
unless irb_bug
642+
lines = lines.map { |l| @context.workspace.filter_backtrace(l) }.compact
643+
if lines.size > @context.back_trace_limit
644+
omit = lines.size - @context.back_trace_limit
645+
lines = lines[0..(@context.back_trace_limit - 1)]
646+
lines << "\t... %d levels..." % omit
647+
end
648+
end
649+
lines = lines.reverse if order == :bottom
650+
lines.map{ |l| l + "\n" }.join
651+
}
652+
puts message
616653
end
617654
print "Maybe IRB bug!\n" if irb_bug
618655
end
@@ -761,7 +798,7 @@ def output_value(omit = false) # :nodoc:
761798
str = "%s...\e[0m" % lines.first
762799
multiline_p = false
763800
else
764-
str.gsub!(/(\A.*?\n).*/m, "\\1...")
801+
str = str.gsub(/(\A.*?\n).*/m, "\\1...")
765802
end
766803
else
767804
output_width = Reline::Unicode.calculate_width(@context.return_format % str, true)

lib/mri/irb/cmd/fork.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ module IRB
1616
module ExtendCommand
1717
class Fork < Nop
1818
def execute
19-
pid = send ExtendCommand.irb_original_method_name("fork")
19+
pid = __send__ ExtendCommand.irb_original_method_name("fork")
2020
unless pid
2121
class << self
2222
alias_method :exit, ExtendCommand.irb_original_method_name('exit')

lib/mri/irb/cmd/measure.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
require_relative "nop"
2+
3+
# :stopdoc:
4+
module IRB
5+
module ExtendCommand
6+
class Measure < Nop
7+
def initialize(*args)
8+
super(*args)
9+
end
10+
11+
def execute(type = nil, arg = nil, &block)
12+
case type
13+
when :off
14+
IRB.conf[:MEASURE] = nil
15+
IRB.unset_measure_callback(arg)
16+
when :list
17+
IRB.conf[:MEASURE_CALLBACKS].each do |type_name, _, arg_val|
18+
puts "- #{type_name}" + (arg_val ? "(#{arg_val.inspect})" : '')
19+
end
20+
when :on
21+
IRB.conf[:MEASURE] = true
22+
added = IRB.set_measure_callback(type, arg)
23+
puts "#{added[0]} is added." if added
24+
else
25+
if block_given?
26+
IRB.conf[:MEASURE] = true
27+
added = IRB.set_measure_callback(&block)
28+
puts "#{added[0]} is added." if added
29+
else
30+
IRB.conf[:MEASURE] = true
31+
added = IRB.set_measure_callback(type, arg)
32+
puts "#{added[0]} is added." if added
33+
end
34+
end
35+
nil
36+
end
37+
end
38+
end
39+
end
40+
# :startdoc:

lib/mri/irb/cmd/nop.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ module ExtendCommand
1515
class Nop
1616

1717

18-
def self.execute(conf, *opts)
18+
def self.execute(conf, *opts, &block)
1919
command = new(conf)
20-
command.execute(*opts)
20+
command.execute(*opts, &block)
2121
end
2222

2323
def initialize(conf)

lib/mri/irb/color.rb

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ module Color
1717
CYAN = 36
1818

1919
TOKEN_KEYWORDS = {
20-
on_kw: ['nil', 'self', 'true', 'false', '__FILE__', '__LINE__'],
20+
on_kw: ['nil', 'self', 'true', 'false', '__FILE__', '__LINE__', '__ENCODING__'],
2121
on_const: ['ENV'],
2222
}
2323
private_constant :TOKEN_KEYWORDS
@@ -60,13 +60,20 @@ module Color
6060
on_words_beg: [[RED, BOLD], ALL],
6161
on_parse_error: [[RED, REVERSE], ALL],
6262
compile_error: [[RED, REVERSE], ALL],
63+
on_assign_error: [[RED, REVERSE], ALL],
64+
on_alias_error: [[RED, REVERSE], ALL],
65+
on_class_name_error:[[RED, REVERSE], ALL],
66+
on_param_error: [[RED, REVERSE], ALL],
6367
}
6468
rescue NameError
6569
# Give up highlighting Ripper-incompatible older Ruby
6670
TOKEN_SEQ_EXPRS = {}
6771
end
6872
private_constant :TOKEN_SEQ_EXPRS
6973

74+
ERROR_TOKENS = TOKEN_SEQ_EXPRS.keys.select { |k| k.to_s.end_with?('error') }
75+
private_constant :ERROR_TOKENS
76+
7077
class << self
7178
def colorable?
7279
$stdout.tty? && supported? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb'))
@@ -107,14 +114,19 @@ def colorize(text, seq)
107114
# If `complete` is false (code is incomplete), this does not warn compile_error.
108115
# This option is needed to avoid warning a user when the compile_error is happening
109116
# because the input is not wrong but just incomplete.
110-
def colorize_code(code, complete: true)
117+
def colorize_code(code, complete: true, ignore_error: false)
111118
return code unless colorable?
112119

113120
symbol_state = SymbolState.new
114121
colored = +''
115122
length = 0
116123

117124
scan(code, allow_last_error: !complete) do |token, str, expr|
125+
# IRB::ColorPrinter skips colorizing fragments with any invalid token
126+
if ignore_error && ERROR_TOKENS.include?(token)
127+
return Reline::Unicode.escape_for_print(code)
128+
end
129+
118130
in_symbol = symbol_state.scan_token(token)
119131
str.each_line do |line|
120132
line = Reline::Unicode.escape_for_print(line)
@@ -180,11 +192,12 @@ def scan(code, allow_last_error:)
180192
end
181193
end
182194
end
195+
ensure
183196
$VERBOSE = verbose
184197
end
185198

186199
def dispatch_seq(token, expr, str, in_symbol:)
187-
if token == :on_parse_error or token == :compile_error
200+
if ERROR_TOKENS.include?(token)
188201
TOKEN_SEQ_EXPRS[token][0]
189202
elsif in_symbol
190203
[YELLOW]

0 commit comments

Comments
 (0)