@@ -35,9 +35,6 @@ module Translation
3535 # - on_rparen
3636 # - on_semicolon
3737 # - on_sp
38- # - on_symbeg
39- # - on_tstring_beg
40- # - on_tstring_end
4138 #
4239 class Ripper < Compiler
4340 # Parses the given Ruby program read from +src+.
@@ -2235,61 +2232,67 @@ def visit_interpolated_regular_expression_node(node)
22352232 # "foo #{bar}"
22362233 # ^^^^^^^^^^^^
22372234 def visit_interpolated_string_node ( node )
2238- if node . opening &.start_with? ( "<<~" )
2239- heredoc = visit_heredoc_string_node ( node )
2235+ with_string_bounds ( node ) do
2236+ if node . opening &.start_with? ( "<<~" )
2237+ heredoc = visit_heredoc_string_node ( node )
22402238
2241- bounds ( node . location )
2242- on_string_literal ( heredoc )
2243- elsif !node . heredoc? && node . parts . length > 1 && node . parts . any? { |part | ( part . is_a? ( StringNode ) || part . is_a? ( InterpolatedStringNode ) ) && !part . opening_loc . nil? }
2244- first , *rest = node . parts
2245- rest . inject ( visit ( first ) ) do |content , part |
2246- concat = visit ( part )
2247-
2248- bounds ( part . location )
2249- on_string_concat ( content , concat )
2250- end
2251- else
2252- bounds ( node . parts . first . location )
2253- parts =
2254- node . parts . inject ( on_string_content ) do |content , part |
2255- on_string_add ( content , visit_string_content ( part ) )
2239+ bounds ( node . location )
2240+ on_string_literal ( heredoc )
2241+ elsif !node . heredoc? && node . parts . length > 1 && node . parts . any? { |part | ( part . is_a? ( StringNode ) || part . is_a? ( InterpolatedStringNode ) ) && !part . opening_loc . nil? }
2242+ first , *rest = node . parts
2243+ rest . inject ( visit ( first ) ) do |content , part |
2244+ concat = visit ( part )
2245+
2246+ bounds ( part . location )
2247+ on_string_concat ( content , concat )
22562248 end
2249+ else
2250+ bounds ( node . parts . first . location )
2251+ parts =
2252+ node . parts . inject ( on_string_content ) do |content , part |
2253+ on_string_add ( content , visit_string_content ( part ) )
2254+ end
22572255
2258- bounds ( node . location )
2259- on_string_literal ( parts )
2256+ bounds ( node . location )
2257+ on_string_literal ( parts )
2258+ end
22602259 end
22612260 end
22622261
22632262 # :"foo #{bar}"
22642263 # ^^^^^^^^^^^^^
22652264 def visit_interpolated_symbol_node ( node )
2266- bounds ( node . parts . first . location )
2267- parts =
2268- node . parts . inject ( on_string_content ) do |content , part |
2269- on_string_add ( content , visit_string_content ( part ) )
2270- end
2265+ with_string_bounds ( node ) do
2266+ bounds ( node . parts . first . location )
2267+ parts =
2268+ node . parts . inject ( on_string_content ) do |content , part |
2269+ on_string_add ( content , visit_string_content ( part ) )
2270+ end
22712271
2272- bounds ( node . location )
2273- on_dyna_symbol ( parts )
2272+ bounds ( node . location )
2273+ on_dyna_symbol ( parts )
2274+ end
22742275 end
22752276
22762277 # `foo #{bar}`
22772278 # ^^^^^^^^^^^^
22782279 def visit_interpolated_x_string_node ( node )
2279- if node . opening . start_with? ( "<<~" )
2280- heredoc = visit_heredoc_x_string_node ( node )
2280+ with_string_bounds ( node ) do
2281+ if node . opening . start_with? ( "<<~" )
2282+ heredoc = visit_heredoc_x_string_node ( node )
22812283
2282- bounds ( node . location )
2283- on_xstring_literal ( heredoc )
2284- else
2285- bounds ( node . parts . first . location )
2286- parts =
2287- node . parts . inject ( on_xstring_new ) do |content , part |
2288- on_xstring_add ( content , visit_string_content ( part ) )
2289- end
2284+ bounds ( node . location )
2285+ on_xstring_literal ( heredoc )
2286+ else
2287+ bounds ( node . parts . first . location )
2288+ parts =
2289+ node . parts . inject ( on_xstring_new ) do |content , part |
2290+ on_xstring_add ( content , visit_string_content ( part ) )
2291+ end
22902292
2291- bounds ( node . location )
2292- on_xstring_literal ( parts )
2293+ bounds ( node . location )
2294+ on_xstring_literal ( parts )
2295+ end
22932296 end
22942297 end
22952298
@@ -3022,24 +3025,60 @@ def visit_statements_node(node)
30223025 # "foo"
30233026 # ^^^^^
30243027 def visit_string_node ( node )
3025- if ( content = node . content ) . empty?
3026- bounds ( node . location )
3027- on_string_literal ( on_string_content )
3028- elsif ( opening = node . opening ) == "?"
3029- bounds ( node . location )
3030- on_CHAR ( "?#{ node . content } " )
3031- elsif opening . start_with? ( "<<~" )
3032- heredoc = visit_heredoc_string_node ( node . to_interpolated )
3028+ with_string_bounds ( node ) do
3029+ if ( content = node . content ) . empty?
3030+ bounds ( node . location )
3031+ on_string_literal ( on_string_content )
3032+ elsif ( opening = node . opening ) == "?"
3033+ bounds ( node . location )
3034+ on_CHAR ( "?#{ node . content } " )
3035+ elsif opening . start_with? ( "<<~" )
3036+ heredoc = visit_heredoc_string_node ( node . to_interpolated )
30333037
3034- bounds ( node . location )
3035- on_string_literal ( heredoc )
3036- else
3037- bounds ( node . content_loc )
3038- tstring_content = on_tstring_content ( content )
3038+ bounds ( node . location )
3039+ on_string_literal ( heredoc )
3040+ else
3041+ bounds ( node . content_loc )
3042+ tstring_content = on_tstring_content ( content )
30393043
3040- bounds ( node . location )
3041- on_string_literal ( on_string_add ( on_string_content , tstring_content ) )
3044+ bounds ( node . location )
3045+ on_string_literal ( on_string_add ( on_string_content , tstring_content ) )
3046+ end
3047+ end
3048+ end
3049+
3050+ # Responsible for emitting the various string-like begin/end events
3051+ private def with_string_bounds ( node )
3052+ # `foo "bar": baz` doesn't emit the closing location
3053+ assoc = !( opening = node . opening ) &.include? ( ":" ) && node . closing &.end_with? ( ":" )
3054+
3055+ is_heredoc = opening &.start_with? ( "<<" )
3056+ if is_heredoc
3057+ bounds ( node . opening_loc )
3058+ on_heredoc_beg ( node . opening )
3059+ elsif opening &.start_with? ( ":" , "%s" )
3060+ bounds ( node . opening_loc )
3061+ on_symbeg ( node . opening )
3062+ elsif opening &.start_with? ( "`" , "%x" )
3063+ bounds ( node . opening_loc )
3064+ on_backtick ( node . opening )
3065+ elsif opening && !opening . start_with? ( "?" )
3066+ bounds ( node . opening_loc )
3067+ on_tstring_beg ( opening )
30423068 end
3069+
3070+ result = yield
3071+ return result if assoc
3072+
3073+ if is_heredoc
3074+ bounds ( node . closing_loc )
3075+ on_heredoc_end ( node . closing )
3076+ elsif node . closing_loc
3077+ bounds ( node . closing_loc )
3078+ on_tstring_end ( node . closing )
3079+ end
3080+
3081+ result
30433082 end
30443083
30453084 # Ripper gives back the escaped string content but strips out the common
@@ -3119,36 +3158,18 @@ def visit_string_node(node)
31193158
31203159 # Visit a heredoc node that is representing a string.
31213160 private def visit_heredoc_string_node ( node )
3122- bounds ( node . opening_loc )
3123- on_heredoc_beg ( node . opening )
3124-
31253161 bounds ( node . location )
3126- result =
3127- visit_heredoc_node ( node . parts , on_string_content ) do |parts , part |
3128- on_string_add ( parts , part )
3129- end
3130-
3131- bounds ( node . closing_loc )
3132- on_heredoc_end ( node . closing )
3133-
3134- result
3162+ visit_heredoc_node ( node . parts , on_string_content ) do |parts , part |
3163+ on_string_add ( parts , part )
3164+ end
31353165 end
31363166
31373167 # Visit a heredoc node that is representing an xstring.
31383168 private def visit_heredoc_x_string_node ( node )
3139- bounds ( node . opening_loc )
3140- on_heredoc_beg ( node . opening )
3141-
31423169 bounds ( node . location )
3143- result =
3144- visit_heredoc_node ( node . parts , on_xstring_new ) do |parts , part |
3145- on_xstring_add ( parts , part )
3146- end
3147-
3148- bounds ( node . closing_loc )
3149- on_heredoc_end ( node . closing )
3150-
3151- result
3170+ visit_heredoc_node ( node . parts , on_xstring_new ) do |parts , part |
3171+ on_xstring_add ( parts , part )
3172+ end
31523173 end
31533174
31543175 # super(foo)
@@ -3175,23 +3196,25 @@ def visit_super_node(node)
31753196 # :foo
31763197 # ^^^^
31773198 def visit_symbol_node ( node )
3178- if node . value_loc . nil?
3179- bounds ( node . location )
3180- on_dyna_symbol ( on_string_content )
3181- elsif ( opening = node . opening ) &.match? ( /^%s|['"]:?$/ )
3182- bounds ( node . value_loc )
3183- content = on_string_add ( on_string_content , on_tstring_content ( node . value ) )
3184- bounds ( node . location )
3185- on_dyna_symbol ( content )
3186- elsif ( closing = node . closing ) == ":"
3187- bounds ( node . location )
3188- on_label ( "#{ node . value } :" )
3189- elsif opening . nil? && node . closing_loc . nil?
3190- bounds ( node . value_loc )
3191- on_symbol_literal ( visit_token ( node . value ) )
3192- else
3193- bounds ( node . value_loc )
3194- on_symbol_literal ( on_symbol ( visit_token ( node . value ) ) )
3199+ with_string_bounds ( node ) do
3200+ if node . value_loc . nil?
3201+ bounds ( node . location )
3202+ on_dyna_symbol ( on_string_content )
3203+ elsif ( opening = node . opening ) &.match? ( /^%s|['"]:?$/ )
3204+ bounds ( node . value_loc )
3205+ content = on_string_add ( on_string_content , on_tstring_content ( node . value ) )
3206+ bounds ( node . location )
3207+ on_dyna_symbol ( content )
3208+ elsif ( closing = node . closing ) == ":"
3209+ bounds ( node . location )
3210+ on_label ( "#{ node . value } :" )
3211+ elsif opening . nil? && node . closing_loc . nil?
3212+ bounds ( node . value_loc )
3213+ on_symbol_literal ( visit_token ( node . value ) )
3214+ else
3215+ bounds ( node . value_loc )
3216+ on_symbol_literal ( on_symbol ( visit_token ( node . value ) ) )
3217+ end
31953218 end
31963219 end
31973220
@@ -3314,20 +3337,22 @@ def visit_while_node(node)
33143337 # `foo`
33153338 # ^^^^^
33163339 def visit_x_string_node ( node )
3317- if node . unescaped . empty?
3318- bounds ( node . location )
3319- on_xstring_literal ( on_xstring_new )
3320- elsif node . opening . start_with? ( "<<~" )
3321- heredoc = visit_heredoc_x_string_node ( node . to_interpolated )
3340+ with_string_bounds ( node ) do
3341+ if node . unescaped . empty?
3342+ bounds ( node . location )
3343+ on_xstring_literal ( on_xstring_new )
3344+ elsif node . opening . start_with? ( "<<~" )
3345+ heredoc = visit_heredoc_x_string_node ( node . to_interpolated )
33223346
3323- bounds ( node . location )
3324- on_xstring_literal ( heredoc )
3325- else
3326- bounds ( node . content_loc )
3327- content = on_tstring_content ( node . content )
3347+ bounds ( node . location )
3348+ on_xstring_literal ( heredoc )
3349+ else
3350+ bounds ( node . content_loc )
3351+ content = on_tstring_content ( node . content )
33283352
3329- bounds ( node . location )
3330- on_xstring_literal ( on_xstring_add ( on_xstring_new , content ) )
3353+ bounds ( node . location )
3354+ on_xstring_literal ( on_xstring_add ( on_xstring_new , content ) )
3355+ end
33313356 end
33323357 end
33333358
0 commit comments