class SyntaxTree::Parser
def on_hshptn(constant, keywords, keyword_rest)
(nil | VarField) keyword_rest
Array[[Label | StringContent, untyped]] keywords,
(nil | untyped) constant,
on_hshptn: (
:call-seq:
def on_hshptn(constant, keywords, keyword_rest) keywords = (keywords || []).map do |(label, value)| if label.is_a?(Label) [label, value] else tstring_beg_index = tokens.rindex do |token| token.is_a?(TStringBeg) && token.location.start_char < label.location.start_char end tstring_beg = tokens.delete_at(tstring_beg_index) label_end_index = tokens.rindex do |token| token.is_a?(LabelEnd) && token.location.start_char == label.location.end_char end label_end = tokens.delete_at(label_end_index) [ DynaSymbol.new( parts: label.parts, quote: label_end.value[0], location: tstring_beg.location.to(label_end.location) ), value ] end end if keyword_rest # We're doing this to delete the token from the list so that it doesn't # confuse future patterns by thinking they have an extra ** on the end. consume_operator(:**) elsif (token = find_operator(:**)) tokens.delete(token) # Create an artificial VarField if we find an extra ** on the end. This # means the formatting will be a little more consistent. keyword_rest = VarField.new(value: nil, location: token.location) end parts = [constant, *keywords.flatten(1), keyword_rest].compact # If there's no constant, there may be braces, so we're going to look for # those to get our bounds. unless constant lbrace = find_token(LBrace) rbrace = find_token(RBrace) if lbrace && rbrace parts = [lbrace, *parts, rbrace] tokens.delete(lbrace) tokens.delete(rbrace) end end HshPtn.new( constant: constant, keywords: keywords, keyword_rest: keyword_rest, location: parts[0].location.to(parts[-1].location) ) end