irb 1.1.0.pre.3
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 +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +55 -0
- data/exe/irb +11 -0
- data/irb.gemspec +29 -0
- data/lib/irb.rb +855 -0
- data/lib/irb/cmd/chws.rb +34 -0
- data/lib/irb/cmd/fork.rb +39 -0
- data/lib/irb/cmd/help.rb +46 -0
- data/lib/irb/cmd/load.rb +67 -0
- data/lib/irb/cmd/nop.rb +39 -0
- data/lib/irb/cmd/pushws.rb +41 -0
- data/lib/irb/cmd/subirb.rb +43 -0
- data/lib/irb/color.rb +218 -0
- data/lib/irb/completion.rb +339 -0
- data/lib/irb/context.rb +459 -0
- data/lib/irb/ext/change-ws.rb +46 -0
- data/lib/irb/ext/history.rb +120 -0
- data/lib/irb/ext/loader.rb +129 -0
- data/lib/irb/ext/multi-irb.rb +265 -0
- data/lib/irb/ext/save-history.rb +117 -0
- data/lib/irb/ext/tracer.rb +72 -0
- data/lib/irb/ext/use-loader.rb +77 -0
- data/lib/irb/ext/workspaces.rb +67 -0
- data/lib/irb/extend-command.rb +328 -0
- data/lib/irb/frame.rb +81 -0
- data/lib/irb/help.rb +37 -0
- data/lib/irb/init.rb +312 -0
- data/lib/irb/input-method.rb +298 -0
- data/lib/irb/inspector.rb +142 -0
- data/lib/irb/lc/.document +4 -0
- data/lib/irb/lc/error.rb +32 -0
- data/lib/irb/lc/help-message +50 -0
- data/lib/irb/lc/ja/encoding_aliases.rb +11 -0
- data/lib/irb/lc/ja/error.rb +31 -0
- data/lib/irb/lc/ja/help-message +52 -0
- data/lib/irb/locale.rb +182 -0
- data/lib/irb/magic-file.rb +38 -0
- data/lib/irb/notifier.rb +232 -0
- data/lib/irb/output-method.rb +92 -0
- data/lib/irb/ruby-lex.rb +492 -0
- data/lib/irb/ruby-token.rb +267 -0
- data/lib/irb/slex.rb +282 -0
- data/lib/irb/src_encoding.rb +7 -0
- data/lib/irb/version.rb +17 -0
- data/lib/irb/workspace.rb +190 -0
- data/lib/irb/ws-for-case-2.rb +15 -0
- data/lib/irb/xmp.rb +170 -0
- metadata +133 -0
data/lib/irb/cmd/chws.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# change-ws.rb -
|
4
|
+
# $Release Version: 0.9.6$
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
|
13
|
+
require_relative "nop"
|
14
|
+
require_relative "../ext/change-ws"
|
15
|
+
|
16
|
+
# :stopdoc:
|
17
|
+
module IRB
|
18
|
+
module ExtendCommand
|
19
|
+
|
20
|
+
class CurrentWorkingWorkspace < Nop
|
21
|
+
def execute(*obj)
|
22
|
+
irb_context.main
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class ChangeWorkspace < Nop
|
27
|
+
def execute(*obj)
|
28
|
+
irb_context.change_workspace(*obj)
|
29
|
+
irb_context.main
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
# :startdoc:
|
data/lib/irb/cmd/fork.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# fork.rb -
|
4
|
+
# $Release Version: 0.9.6 $
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
|
13
|
+
|
14
|
+
# :stopdoc:
|
15
|
+
module IRB
|
16
|
+
module ExtendCommand
|
17
|
+
class Fork < Nop
|
18
|
+
def execute
|
19
|
+
pid = send ExtendCommand.irb_original_method_name("fork")
|
20
|
+
unless pid
|
21
|
+
class << self
|
22
|
+
alias_method :exit, ExtendCommand.irb_original_method_name('exit')
|
23
|
+
end
|
24
|
+
if block_given?
|
25
|
+
begin
|
26
|
+
yield
|
27
|
+
ensure
|
28
|
+
exit
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
pid
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
# :startdoc:
|
38
|
+
|
39
|
+
|
data/lib/irb/cmd/help.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# help.rb - helper using ri
|
4
|
+
# $Release Version: 0.9.6$
|
5
|
+
# $Revision$
|
6
|
+
#
|
7
|
+
# --
|
8
|
+
#
|
9
|
+
#
|
10
|
+
#
|
11
|
+
|
12
|
+
require_relative "nop"
|
13
|
+
|
14
|
+
# :stopdoc:
|
15
|
+
module IRB
|
16
|
+
module ExtendCommand
|
17
|
+
class Help < Nop
|
18
|
+
def execute(*names)
|
19
|
+
require 'rdoc/ri/driver'
|
20
|
+
IRB::ExtendCommand::Help.const_set(:Ri, RDoc::RI::Driver.new)
|
21
|
+
rescue LoadError, SystemExit
|
22
|
+
IRB::ExtendCommand::Help.remove_method(:execute)
|
23
|
+
# raise NoMethodError in ensure
|
24
|
+
else
|
25
|
+
def execute(*names)
|
26
|
+
if names.empty?
|
27
|
+
Ri.interactive
|
28
|
+
return
|
29
|
+
end
|
30
|
+
names.each do |name|
|
31
|
+
begin
|
32
|
+
Ri.display_name(name.to_s)
|
33
|
+
rescue RDoc::RI::Error
|
34
|
+
puts $!.message
|
35
|
+
end
|
36
|
+
end
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
nil
|
40
|
+
ensure
|
41
|
+
execute(*names)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
# :startdoc:
|
data/lib/irb/cmd/load.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# load.rb -
|
4
|
+
# $Release Version: 0.9.6$
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
|
13
|
+
require_relative "nop"
|
14
|
+
require_relative "../ext/loader"
|
15
|
+
|
16
|
+
# :stopdoc:
|
17
|
+
module IRB
|
18
|
+
module ExtendCommand
|
19
|
+
class Load < Nop
|
20
|
+
include IrbLoader
|
21
|
+
|
22
|
+
def execute(file_name, priv = nil)
|
23
|
+
return irb_load(file_name, priv)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Require < Nop
|
28
|
+
include IrbLoader
|
29
|
+
|
30
|
+
def execute(file_name)
|
31
|
+
|
32
|
+
rex = Regexp.new("#{Regexp.quote(file_name)}(\.o|\.rb)?")
|
33
|
+
return false if $".find{|f| f =~ rex}
|
34
|
+
|
35
|
+
case file_name
|
36
|
+
when /\.rb$/
|
37
|
+
begin
|
38
|
+
if irb_load(file_name)
|
39
|
+
$".push file_name
|
40
|
+
return true
|
41
|
+
end
|
42
|
+
rescue LoadError
|
43
|
+
end
|
44
|
+
when /\.(so|o|sl)$/
|
45
|
+
return ruby_require(file_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
begin
|
49
|
+
irb_load(f = file_name + ".rb")
|
50
|
+
$".push f
|
51
|
+
return true
|
52
|
+
rescue LoadError
|
53
|
+
return ruby_require(file_name)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class Source < Nop
|
59
|
+
include IrbLoader
|
60
|
+
def execute(file_name)
|
61
|
+
source_file(file_name)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
# :startdoc:
|
data/lib/irb/cmd/nop.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# nop.rb -
|
4
|
+
# $Release Version: 0.9.6$
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
# :stopdoc:
|
13
|
+
module IRB
|
14
|
+
module ExtendCommand
|
15
|
+
class Nop
|
16
|
+
|
17
|
+
|
18
|
+
def self.execute(conf, *opts)
|
19
|
+
command = new(conf)
|
20
|
+
command.execute(*opts)
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(conf)
|
24
|
+
@irb_context = conf
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :irb_context
|
28
|
+
|
29
|
+
def irb
|
30
|
+
@irb_context.irb
|
31
|
+
end
|
32
|
+
|
33
|
+
def execute(*opts)
|
34
|
+
#nop
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
# :startdoc:
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# change-ws.rb -
|
4
|
+
# $Release Version: 0.9.6$
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
|
13
|
+
require_relative "nop"
|
14
|
+
require_relative "../ext/workspaces"
|
15
|
+
|
16
|
+
# :stopdoc:
|
17
|
+
module IRB
|
18
|
+
module ExtendCommand
|
19
|
+
class Workspaces < Nop
|
20
|
+
def execute(*obj)
|
21
|
+
irb_context.workspaces.collect{|ws| ws.main}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class PushWorkspace < Workspaces
|
26
|
+
def execute(*obj)
|
27
|
+
irb_context.push_workspace(*obj)
|
28
|
+
super
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class PopWorkspace < Workspaces
|
33
|
+
def execute(*obj)
|
34
|
+
irb_context.pop_workspace(*obj)
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
# :startdoc:
|
41
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
# multi.rb -
|
3
|
+
# $Release Version: 0.9.6$
|
4
|
+
# $Revision$
|
5
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
6
|
+
#
|
7
|
+
# --
|
8
|
+
#
|
9
|
+
#
|
10
|
+
#
|
11
|
+
|
12
|
+
require_relative "nop"
|
13
|
+
require_relative "../ext/multi-irb"
|
14
|
+
|
15
|
+
# :stopdoc:
|
16
|
+
module IRB
|
17
|
+
module ExtendCommand
|
18
|
+
class IrbCommand < Nop
|
19
|
+
def execute(*obj)
|
20
|
+
IRB.irb(nil, *obj)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Jobs < Nop
|
25
|
+
def execute
|
26
|
+
IRB.JobManager
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Foreground < Nop
|
31
|
+
def execute(key)
|
32
|
+
IRB.JobManager.switch(key)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Kill < Nop
|
37
|
+
def execute(*keys)
|
38
|
+
IRB.JobManager.kill(*keys)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
# :startdoc:
|
data/lib/irb/color.rb
ADDED
@@ -0,0 +1,218 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'reline'
|
3
|
+
require 'ripper'
|
4
|
+
|
5
|
+
module IRB # :nodoc:
|
6
|
+
module Color
|
7
|
+
CLEAR = 0
|
8
|
+
BOLD = 1
|
9
|
+
UNDERLINE = 4
|
10
|
+
REVERSE = 7
|
11
|
+
RED = 31
|
12
|
+
GREEN = 32
|
13
|
+
YELLOW = 33
|
14
|
+
BLUE = 34
|
15
|
+
MAGENTA = 35
|
16
|
+
CYAN = 36
|
17
|
+
|
18
|
+
TOKEN_KEYWORDS = {
|
19
|
+
on_kw: ['nil', 'self', 'true', 'false', '__FILE__', '__LINE__'],
|
20
|
+
on_const: ['ENV'],
|
21
|
+
}
|
22
|
+
private_constant :TOKEN_KEYWORDS
|
23
|
+
|
24
|
+
# A constant of all-bit 1 to match any Ripper's state in #dispatch_seq
|
25
|
+
ALL = -1
|
26
|
+
private_constant :ALL
|
27
|
+
|
28
|
+
begin
|
29
|
+
# Following pry's colors where possible, but sometimes having a compromise like making
|
30
|
+
# backtick and regexp as red (string's color, because they're sharing tokens).
|
31
|
+
TOKEN_SEQ_EXPRS = {
|
32
|
+
on_CHAR: [[BLUE, BOLD], ALL],
|
33
|
+
on_backtick: [[RED], ALL],
|
34
|
+
on_comment: [[BLUE, BOLD], ALL],
|
35
|
+
on_const: [[BLUE, BOLD, UNDERLINE], ALL],
|
36
|
+
on_embexpr_beg: [[RED], ALL],
|
37
|
+
on_embexpr_end: [[RED], ALL],
|
38
|
+
on_embvar: [[RED], ALL],
|
39
|
+
on_float: [[MAGENTA, BOLD], ALL],
|
40
|
+
on_gvar: [[GREEN, BOLD], ALL],
|
41
|
+
on_heredoc_beg: [[RED], ALL],
|
42
|
+
on_heredoc_end: [[RED], ALL],
|
43
|
+
on_ident: [[BLUE, BOLD], Ripper::EXPR_ENDFN],
|
44
|
+
on_imaginary: [[BLUE, BOLD], ALL],
|
45
|
+
on_int: [[BLUE, BOLD], ALL],
|
46
|
+
on_kw: [[GREEN], ALL],
|
47
|
+
on_label: [[MAGENTA], ALL],
|
48
|
+
on_label_end: [[RED], ALL],
|
49
|
+
on_qsymbols_beg: [[RED], ALL],
|
50
|
+
on_qwords_beg: [[RED], ALL],
|
51
|
+
on_rational: [[BLUE, BOLD], ALL],
|
52
|
+
on_regexp_beg: [[RED, BOLD], ALL],
|
53
|
+
on_regexp_end: [[RED, BOLD], ALL],
|
54
|
+
on_symbeg: [[YELLOW], ALL],
|
55
|
+
on_tstring_beg: [[RED], ALL],
|
56
|
+
on_tstring_content: [[RED], ALL],
|
57
|
+
on_tstring_end: [[RED], ALL],
|
58
|
+
on_words_beg: [[RED], ALL],
|
59
|
+
on_parse_error: [[RED, REVERSE], ALL],
|
60
|
+
compile_error: [[RED, REVERSE], ALL],
|
61
|
+
}
|
62
|
+
rescue NameError
|
63
|
+
# Give up highlighting Ripper-incompatible older Ruby
|
64
|
+
TOKEN_SEQ_EXPRS = {}
|
65
|
+
end
|
66
|
+
private_constant :TOKEN_SEQ_EXPRS
|
67
|
+
|
68
|
+
class << self
|
69
|
+
def colorable?
|
70
|
+
$stdout.tty? && supported? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb'))
|
71
|
+
end
|
72
|
+
|
73
|
+
def inspect_colorable?(obj)
|
74
|
+
case obj
|
75
|
+
when String, Symbol, Regexp, Integer, Float, FalseClass, TrueClass, NilClass
|
76
|
+
true
|
77
|
+
when Hash
|
78
|
+
obj.all? { |k, v| inspect_colorable?(k) && inspect_colorable?(v) }
|
79
|
+
when Array
|
80
|
+
obj.all? { |o| inspect_colorable?(o) }
|
81
|
+
when Range
|
82
|
+
inspect_colorable?(obj.begin) && inspect_colorable?(obj.end)
|
83
|
+
when Module
|
84
|
+
!obj.name.nil?
|
85
|
+
else
|
86
|
+
false
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def clear
|
91
|
+
return '' unless colorable?
|
92
|
+
"\e[#{CLEAR}m"
|
93
|
+
end
|
94
|
+
|
95
|
+
def colorize(text, seq)
|
96
|
+
return text unless colorable?
|
97
|
+
seq = seq.map { |s| "\e[#{const_get(s)}m" }.join('')
|
98
|
+
"#{seq}#{text}#{clear}"
|
99
|
+
end
|
100
|
+
|
101
|
+
# If `complete` is false (code is incomplete), this does not warn compile_error.
|
102
|
+
# This option is needed to avoid warning a user when the compile_error is happening
|
103
|
+
# because the input is not wrong but just incomplete.
|
104
|
+
def colorize_code(code, complete: true)
|
105
|
+
return code unless colorable?
|
106
|
+
|
107
|
+
symbol_state = SymbolState.new
|
108
|
+
colored = +''
|
109
|
+
length = 0
|
110
|
+
|
111
|
+
scan(code, allow_last_error: !complete) do |token, str, expr|
|
112
|
+
in_symbol = symbol_state.scan_token(token)
|
113
|
+
str.each_line do |line|
|
114
|
+
line = Reline::Unicode.escape_for_print(line)
|
115
|
+
if seq = dispatch_seq(token, expr, line, in_symbol: in_symbol)
|
116
|
+
colored << seq.map { |s| "\e[#{s}m" }.join('')
|
117
|
+
colored << line.sub(/\Z/, clear)
|
118
|
+
else
|
119
|
+
colored << line
|
120
|
+
end
|
121
|
+
end
|
122
|
+
length += str.bytesize
|
123
|
+
end
|
124
|
+
|
125
|
+
# give up colorizing incomplete Ripper tokens
|
126
|
+
if length != code.bytesize
|
127
|
+
return Reline::Unicode.escape_for_print(code)
|
128
|
+
end
|
129
|
+
|
130
|
+
colored
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
# Ripper::Lexer::Elem#state is supported on Ruby 2.5+
|
136
|
+
def supported?
|
137
|
+
return @supported if defined?(@supported)
|
138
|
+
@supported = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.5.0')
|
139
|
+
end
|
140
|
+
|
141
|
+
def scan(code, allow_last_error:)
|
142
|
+
pos = [1, 0]
|
143
|
+
|
144
|
+
lexer = Ripper::Lexer.new(code)
|
145
|
+
if lexer.respond_to?(:scan) # Ruby 2.7+
|
146
|
+
lexer.scan.each do |elem|
|
147
|
+
str = elem.tok
|
148
|
+
next if allow_last_error and /meets end of file|unexpected end-of-input/ =~ elem.message
|
149
|
+
next if ([elem.pos[0], elem.pos[1] + str.bytesize] <=> pos) <= 0
|
150
|
+
|
151
|
+
str.each_line do |line|
|
152
|
+
if line.end_with?("\n")
|
153
|
+
pos[0] += 1
|
154
|
+
pos[1] = 0
|
155
|
+
else
|
156
|
+
pos[1] += line.bytesize
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
yield(elem.event, str, elem.state)
|
161
|
+
end
|
162
|
+
else
|
163
|
+
lexer.parse.each do |elem|
|
164
|
+
yield(elem.event, elem.tok, elem.state)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def dispatch_seq(token, expr, str, in_symbol:)
|
170
|
+
if token == :on_parse_error or token == :compile_error
|
171
|
+
TOKEN_SEQ_EXPRS[token][0]
|
172
|
+
elsif in_symbol
|
173
|
+
[YELLOW]
|
174
|
+
elsif TOKEN_KEYWORDS.fetch(token, []).include?(str)
|
175
|
+
[CYAN, BOLD]
|
176
|
+
elsif (seq, exprs = TOKEN_SEQ_EXPRS[token]; (expr & (exprs || 0)) != 0)
|
177
|
+
seq
|
178
|
+
else
|
179
|
+
nil
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# A class to manage a state to know whether the current token is for Symbol or not.
|
185
|
+
class SymbolState
|
186
|
+
def initialize
|
187
|
+
# Push `true` to detect Symbol. `false` to increase the nest level for non-Symbol.
|
188
|
+
@stack = []
|
189
|
+
end
|
190
|
+
|
191
|
+
# Return true if the token is a part of Symbol.
|
192
|
+
def scan_token(token)
|
193
|
+
prev_state = @stack.last
|
194
|
+
case token
|
195
|
+
when :on_symbeg
|
196
|
+
@stack << true
|
197
|
+
when :on_ident, :on_op, :on_const, :on_ivar, :on_cvar, :on_gvar, :on_kw
|
198
|
+
if @stack.last # Pop only when it's Symbol
|
199
|
+
@stack.pop
|
200
|
+
return prev_state
|
201
|
+
end
|
202
|
+
when :on_tstring_beg
|
203
|
+
@stack << false
|
204
|
+
when :on_embexpr_beg
|
205
|
+
@stack << false
|
206
|
+
return prev_state
|
207
|
+
when :on_tstring_end # :on_tstring_end may close Symbol
|
208
|
+
@stack.pop
|
209
|
+
return prev_state
|
210
|
+
when :on_embexpr_end
|
211
|
+
@stack.pop
|
212
|
+
end
|
213
|
+
@stack.last
|
214
|
+
end
|
215
|
+
end
|
216
|
+
private_constant :SymbolState
|
217
|
+
end
|
218
|
+
end
|