@@ -1564,6 +1564,10 @@ public RubyNode visitInterpolatedRegularExpressionNode(Nodes.InterpolatedRegular
1564
1564
1565
1565
@ Override
1566
1566
public RubyNode visitInterpolatedStringNode (Nodes .InterpolatedStringNode node ) {
1567
+ if (allPartsAreStringNodes (node )) {
1568
+ return visitStringNode (concatStringNodes (node ));
1569
+ }
1570
+
1567
1571
final ToSNode [] children = translateInterpolatedParts (node .parts );
1568
1572
1569
1573
final RubyNode rubyNode = new InterpolatedStringNode (children , sourceEncoding .jcoding );
@@ -1588,6 +1592,38 @@ public RubyNode visitInterpolatedXStringNode(Nodes.InterpolatedXStringNode node)
1588
1592
return assignPositionAndFlags (node , rubyNode );
1589
1593
}
1590
1594
1595
+ private static boolean allPartsAreStringNodes (Nodes .InterpolatedStringNode node ) {
1596
+ for (var part : node .parts ) {
1597
+ if (!(part instanceof Nodes .StringNode )) {
1598
+ return false ;
1599
+ }
1600
+ }
1601
+ return true ;
1602
+ }
1603
+
1604
+ private static Nodes .StringNode concatStringNodes (Nodes .InterpolatedStringNode node ) {
1605
+ Nodes .Node [] parts = node .parts ;
1606
+ assert parts .length > 0 ;
1607
+
1608
+ int totalSize = 0 ;
1609
+ for (var part : parts ) {
1610
+ totalSize += ((Nodes .StringNode ) part ).unescaped .length ;
1611
+ }
1612
+
1613
+ byte [] concatenated = new byte [totalSize ];
1614
+ int i = 0 ;
1615
+ for (var part : parts ) {
1616
+ byte [] bytes = ((Nodes .StringNode ) part ).unescaped ;
1617
+ System .arraycopy (bytes , 0 , concatenated , i , bytes .length );
1618
+ i += bytes .length ;
1619
+ }
1620
+
1621
+ int start = parts [0 ].startOffset ;
1622
+ var last = parts [parts .length - 1 ];
1623
+ int length = last .endOffset () - start ;
1624
+ return new Nodes .StringNode (NO_FLAGS , concatenated , start , length );
1625
+ }
1626
+
1591
1627
private ToSNode [] translateInterpolatedParts (Nodes .Node [] parts ) {
1592
1628
final ToSNode [] children = new ToSNode [parts .length ];
1593
1629
@@ -2661,7 +2697,7 @@ private void assignPositionOnly(Nodes.Node[] nodes, RubyNode rubyNode) {
2661
2697
final Nodes .Node first = nodes [0 ];
2662
2698
final Nodes .Node last = nodes [nodes .length - 1 ];
2663
2699
2664
- final int length = last .startOffset - first .startOffset + last . length ;
2700
+ final int length = last .endOffset () - first .startOffset ;
2665
2701
rubyNode .unsafeSetSourceSection (first .startOffset , length );
2666
2702
}
2667
2703
0 commit comments