Skip to content

Commit b1011e0

Browse files
committed
Translate "ab" "cd" as a single StringLiteralNode
1 parent 62a86db commit b1011e0

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
subject: "String"
2+
description: "2 string literals concatenated at parse/translation time"
3+
focused_on_node: "org.truffleruby.language.literal.StringLiteralNode"
4+
ruby: |
5+
"foo" "bar"
6+
ast: |
7+
StringLiteralNode
8+
attributes:
9+
encoding = UTF-8
10+
flags = 0
11+
tstring = foobar

src/main/java/org/truffleruby/parser/YARPTranslator.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1564,6 +1564,10 @@ public RubyNode visitInterpolatedRegularExpressionNode(Nodes.InterpolatedRegular
15641564

15651565
@Override
15661566
public RubyNode visitInterpolatedStringNode(Nodes.InterpolatedStringNode node) {
1567+
if (allPartsAreStringNodes(node)) {
1568+
return visitStringNode(concatStringNodes(node));
1569+
}
1570+
15671571
final ToSNode[] children = translateInterpolatedParts(node.parts);
15681572

15691573
final RubyNode rubyNode = new InterpolatedStringNode(children, sourceEncoding.jcoding);
@@ -1588,6 +1592,38 @@ public RubyNode visitInterpolatedXStringNode(Nodes.InterpolatedXStringNode node)
15881592
return assignPositionAndFlags(node, rubyNode);
15891593
}
15901594

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+
15911627
private ToSNode[] translateInterpolatedParts(Nodes.Node[] parts) {
15921628
final ToSNode[] children = new ToSNode[parts.length];
15931629

@@ -2661,7 +2697,7 @@ private void assignPositionOnly(Nodes.Node[] nodes, RubyNode rubyNode) {
26612697
final Nodes.Node first = nodes[0];
26622698
final Nodes.Node last = nodes[nodes.length - 1];
26632699

2664-
final int length = last.startOffset - first.startOffset + last.length;
2700+
final int length = last.endOffset() - first.startOffset;
26652701
rubyNode.unsafeSetSourceSection(first.startOffset, length);
26662702
}
26672703

0 commit comments

Comments
 (0)