Skip to content

Commit b3d5b54

Browse files
eregonandrykonchin
authored andcommitted
Workaround flags of interpolated regexp string parts causing issues
1 parent b272bee commit b3d5b54

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,10 @@ protected final void copyNewlineFlag(Nodes.Node yarpNode, RubyNode rubyNode) {
215215
}
216216
}
217217

218+
protected void copyNewLineFlag(Nodes.Node source, Nodes.Node target) {
219+
target.setNewLineFlag(source.hasNewLineFlag());
220+
}
221+
218222
protected static RubyNode sequence(Nodes.Node yarpNode, RubyNode... sequence) {
219223
assert !yarpNode.hasNewLineFlag() : "Expected node passed to sequence() to not have a newline flag";
220224

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

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2387,7 +2387,7 @@ public RubyNode visitInterpolatedMatchLastLineNode(Nodes.InterpolatedMatchLastLi
23872387
public RubyNode visitInterpolatedRegularExpressionNode(Nodes.InterpolatedRegularExpressionNode node) {
23882388
var encodingAndOptions = getRegexpEncodingAndOptions(new Nodes.RegularExpressionFlags(node.flags));
23892389
var options = encodingAndOptions.options;
2390-
final ToSNode[] children = translateInterpolatedParts(node.parts);
2390+
final ToSNode[] children = translateInterpolatedPartsIgnoreForceEncodingFlags(node.parts);
23912391

23922392
final RubyEncoding encoding;
23932393
if (!options.isKcodeDefault()) { // explicit encoding
@@ -2526,6 +2526,31 @@ private ToSNode[] translateInterpolatedParts(Nodes.Node[] parts) {
25262526
return children;
25272527
}
25282528

2529+
/** Regexp encoding negotiation does not work correctly if such flags are kept, e.g. for /#{ }\xc2\xa1/e in
2530+
* test_m17n.rb. Not clear what is a good solution yet. */
2531+
private ToSNode[] translateInterpolatedPartsIgnoreForceEncodingFlags(Nodes.Node[] parts) {
2532+
final ToSNode[] children = new ToSNode[parts.length];
2533+
2534+
for (int i = 0; i < parts.length; i++) {
2535+
RubyNode expression;
2536+
if (parts[i] instanceof Nodes.StringNode stringNode) {
2537+
short flags = stringNode.isFrozen() ? Nodes.StringFlags.FROZEN : NO_FLAGS;
2538+
Nodes.StringNode stringNodeNoForceEncoding = new Nodes.StringNode(flags, stringNode.unescaped,
2539+
stringNode.startOffset, stringNode.length);
2540+
2541+
// Prism might assign new line flag not to the outer regexp node but to its first part instead
2542+
copyNewLineFlag(stringNode, stringNodeNoForceEncoding);
2543+
2544+
expression = stringNodeNoForceEncoding.accept(this);
2545+
} else {
2546+
expression = parts[i].accept(this);
2547+
}
2548+
children[i] = ToSNodeGen.create(expression);
2549+
}
2550+
2551+
return children;
2552+
}
2553+
25292554
@Override
25302555
public RubyNode visitItParametersNode(Nodes.ItParametersNode node) {
25312556
throw CompilerDirectives.shouldNotReachHere("ItParametersNode is only from Ruby 3.4");

0 commit comments

Comments
 (0)