@@ -189,9 +189,65 @@ public RubyNode visitAttrAssignNode(org.jruby.ast.AttrAssignNode node) {
189
189
* See translateDummyAssignment to understand what this is for.
190
190
*/
191
191
public RubyNode visitAttrAssignNodeExtraArgument (org .jruby .ast .AttrAssignNode node , RubyNode extraArgument ) {
192
- final CallNode callNode = new CallNode (node .getPosition (), node .getReceiverNode (), node .getName (), node .getArgsNode (), null );
193
- boolean isAccessorOnSelf = (node .getReceiverNode () instanceof org .jruby .ast .SelfNode );
194
- return visitCallNodeExtraArgument (callNode , extraArgument , isAccessorOnSelf , false );
192
+ final SourceSection sourceSection = translate (node .getPosition ());
193
+
194
+ // The last argument is the value we assign, and we need to return that as the whole result of this node
195
+
196
+ if (extraArgument == null ) {
197
+ // Get that last argument out
198
+ final List <org .jruby .ast .Node > argChildNodes = new ArrayList <>(node .getArgsNode ().childNodes ());
199
+ final org .jruby .ast .Node valueNode = argChildNodes .get (argChildNodes .size () - 1 );
200
+ argChildNodes .remove (argChildNodes .size () - 1 );
201
+
202
+ // Evaluate the value and store it in a local variable
203
+ final FrameSlot frameSlot = environment .declareVar (environment .allocateLocalTemp ("attrasgn" ));
204
+ final WriteLocalVariableNode writeValue = WriteLocalVariableNodeFactory .create (context , sourceSection , frameSlot , valueNode .accept (this ));
205
+
206
+ // Recreate the arguments array, reading that local instead of including the RHS for the last argument
207
+ argChildNodes .add (new ReadLocalDummyNode (sourceSection , frameSlot ));
208
+ final org .jruby .ast .ArrayNode newArgsNode = new org .jruby .ast .ArrayNode (node .getPosition (), argChildNodes .get (0 ));
209
+ argChildNodes .remove (0 );
210
+ for (org .jruby .ast .Node child : argChildNodes ) {
211
+ newArgsNode .add (child );
212
+ }
213
+
214
+ final CallNode callNode = new CallNode (node .getPosition (), node .getReceiverNode (), node .getName (), newArgsNode , null );
215
+ boolean isAccessorOnSelf = (node .getReceiverNode () instanceof org .jruby .ast .SelfNode );
216
+ final RubyNode actualCall = visitCallNodeExtraArgument (callNode , null , isAccessorOnSelf , false );
217
+
218
+ return SequenceNode .sequence (context , sourceSection ,
219
+ writeValue ,
220
+ actualCall ,
221
+ ReadLocalVariableNodeFactory .create (context , sourceSection , frameSlot ));
222
+ } else {
223
+ final RubyNode valueNode = extraArgument ;
224
+
225
+ // Evaluate the value and store it in a local variable
226
+ final FrameSlot frameSlot = environment .declareVar (environment .allocateLocalTemp ("attrasgn" ));
227
+ final WriteLocalVariableNode writeValue = WriteLocalVariableNodeFactory .create (context , sourceSection , frameSlot , valueNode );
228
+
229
+ // Recreate the arguments array, reading that local instead of including the RHS for the last argument
230
+ final List <org .jruby .ast .Node > argChildNodes = new ArrayList <>();
231
+ if (node .getArgsNode () != null ) {
232
+ argChildNodes .addAll (node .getArgsNode ().childNodes ());
233
+ }
234
+ argChildNodes .add (new ReadLocalDummyNode (sourceSection , frameSlot ));
235
+ final org .jruby .ast .ArrayNode newArgsNode = new org .jruby .ast .ArrayNode (node .getPosition (), argChildNodes .get (0 ));
236
+ argChildNodes .remove (0 );
237
+ for (org .jruby .ast .Node child : argChildNodes ) {
238
+ newArgsNode .add (child );
239
+ }
240
+
241
+ final CallNode callNode = new CallNode (node .getPosition (), node .getReceiverNode (), node .getName (), newArgsNode , null );
242
+ boolean isAccessorOnSelf = (node .getReceiverNode () instanceof org .jruby .ast .SelfNode );
243
+ final RubyNode actualCall = visitCallNodeExtraArgument (callNode , null , isAccessorOnSelf , false );
244
+
245
+ return SequenceNode .sequence (context , sourceSection ,
246
+ writeValue ,
247
+ actualCall ,
248
+ ReadLocalVariableNodeFactory .create (context , sourceSection , frameSlot ));
249
+ }
250
+
195
251
}
196
252
197
253
@ Override
@@ -2325,4 +2381,14 @@ protected String getIdentifier() {
2325
2381
}
2326
2382
}
2327
2383
2384
+ @ Override
2385
+ public RubyNode visitOther (Node node ) {
2386
+ if (node instanceof ReadLocalDummyNode ) {
2387
+ final ReadLocalDummyNode readLocal = (ReadLocalDummyNode ) node ;
2388
+ return ReadLocalVariableNodeFactory .create (context , readLocal .getSourceSection (), readLocal .getFrameSlot ());
2389
+ } else {
2390
+ throw new UnsupportedOperationException ();
2391
+ }
2392
+ }
2393
+
2328
2394
}
0 commit comments