Skip to content

Commit 75bf2e7

Browse files
committed
Refactor do keyword parsing
Mirror much more closely the parse.y COND and CMDARG stacks. This fixes a whole host of really really weird edge cases.
1 parent 39fb41f commit 75bf2e7

6 files changed

Lines changed: 152 additions & 71 deletions

File tree

config.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,8 @@ tokens:
496496
comment: "defined?"
497497
- name: KEYWORD_DO_BLOCK
498498
comment: "do keyword for a block attached to a command"
499+
- name: KEYWORD_DO_LAMBDA
500+
comment: "do keyword that opens the body of a lambda literal"
499501
- name: KEYWORD_DO_LOOP
500502
comment: "do keyword for a predicate in a while, until, or for loop"
501503
- name: KEYWORD_END_UPCASE

lib/prism/lex_compat.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ def deconstruct_keys(keys) # :nodoc:
141141
KEYWORD_DEFINED: :on_kw,
142142
KEYWORD_DO: :on_kw,
143143
KEYWORD_DO_BLOCK: :on_kw,
144+
KEYWORD_DO_LAMBDA: :on_kw,
144145
KEYWORD_DO_LOOP: :on_kw,
145146
KEYWORD_ELSE: :on_kw,
146147
KEYWORD_ELSIF: :on_kw,

lib/prism/translation/parser/lexer.rb

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ class Lexer # :nodoc:
8888
KEYWORD_DEFINED: :kDEFINED,
8989
KEYWORD_DO: :kDO,
9090
KEYWORD_DO_BLOCK: :kDO_BLOCK,
91+
KEYWORD_DO_LAMBDA: :kDO_LAMBDA,
9192
KEYWORD_DO_LOOP: :kDO_COND,
9293
KEYWORD_END: :kEND,
9394
KEYWORD_END_UPCASE: :klEND,
@@ -192,14 +193,6 @@ class Lexer # :nodoc:
192193
EXPR_BEG = 0x1
193194
EXPR_LABEL = 0x400
194195

195-
# It is used to determine whether `do` is of the token type `kDO` or
196-
# `kDO_LAMBDA`.
197-
#
198-
# NOTE: In edge cases like `-> (foo = -> (bar) {}) do end`, please note
199-
# that `kDO` is still returned instead of `kDO_LAMBDA`, which is
200-
# expected: https://github.com/ruby/prism/pull/3046
201-
LAMBDA_TOKEN_TYPES = Set.new([:kDO_LAMBDA, :tLAMBDA, :tLAMBEG])
202-
203196
# The `PARENTHESIS_LEFT` token in Prism is classified as either
204197
# `tLPAREN` or `tLPAREN2` in the Parser gem. The following token types
205198
# are listed as those classified as `tLPAREN`.
@@ -221,7 +214,7 @@ class Lexer # :nodoc:
221214
# Heredocs are complex and require us to keep track of a bit of info to refer to later
222215
HeredocData = Struct.new(:identifier, :common_whitespace, keyword_init: true)
223216

224-
private_constant :TYPES, :EXPR_BEG, :EXPR_LABEL, :LAMBDA_TOKEN_TYPES, :LPAREN_CONVERSION_TOKEN_TYPES, :HeredocData
217+
private_constant :TYPES, :EXPR_BEG, :EXPR_LABEL, :LPAREN_CONVERSION_TOKEN_TYPES, :HeredocData
225218

226219
# The Parser::Source::Buffer that the tokens were lexed from.
227220
attr_reader :source_buffer
@@ -269,14 +262,6 @@ def to_a
269262
location = range(token.location.start_offset, token.location.end_offset)
270263

271264
case type
272-
when :kDO
273-
nearest_lambda_token = tokens.reverse_each.find do |token|
274-
LAMBDA_TOKEN_TYPES.include?(token.first)
275-
end
276-
277-
if nearest_lambda_token&.first == :tLAMBDA
278-
type = :kDO_LAMBDA
279-
end
280265
when :tCHARACTER
281266
value.delete_prefix!("?")
282267
# Character literals behave similar to double-quoted strings. We can use the same escaping mechanism.

0 commit comments

Comments
 (0)