Skip to content

Commit befc299

Browse files
committed
Translate nodes (method call) - fix RubyCallNode#isSplatted and SplatCastNode#copy
1 parent 7cd5751 commit befc299

File tree

4 files changed

+78
-90
lines changed

4 files changed

+78
-90
lines changed

spec/tags/truffle/parsing/parsing_tags.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,6 @@ fails:Parsing a Method call (super / outside a method body with explicit argumen
7575
fails:Parsing a Method call (super / outside a method body without explicit arguments) case is parsed correctly
7676
fails:Parsing a Method call (Arguments/with a &-deconstruction to a block argument (&bar)) case is parsed correctly
7777
fails:Parsing a Method call (Arguments/with block literal argument) case is parsed correctly
78-
fails:Parsing a Method call (Arguments/with double splat operator (**kw)) case is parsed correctly
79-
fails:Parsing a Method call (Arguments/with positional argument and splat operator (a, *args)) case is parsed correctly
80-
fails:Parsing a Method call (Arguments/with splat operator (*args)) case is parsed correctly
81-
fails:Parsing a Method call (Arguments/with splat operator and positional arguments (*args, a)) case is parsed correctly
8278
fails:Parsing a Method call (Special cases/method #lambda (Kernel#lambda)) case is parsed correctly
8379
fails:Parsing a Method call (Special cases/method #lambda (not Kernel#lambda)) case is parsed correctly
8480
fails:Parsing a Method call (super / in a method body with explicit arguments) case is parsed correctly

spec/truffle/parsing/fixtures/method_calls/arguments/with_positional_argument_and_splat_operator.yaml

Lines changed: 37 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ subject: "Method call"
22
description: "Arguments/with positional argument and splat operator (a, *args)"
33
notes: |
44
is represented by ArrayConcatNode and SplatCastNodeGen
5+
yarp_specific: true # Simplified AST and replaced ArrayAppendOneNodeGen by concatenating with array of one element
56
focused_on_node: "org.truffleruby.language.dispatch.RubyCallNode"
67
ruby: |
78
foo(bar, *baz)
@@ -22,65 +23,52 @@ ast: |
2223
notRuby2KeywordsHashProfile = false
2324
children:
2425
arguments = [
25-
ArrayConcatNode
26+
RubyCallNode
2627
attributes:
28+
descriptor = org.truffleruby.language.arguments.EmptyArgumentsDescriptor@...
29+
dispatchConfig = PRIVATE
30+
emptyKeywordsProfile = false
2731
flags = 0
32+
isAttrAssign = false
33+
isSafeNavigation = false
34+
isSplatted = false
35+
isVCall = true
36+
lastArgIsNotHashProfile = false
37+
methodName = "bar"
38+
notEmptyKeywordsProfile = false
39+
notRuby2KeywordsHashProfile = false
2840
children:
29-
children = [
30-
ArrayLiteralNode$UninitialisedArrayLiteralNode
41+
receiver =
42+
SelfNode
3143
attributes:
3244
flags = 0
33-
language = org.truffleruby.RubyLanguage@...
34-
children:
35-
values = [
36-
RubyCallNode
37-
attributes:
38-
descriptor = org.truffleruby.language.arguments.EmptyArgumentsDescriptor@...
39-
dispatchConfig = PRIVATE
40-
emptyKeywordsProfile = false
41-
flags = 0
42-
isAttrAssign = false
43-
isSafeNavigation = false
44-
isSplatted = false
45-
isVCall = true
46-
lastArgIsNotHashProfile = false
47-
methodName = "bar"
48-
notEmptyKeywordsProfile = false
49-
notRuby2KeywordsHashProfile = false
50-
children:
51-
receiver =
52-
SelfNode
53-
attributes:
54-
flags = 0
55-
]
56-
SplatCastNodeGen
45+
SplatCastNodeGen
46+
attributes:
47+
conversionMethod = :to_a
48+
copy = true
49+
flags = 0
50+
nilBehavior = CONVERT
51+
children:
52+
childNode_ =
53+
RubyCallNode
5754
attributes:
58-
conversionMethod = :to_a
59-
copy = true
55+
descriptor = org.truffleruby.language.arguments.EmptyArgumentsDescriptor@...
56+
dispatchConfig = PRIVATE
57+
emptyKeywordsProfile = false
6058
flags = 0
61-
nilBehavior = CONVERT
59+
isAttrAssign = false
60+
isSafeNavigation = false
61+
isSplatted = false
62+
isVCall = true
63+
lastArgIsNotHashProfile = false
64+
methodName = "baz"
65+
notEmptyKeywordsProfile = false
66+
notRuby2KeywordsHashProfile = false
6267
children:
63-
childNode_ =
64-
RubyCallNode
68+
receiver =
69+
SelfNode
6570
attributes:
66-
descriptor = org.truffleruby.language.arguments.EmptyArgumentsDescriptor@...
67-
dispatchConfig = PRIVATE
68-
emptyKeywordsProfile = false
6971
flags = 0
70-
isAttrAssign = false
71-
isSafeNavigation = false
72-
isSplatted = false
73-
isVCall = true
74-
lastArgIsNotHashProfile = false
75-
methodName = "baz"
76-
notEmptyKeywordsProfile = false
77-
notRuby2KeywordsHashProfile = false
78-
children:
79-
receiver =
80-
SelfNode
81-
attributes:
82-
flags = 0
83-
]
8472
]
8573
receiver =
8674
SelfNode

spec/truffle/parsing/fixtures/method_calls/arguments/with_splat_operator_and_positional_arguments.yaml

Lines changed: 26 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ notes: |
55
- ArrayAppendOneNodeGen,
66
- KernelNodesFactory$DupASTNodeFactory$DupASTNodeGen
77
- SplatCastNodeGen
8+
yarp_specific: true # Simplified AST and replaced ArrayAppendOneNodeGen by concatenating with array of one element
89
focused_on_node: "org.truffleruby.language.dispatch.RubyCallNode"
910
ruby: |
1011
foo(*bar, baz)
@@ -25,44 +26,14 @@ ast: |
2526
notRuby2KeywordsHashProfile = false
2627
children:
2728
arguments = [
28-
ArrayAppendOneNodeGen
29+
SplatCastNodeGen
2930
attributes:
31+
conversionMethod = :to_a
32+
copy = true
3033
flags = 0
34+
nilBehavior = CONVERT
3135
children:
32-
arrayNode_ =
33-
KernelNodesFactory$DupASTNodeFactory$DupASTNodeGen
34-
attributes:
35-
flags = 0
36-
children:
37-
selfNode_ =
38-
SplatCastNodeGen
39-
attributes:
40-
conversionMethod = :to_a
41-
copy = true
42-
flags = 0
43-
nilBehavior = CONVERT
44-
children:
45-
childNode_ =
46-
RubyCallNode
47-
attributes:
48-
descriptor = org.truffleruby.language.arguments.EmptyArgumentsDescriptor@...
49-
dispatchConfig = PRIVATE
50-
emptyKeywordsProfile = false
51-
flags = 0
52-
isAttrAssign = false
53-
isSafeNavigation = false
54-
isSplatted = false
55-
isVCall = true
56-
lastArgIsNotHashProfile = false
57-
methodName = "bar"
58-
notEmptyKeywordsProfile = false
59-
notRuby2KeywordsHashProfile = false
60-
children:
61-
receiver =
62-
SelfNode
63-
attributes:
64-
flags = 0
65-
valueNode_ =
36+
childNode_ =
6637
RubyCallNode
6738
attributes:
6839
descriptor = org.truffleruby.language.arguments.EmptyArgumentsDescriptor@...
@@ -74,14 +45,33 @@ ast: |
7445
isSplatted = false
7546
isVCall = true
7647
lastArgIsNotHashProfile = false
77-
methodName = "baz"
48+
methodName = "bar"
7849
notEmptyKeywordsProfile = false
7950
notRuby2KeywordsHashProfile = false
8051
children:
8152
receiver =
8253
SelfNode
8354
attributes:
8455
flags = 0
56+
RubyCallNode
57+
attributes:
58+
descriptor = org.truffleruby.language.arguments.EmptyArgumentsDescriptor@...
59+
dispatchConfig = PRIVATE
60+
emptyKeywordsProfile = false
61+
flags = 0
62+
isAttrAssign = false
63+
isSafeNavigation = false
64+
isSplatted = false
65+
isVCall = true
66+
lastArgIsNotHashProfile = false
67+
methodName = "baz"
68+
notEmptyKeywordsProfile = false
69+
notRuby2KeywordsHashProfile = false
70+
children:
71+
receiver =
72+
SelfNode
73+
attributes:
74+
flags = 0
8575
]
8676
receiver =
8777
SelfNode

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,20 @@ public RubyNode visitCallNode(Nodes.CallNode node) {
459459
final boolean isAttrAssign = methodName.endsWith("=");
460460
final boolean isSafeNavigation = node.isSafeNavigation();
461461

462+
final boolean isSplatted;
463+
boolean isSplatFound = false;
464+
for (var n : arguments) { // check if there is splat operator in the arguments list
465+
if (n instanceof Nodes.SplatNode) {
466+
isSplatFound = true;
467+
}
468+
}
469+
isSplatted = isSplatFound;
470+
471+
// No need to copy the array for call(*splat), the elements will be copied to the frame arguments
472+
if (isSplatted && translatedArguments.length == 1 && translatedArguments[0] instanceof SplatCastNode splatNode) {
473+
splatNode.doNotCopy();
474+
}
475+
462476
// TODO (pitr-ch 02-Dec-2019): replace with a primitive
463477
if (environment.getParseEnvironment().inCore() && isVariableCall && methodName.equals("undefined")) {
464478
// translate undefined
@@ -499,7 +513,7 @@ public RubyNode visitCallNode(Nodes.CallNode node) {
499513
null,
500514
argumentsDescriptor,
501515
translatedArguments,
502-
false,
516+
isSplatted,
503517
ignoreVisibility,
504518
isVariableCall,
505519
isSafeNavigation,

0 commit comments

Comments
 (0)