|
14 | 14 | import java.util.ArrayDeque;
|
15 | 15 | import java.util.ArrayList;
|
16 | 16 | import java.util.Arrays;
|
| 17 | +import java.util.Collections; |
17 | 18 | import java.util.Deque;
|
18 | 19 | import java.util.Iterator;
|
19 | 20 | import java.util.List;
|
@@ -2469,58 +2470,87 @@ public RubyNode visitOpElementAsgnNode(OpElementAsgnParseNode node) {
|
2469 | 2470 | tempName,
|
2470 | 2471 | 0,
|
2471 | 2472 | node.getReceiverNode());
|
| 2473 | + final ArrayList<ValueFromNode> argValues = argsToTemp(node); |
2472 | 2474 |
|
2473 | 2475 | final String op = node.getOperatorName();
|
2474 | 2476 | final boolean logicalOperation = op.equals("&&") || op.equals("||");
|
2475 | 2477 |
|
2476 | 2478 | if (logicalOperation) {
|
2477 |
| - final ParseNode write = write(node, readReceiverFromTemp, value); |
2478 |
| - final ParseNode operation = operation(node, readReceiverFromTemp, op, write); |
| 2479 | + final ParseNode write = write(node, readReceiverFromTemp, argValues, value); |
| 2480 | + final ParseNode operation = operation(node, readReceiverFromTemp, argValues, op, write); |
2479 | 2481 |
|
2480 |
| - return block(node, writeReceiverToTemp, operation); |
| 2482 | + return block(node, writeReceiverToTemp, argValues, operation); |
2481 | 2483 | } else {
|
2482 |
| - final ParseNode operation = operation(node, readReceiverFromTemp, op, value); |
2483 |
| - final ParseNode write = write(node, readReceiverFromTemp, operation); |
| 2484 | + final ParseNode operation = operation(node, readReceiverFromTemp, argValues, op, value); |
| 2485 | + final ParseNode write = write(node, readReceiverFromTemp, argValues, operation); |
2484 | 2486 |
|
2485 |
| - return block(node, writeReceiverToTemp, write); |
| 2487 | + return block(node, writeReceiverToTemp, argValues, write); |
2486 | 2488 | }
|
2487 | 2489 | }
|
2488 | 2490 |
|
2489 |
| - private RubyNode block(OpElementAsgnParseNode node, ParseNode writeReceiverToTemp, ParseNode main) { |
| 2491 | + private RubyNode block(OpElementAsgnParseNode node, ParseNode writeReceiverToTemp, |
| 2492 | + ArrayList<ValueFromNode> argValues, ParseNode main) { |
2490 | 2493 | final BlockParseNode block = new BlockParseNode(node.getPosition());
|
2491 | 2494 | block.add(writeReceiverToTemp);
|
2492 | 2495 | block.add(main);
|
2493 | 2496 |
|
2494 |
| - final RubyNode ret = block.accept(this); |
| 2497 | + RubyNode ret = block.accept(this); |
| 2498 | + Collections.reverse(argValues); |
| 2499 | + for (var arg : argValues) { |
| 2500 | + ret = arg.prepareAndThen(node.getPosition(), ret); |
| 2501 | + } |
2495 | 2502 | return addNewlineIfNeeded(node, ret);
|
2496 | 2503 | }
|
2497 | 2504 |
|
2498 |
| - private ParseNode write(OpElementAsgnParseNode node, ParseNode readReceiverFromTemp, ParseNode value) { |
2499 |
| - final ParseNode readArguments = node.getArgsNode(); |
| 2505 | + private ParseNode write(OpElementAsgnParseNode node, ParseNode readReceiverFromTemp, |
| 2506 | + ArrayList<ValueFromNode> argValues, ParseNode value) { |
2500 | 2507 | final ParseNode writeArguments;
|
2501 | 2508 | // Like ParserSupport#arg_add, but copy the first node
|
2502 |
| - if (readArguments instanceof ArrayParseNode) { |
| 2509 | + if (node.getArgsNode() instanceof ArrayParseNode) { |
2503 | 2510 | final ArrayParseNode readArgsCopy = new ArrayParseNode(node.getPosition());
|
2504 |
| - readArgsCopy.addAll((ArrayParseNode) readArguments).add(value); |
| 2511 | + for (var arg : argValues) { |
| 2512 | + readArgsCopy.add(arg.get(node.getPosition())); |
| 2513 | + } |
| 2514 | + readArgsCopy.add(value); |
2505 | 2515 | writeArguments = readArgsCopy;
|
2506 | 2516 | } else {
|
2507 |
| - writeArguments = new ArgsPushParseNode(node.getPosition(), readArguments, value); |
| 2517 | + writeArguments = new ArgsPushParseNode(node.getPosition(), argValues.get(0).get(node.getPosition()), value); |
2508 | 2518 | }
|
2509 | 2519 |
|
2510 | 2520 | return new AttrAssignParseNode(node.getPosition(), readReceiverFromTemp, "[]=", writeArguments, false);
|
2511 | 2521 | }
|
2512 | 2522 |
|
| 2523 | + private ArrayList<ValueFromNode> argsToTemp(OpElementAsgnParseNode node) { |
| 2524 | + ArrayList<ValueFromNode> argValues = new ArrayList<>(); |
| 2525 | + |
| 2526 | + final ParseNode readArguments = node.getArgsNode(); |
| 2527 | + if (readArguments instanceof ArrayParseNode) { |
| 2528 | + for (ParseNode child : ((ArrayParseNode) readArguments).children()) { |
| 2529 | + argValues.add(ValueFromNode.valueFromNode(this, child)); |
| 2530 | + } |
| 2531 | + } else { |
| 2532 | + argValues.add(ValueFromNode.valueFromNode(this, readArguments)); |
| 2533 | + } |
| 2534 | + |
| 2535 | + return argValues; |
| 2536 | + } |
| 2537 | + |
2513 | 2538 | private ParseNode operation(
|
2514 | 2539 | OpElementAsgnParseNode node,
|
2515 | 2540 | ParseNode readReceiverFromTemp,
|
| 2541 | + ArrayList<ValueFromNode> argValues, |
2516 | 2542 | String op,
|
2517 | 2543 | ParseNode right) {
|
| 2544 | + final ArrayParseNode readArguments = new ArrayParseNode(node.getPosition()); |
| 2545 | + for (var arg : argValues) { |
| 2546 | + readArguments.add(arg.get(node.getPosition())); |
| 2547 | + } |
2518 | 2548 |
|
2519 | 2549 | final ParseNode read = new CallParseNode(
|
2520 | 2550 | node.getPosition(),
|
2521 | 2551 | readReceiverFromTemp,
|
2522 | 2552 | "[]",
|
2523 |
| - node.getArgsNode(), |
| 2553 | + readArguments, |
2524 | 2554 | null);
|
2525 | 2555 | ParseNode operation;
|
2526 | 2556 | switch (op) {
|
|
0 commit comments