Skip to content

Commit 7251471

Browse files
committed
Adopt CallNodeFlags' IGNORE_VISIBILITY flag
1 parent 90f59cf commit 7251471

File tree

4 files changed

+35
-32
lines changed

4 files changed

+35
-32
lines changed

spec/truffle/parsing/fixtures/operators/&&=/attribute_assignment_with_safe_navigation_operator.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ notes: >
1717
(IsNilNode
1818
(ReadLocalVariableNode)) # %value_0
1919
(AndNodeGen ...))
20+
yarp_specific: true # assign true value (instead of false) to isSafeNavigation attribute for a.foo and a.foo= calls
2021
focused_on_node: "org.truffleruby.language.defined.DefinedWrapperNode"
2122
ruby: |
2223
a&.foo &&= 42
@@ -85,7 +86,7 @@ ast: |
8586
emptyKeywordsProfile = false
8687
flags = 0
8788
isAttrAssign = false
88-
isSafeNavigation = false
89+
isSafeNavigation = true
8990
isSplatted = false
9091
isVCall = false
9192
lastArgIsNotHashProfile = false
@@ -107,7 +108,7 @@ ast: |
107108
emptyKeywordsProfile = false
108109
flags = 0
109110
isAttrAssign = true
110-
isSafeNavigation = false
111+
isSafeNavigation = true
111112
isSplatted = false
112113
isVCall = false
113114
lastArgIsNotHashProfile = false

spec/truffle/parsing/fixtures/operators/+=/attribute_assignment_with_safe_navigation_operator.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ notes: >
1818
(ReadLocalVariableNode)) # %value_0
1919
(RubyCallNode ...))
2020
yarp_specific: true # fixed assigning method call node and set `isAttrAssign = true`
21+
# assign true value (instead of false) to isSafeNavigation attribute for a.foo and a.foo= calls
2122
focused_on_node: "org.truffleruby.language.control.SequenceNode"
2223
ruby: |
2324
a&.foo += 42
@@ -89,7 +90,7 @@ ast: |
8990
emptyKeywordsProfile = false
9091
flags = 0
9192
isAttrAssign = true
92-
isSafeNavigation = false
93+
isSafeNavigation = true
9394
isSplatted = false
9495
isVCall = false
9596
lastArgIsNotHashProfile = false
@@ -112,7 +113,7 @@ ast: |
112113
emptyKeywordsProfile = false
113114
flags = 0
114115
isAttrAssign = false
115-
isSafeNavigation = false
116+
isSafeNavigation = true
116117
isSplatted = false
117118
isVCall = false
118119
lastArgIsNotHashProfile = false

spec/truffle/parsing/fixtures/operators/||=/attribute_assignment_with_safe_navigation_operator.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ notes: >
1717
(IsNilNode
1818
(ReadLocalVariableNode)) # %value_0
1919
(OrNodeGen ...))
20+
yarp_specific: true # assign true value (instead of false) to isSafeNavigation attribute for a.foo and a.foo= calls
2021
focused_on_node: "org.truffleruby.language.defined.DefinedWrapperNode"
2122
ruby: |
2223
a&.foo ||= 42
@@ -85,7 +86,7 @@ ast: |
8586
emptyKeywordsProfile = false
8687
flags = 0
8788
isAttrAssign = false
88-
isSafeNavigation = false
89+
isSafeNavigation = true
8990
isSplatted = false
9091
isVCall = false
9192
lastArgIsNotHashProfile = false
@@ -107,7 +108,7 @@ ast: |
107108
emptyKeywordsProfile = false
108109
flags = 0
109110
isAttrAssign = true
110-
isSafeNavigation = false
111+
isSafeNavigation = true
111112
isSplatted = false
112113
isVCall = false
113114
lastArgIsNotHashProfile = false

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

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -599,10 +599,11 @@ public RubyNode visitCallAndWriteNode(Nodes.CallAndWriteNode node) {
599599
final var writeReceiverNode = receiverExpression.getWriteNode();
600600
final var readReceiver = receiverExpression.getReadYARPNode();
601601

602-
// Use Prism nodes and rely on CallNode translation to automatically set CallNode flags
603-
// Ignore node.flags - it could be only SAFE_NAVIGATION that is handled manually
604-
final RubyNode readNode = callNode(node, readReceiver, node.read_name, Nodes.Node.EMPTY_ARRAY).accept(this);
605-
final RubyNode writeNode = callNode(node, Nodes.CallNodeFlags.ATTRIBUTE_WRITE, readReceiver, node.write_name,
602+
// Use Prism nodes and rely on CallNode translation to automatically set RubyCallNode attributes
603+
short writeFlags = (short) (node.flags | Nodes.CallNodeFlags.ATTRIBUTE_WRITE);
604+
final RubyNode readNode = callNode(node, node.flags, readReceiver, node.read_name, Nodes.Node.EMPTY_ARRAY)
605+
.accept(this);
606+
final RubyNode writeNode = callNode(node, writeFlags, readReceiver, node.write_name,
606607
node.value).accept(this);
607608
final RubyNode andNode = AndNodeGen.create(readNode, writeNode);
608609

@@ -628,9 +629,6 @@ public RubyNode visitCallNode(Nodes.CallNode node) {
628629
var argumentsAndBlock = translateArgumentsAndBlock(node.arguments, node.block, methodName);
629630
var translatedArguments = argumentsAndBlock.arguments();
630631

631-
// if the receiver is explicit or implicit 'self' then we can call private methods
632-
final boolean ignoreVisibility = node.receiver == null || node.receiver instanceof Nodes.SelfNode;
633-
634632
if (environment.getParseEnvironment().inCore() && node.isVariableCall() && methodName.equals("undefined")) {
635633
// translate undefined
636634
final RubyNode rubyNode = new ObjectLiteralNode(NotProvided.INSTANCE);
@@ -667,7 +665,7 @@ public RubyNode visitCallNode(Nodes.CallNode node) {
667665
argumentsAndBlock.argumentsDescriptor(),
668666
translatedArguments,
669667
argumentsAndBlock.isSplatted(),
670-
ignoreVisibility,
668+
node.isIgnoreVisibility(),
671669
node.isVariableCall(),
672670
node.isSafeNavigation(),
673671
node.isAttributeWrite());
@@ -789,10 +787,10 @@ public RubyNode visitCallOperatorWriteNode(Nodes.CallOperatorWriteNode node) {
789787
final var readReceiver = receiverExpression.getReadYARPNode();
790788

791789
// Use Prism nodes and rely on CallNode translation to automatically set CallNode flags
792-
// Ignore node.flags - it could be only SAFE_NAVIGATION that is handled manually
793-
final Nodes.Node read = callNode(node, readReceiver, node.read_name, Nodes.Node.EMPTY_ARRAY);
790+
short writeFlags = (short) (node.flags | Nodes.CallNodeFlags.ATTRIBUTE_WRITE);
791+
final Nodes.Node read = callNode(node, node.flags, readReceiver, node.read_name, Nodes.Node.EMPTY_ARRAY);
794792
final Nodes.Node executeOperator = callNode(node, read, node.operator, node.value);
795-
final Nodes.Node write = callNode(node, Nodes.CallNodeFlags.ATTRIBUTE_WRITE, readReceiver, node.write_name,
793+
final Nodes.Node write = callNode(node, writeFlags, readReceiver, node.write_name,
796794
executeOperator);
797795

798796
final RubyNode writeNode = write.accept(this);
@@ -823,9 +821,10 @@ public RubyNode visitCallOrWriteNode(Nodes.CallOrWriteNode node) {
823821
final var readReceiver = receiverExpression.getReadYARPNode();
824822

825823
// Use Prism nodes and rely on CallNode translation to automatically set CallNode flags
826-
// Ignore node.flags - it could be only SAFE_NAVIGATION that is handled manually
827-
final RubyNode readNode = callNode(node, readReceiver, node.read_name, Nodes.Node.EMPTY_ARRAY).accept(this);
828-
final RubyNode writeNode = callNode(node, Nodes.CallNodeFlags.ATTRIBUTE_WRITE, readReceiver, node.write_name,
824+
short writeFlags = (short) (node.flags | Nodes.CallNodeFlags.ATTRIBUTE_WRITE);
825+
final RubyNode readNode = callNode(node, node.flags, readReceiver, node.read_name, Nodes.Node.EMPTY_ARRAY)
826+
.accept(this);
827+
final RubyNode writeNode = callNode(node, writeFlags, readReceiver, node.write_name,
829828
node.value).accept(this);
830829
final RubyNode orNode = OrNodeGen.create(readNode, writeNode);
831830

@@ -1607,9 +1606,9 @@ public RubyNode visitForNode(Nodes.ForNode node) {
16071606
final var arguments = new Nodes.ArgumentsNode(NO_FLAGS, new Nodes.Node[]{ readParameter }, 0, 0);
16081607

16091608
// preserve target flags because they can contain SAFE_NAVIGATION flag
1610-
int flags = target.flags | Nodes.CallNodeFlags.ATTRIBUTE_WRITE;
1609+
short flags = (short) (target.flags | Nodes.CallNodeFlags.ATTRIBUTE_WRITE);
16111610

1612-
writeIndex = new Nodes.CallNode((short) flags, target.receiver, target.name, arguments, null, 0, 0);
1611+
writeIndex = new Nodes.CallNode(flags, target.receiver, target.name, arguments, null, 0, 0);
16131612
} else if (node.index instanceof Nodes.IndexTargetNode target) {
16141613
final Nodes.ArgumentsNode arguments;
16151614
final Nodes.Node[] statements;
@@ -1888,7 +1887,7 @@ public RubyNode visitIndexAndWriteNode(Nodes.IndexAndWriteNode node) {
18881887
}
18891888

18901889
final RubyNode rubyNode = translateIndexOrAndIndexAndWriteNodes(true, node.receiver, arguments, node.block,
1891-
node.value);
1890+
node.value, node.flags);
18921891
return assignPositionAndFlags(node, rubyNode);
18931892
}
18941893

@@ -1938,16 +1937,16 @@ public RubyNode visitIndexOperatorWriteNode(Nodes.IndexOperatorWriteNode node) {
19381937
readArguments[i] = expression.getReadYARPNode();
19391938
}
19401939

1941-
// Prism doesn't set any flag for IndexOperatorWriteNode right now
1942-
final Nodes.Node read = new Nodes.CallNode(NO_FLAGS, readReceiver, "[]",
1940+
final Nodes.Node read = new Nodes.CallNode(node.flags, readReceiver, "[]",
19431941
new Nodes.ArgumentsNode(NO_FLAGS, readArguments, 0, 0), blockArgument, 0, 0);
19441942
final Nodes.Node executeOperator = callNode(node, read, node.operator, node.value);
19451943

19461944
final Nodes.Node[] readArgumentsAndResult = new Nodes.Node[argumentsCount + 1];
19471945
System.arraycopy(readArguments, 0, readArgumentsAndResult, 0, argumentsCount);
19481946
readArgumentsAndResult[argumentsCount] = executeOperator;
19491947

1950-
final Nodes.Node write = new Nodes.CallNode(Nodes.CallNodeFlags.ATTRIBUTE_WRITE, readReceiver, "[]=",
1948+
short writeFlags = (short) (node.flags | Nodes.CallNodeFlags.ATTRIBUTE_WRITE);
1949+
final Nodes.Node write = new Nodes.CallNode(writeFlags, readReceiver, "[]=",
19511950
new Nodes.ArgumentsNode(NO_FLAGS, readArgumentsAndResult, 0, 0), blockArgument, 0, 0);
19521951
final RubyNode writeNode = write.accept(this);
19531952
final RubyNode writeArgumentsNode = sequence(Arrays.asList(writeArgumentsNodes));
@@ -1974,7 +1973,7 @@ public RubyNode visitIndexOrWriteNode(Nodes.IndexOrWriteNode node) {
19741973
}
19751974

19761975
final RubyNode rubyNode = translateIndexOrAndIndexAndWriteNodes(false, node.receiver, arguments, node.block,
1977-
node.value);
1976+
node.value, node.flags);
19781977
return assignPositionAndFlags(node, rubyNode);
19791978
}
19801979

@@ -2004,15 +2003,16 @@ public RubyNode visitIndexTargetNode(Nodes.IndexTargetNode node) {
20042003
node.arguments.length);
20052004
}
20062005

2007-
final var callNode = new Nodes.CallNode(node.flags, node.receiver, "[]=", argumentsNode, node.block,
2006+
short writeFlags = (short) (node.flags | Nodes.CallNodeFlags.ATTRIBUTE_WRITE);
2007+
final var callNode = new Nodes.CallNode(writeFlags, node.receiver, "[]=", argumentsNode, node.block,
20082008
node.startOffset,
20092009
node.length);
20102010
return callNode.accept(this);
20112011
}
20122012

20132013

20142014
private RubyNode translateIndexOrAndIndexAndWriteNodes(boolean isAndOperator, Nodes.Node receiver,
2015-
Nodes.Node[] arguments, Nodes.Node block, Nodes.Node value) {
2015+
Nodes.Node[] arguments, Nodes.Node block, Nodes.Node value, short flags) {
20162016
// Handle both &&= and ||= operators:
20172017
// `a[b] ||= c` is translated into `a[b] || a[b] = c`
20182018
// `a[b] &&= c` is translated into `a[b] && a[b] = c`
@@ -2050,16 +2050,16 @@ private RubyNode translateIndexOrAndIndexAndWriteNodes(boolean isAndOperator, No
20502050
blockArgument = null;
20512051
}
20522052

2053-
// Prism doesn't set any flag for IndexAndWriteNode and IndexOrWriteNode right now
2054-
final Nodes.Node read = new Nodes.CallNode(NO_FLAGS, readReceiver, "[]",
2053+
final Nodes.Node read = new Nodes.CallNode(flags, readReceiver, "[]",
20552054
new Nodes.ArgumentsNode(NO_FLAGS, readArguments, 0, 0), blockArgument, 0, 0);
20562055
final RubyNode readNode = read.accept(this);
20572056

20582057
final Nodes.Node[] readArgumentsAndValue = new Nodes.Node[arguments.length + 1];
20592058
System.arraycopy(readArguments, 0, readArgumentsAndValue, 0, arguments.length);
20602059
readArgumentsAndValue[arguments.length] = value;
20612060

2062-
final Nodes.Node write = new Nodes.CallNode(Nodes.CallNodeFlags.ATTRIBUTE_WRITE, readReceiver, "[]=",
2061+
short writeFlags = (short) (flags | Nodes.CallNodeFlags.ATTRIBUTE_WRITE);
2062+
final Nodes.Node write = new Nodes.CallNode(writeFlags, readReceiver, "[]=",
20632063
new Nodes.ArgumentsNode(NO_FLAGS, readArgumentsAndValue, 0, 0), blockArgument, 0, 0);
20642064
final RubyNode writeNode = write.accept(this);
20652065

0 commit comments

Comments
 (0)