@@ -60,11 +60,19 @@ def set_input(io, p = nil, &block)
60
60
@io . dynamic_prompt do |lines |
61
61
lines << '' if lines . empty?
62
62
result = [ ]
63
- lines . each_index { |i |
64
- c = lines [ 0 ..i ] . map { |l | l + "\n " } . join
65
- ltype , indent , continue , code_block_open = check_state ( c )
66
- result << @prompt . call ( ltype , indent , continue || code_block_open , @line_no + i )
67
- }
63
+ tokens = ripper_lex_without_warning ( lines . map { |l | l + "\n " } . join )
64
+ code = String . new
65
+ partial_tokens = [ ]
66
+ line_num_offset = 0
67
+ tokens . each do |t |
68
+ code << t [ 2 ]
69
+ partial_tokens << t
70
+ if t [ 2 ] . include? ( "\n " )
71
+ ltype , indent , continue , code_block_open = check_state ( code , partial_tokens )
72
+ result << @prompt . call ( ltype , indent , continue || code_block_open , @line_no + line_num_offset )
73
+ line_num_offset += 1
74
+ end
75
+ end
68
76
result
69
77
end
70
78
end
@@ -88,12 +96,9 @@ def set_prompt(p = nil, &block)
88
96
89
97
def ripper_lex_without_warning ( code )
90
98
verbose , $VERBOSE = $VERBOSE, nil
91
- tokens = [ ]
99
+ tokens = nil
92
100
self . class . compile_with_errors_suppressed ( code ) do |inner_code , line_no |
93
- lexer = Ripper ::Lexer . new ( inner_code , '-' , line_no )
94
- until ( ts = lexer . lex ) . empty?
95
- tokens . concat ( ts )
96
- end
101
+ tokens = Ripper . lex ( inner_code , '-' , line_no )
97
102
end
98
103
$VERBOSE = verbose
99
104
tokens
@@ -124,12 +129,12 @@ def set_auto_indent(context)
124
129
end
125
130
end
126
131
127
- def check_state ( code )
128
- @ tokens = ripper_lex_without_warning ( code )
129
- ltype = process_literal_type
130
- indent = process_nesting_level
131
- continue = process_continue
132
- code_block_open = check_code_block ( code )
132
+ def check_state ( code , tokens = nil )
133
+ tokens = ripper_lex_without_warning ( code ) unless tokens
134
+ ltype = process_literal_type ( tokens )
135
+ indent = process_nesting_level ( tokens )
136
+ continue = process_continue ( tokens )
137
+ code_block_open = check_code_block ( code , tokens )
133
138
[ ltype , indent , continue , code_block_open ]
134
139
end
135
140
@@ -189,36 +194,36 @@ def lex
189
194
code = @line + ( line . nil? ? '' : line )
190
195
code . gsub! ( /\s *\z / , '' ) . concat ( "\n " )
191
196
@tokens = ripper_lex_without_warning ( code )
192
- @continue = process_continue
193
- @code_block_open = check_code_block ( code )
194
- @indent = process_nesting_level
195
- @ltype = process_literal_type
197
+ @continue = process_continue ( @tokens )
198
+ @code_block_open = check_code_block ( code , @tokens )
199
+ @indent = process_nesting_level ( @tokens )
200
+ @ltype = process_literal_type ( @tokens )
196
201
line
197
202
end
198
203
199
- def process_continue
204
+ def process_continue ( tokens )
200
205
# last token is always newline
201
- if @ tokens. size >= 2 and @ tokens[ -2 ] [ 1 ] == :on_regexp_end
206
+ if tokens . size >= 2 and tokens [ -2 ] [ 1 ] == :on_regexp_end
202
207
# end of regexp literal
203
208
return false
204
- elsif @ tokens. size >= 2 and @ tokens[ -2 ] [ 1 ] == :on_semicolon
209
+ elsif tokens . size >= 2 and tokens [ -2 ] [ 1 ] == :on_semicolon
205
210
return false
206
- elsif @ tokens. size >= 2 and @ tokens[ -2 ] [ 1 ] == :on_kw and [ 'begin' , 'else' , 'ensure' ] . include? ( @ tokens[ -2 ] [ 2 ] )
211
+ elsif tokens . size >= 2 and tokens [ -2 ] [ 1 ] == :on_kw and [ 'begin' , 'else' , 'ensure' ] . include? ( tokens [ -2 ] [ 2 ] )
207
212
return false
208
- elsif !@ tokens. empty? and @ tokens. last [ 2 ] == "\\ \n "
213
+ elsif !tokens . empty? and tokens . last [ 2 ] == "\\ \n "
209
214
return true
210
- elsif @ tokens. size >= 1 and @ tokens[ -1 ] [ 1 ] == :on_heredoc_end # "EOH\n"
215
+ elsif tokens . size >= 1 and tokens [ -1 ] [ 1 ] == :on_heredoc_end # "EOH\n"
211
216
return false
212
- elsif @ tokens. size >= 2 and defined? ( Ripper ::EXPR_BEG ) and @ tokens[ -2 ] [ 3 ] . anybits? ( Ripper ::EXPR_BEG | Ripper ::EXPR_FNAME )
217
+ elsif tokens . size >= 2 and defined? ( Ripper ::EXPR_BEG ) and tokens [ -2 ] [ 3 ] . anybits? ( Ripper ::EXPR_BEG | Ripper ::EXPR_FNAME )
213
218
# end of literal except for regexp
214
219
return true
215
220
end
216
221
false
217
222
end
218
223
219
- def check_code_block ( code )
220
- return true if @ tokens. empty?
221
- if @ tokens. last [ 1 ] == :on_heredoc_beg
224
+ def check_code_block ( code , tokens )
225
+ return true if tokens . empty?
226
+ if tokens . last [ 1 ] == :on_heredoc_beg
222
227
return true
223
228
end
224
229
@@ -290,7 +295,7 @@ def check_code_block(code)
290
295
end
291
296
292
297
if defined? ( Ripper ::EXPR_BEG )
293
- last_lex_state = @ tokens. last [ 3 ]
298
+ last_lex_state = tokens . last [ 3 ]
294
299
if last_lex_state . allbits? ( Ripper ::EXPR_BEG )
295
300
return false
296
301
elsif last_lex_state . allbits? ( Ripper ::EXPR_DOT )
@@ -309,10 +314,10 @@ def check_code_block(code)
309
314
false
310
315
end
311
316
312
- def process_nesting_level
317
+ def process_nesting_level ( tokens )
313
318
indent = 0
314
319
in_oneliner_def = nil
315
- @ tokens. each_with_index { |t , index |
320
+ tokens . each_with_index { |t , index |
316
321
# detecting one-liner method definition
317
322
if in_oneliner_def . nil?
318
323
if t [ 3 ] . allbits? ( Ripper ::EXPR_ENDFN )
@@ -340,10 +345,10 @@ def process_nesting_level
340
345
when :on_rbracket , :on_rbrace , :on_rparen
341
346
indent -= 1
342
347
when :on_kw
343
- next if index > 0 and @ tokens[ index - 1 ] [ 3 ] . allbits? ( Ripper ::EXPR_FNAME )
348
+ next if index > 0 and tokens [ index - 1 ] [ 3 ] . allbits? ( Ripper ::EXPR_FNAME )
344
349
case t [ 2 ]
345
350
when 'do'
346
- if index > 0 and @ tokens[ index - 1 ] [ 3 ] . anybits? ( Ripper ::EXPR_CMDARG | Ripper ::EXPR_ENDFN | Ripper ::EXPR_ARG )
351
+ if index > 0 and tokens [ index - 1 ] [ 3 ] . anybits? ( Ripper ::EXPR_CMDARG | Ripper ::EXPR_ENDFN | Ripper ::EXPR_ARG )
347
352
# method_with_block do; end
348
353
indent += 1
349
354
else
@@ -525,12 +530,12 @@ def check_corresponding_token_depth
525
530
corresponding_token_depth
526
531
end
527
532
528
- def check_string_literal
533
+ def check_string_literal ( tokens )
529
534
i = 0
530
535
start_token = [ ]
531
536
end_type = [ ]
532
- while i < @ tokens. size
533
- t = @ tokens[ i ]
537
+ while i < tokens . size
538
+ t = tokens [ i ]
534
539
case t [ 1 ]
535
540
when :on_tstring_beg
536
541
start_token << t
@@ -540,7 +545,7 @@ def check_string_literal
540
545
end_type << :on_regexp_end
541
546
when :on_symbeg
542
547
acceptable_single_tokens = %i{ on_ident on_const on_op on_cvar on_ivar on_gvar on_kw }
543
- if ( i + 1 ) < @ tokens. size and acceptable_single_tokens . all? { |t | @ tokens[ i + 1 ] [ 1 ] != t }
548
+ if ( i + 1 ) < tokens . size and acceptable_single_tokens . all? { |t | tokens [ i + 1 ] [ 1 ] != t }
544
549
start_token << t
545
550
end_type << :on_tstring_end
546
551
end
@@ -562,8 +567,8 @@ def check_string_literal
562
567
start_token . last . nil? ? '' : start_token . last
563
568
end
564
569
565
- def process_literal_type
566
- start_token = check_string_literal
570
+ def process_literal_type ( tokens )
571
+ start_token = check_string_literal ( tokens )
567
572
case start_token [ 1 ]
568
573
when :on_tstring_beg
569
574
case start_token [ 2 ]
0 commit comments