|
11 | 11 |
|
12 | 12 | import com.oracle.truffle.api.nodes.Node;
|
13 | 13 | import com.oracle.truffle.api.source.Source;
|
| 14 | +import com.oracle.truffle.api.source.SourceSection; |
14 | 15 | import com.oracle.truffle.api.strings.TruffleString;
|
15 | 16 | import org.truffleruby.RubyLanguage;
|
16 | 17 | import org.truffleruby.annotations.Split;
|
|
30 | 31 | import org.truffleruby.language.RubyNode;
|
31 | 32 | import org.truffleruby.language.RubyRootNode;
|
32 | 33 | import org.truffleruby.language.RubyTopLevelRootNode;
|
33 |
| -import org.truffleruby.language.SourceIndexLength; |
34 | 34 | import org.truffleruby.language.arguments.EmptyArgumentsDescriptor;
|
35 | 35 | import org.truffleruby.language.constants.ReadConstantNode;
|
36 | 36 | import org.truffleruby.language.control.AndNodeGen;
|
37 | 37 | import org.truffleruby.language.control.IfElseNodeGen;
|
38 | 38 | import org.truffleruby.language.control.IfNodeGen;
|
39 | 39 | import org.truffleruby.language.control.OrNodeGen;
|
40 | 40 | import org.truffleruby.language.control.RetryNode;
|
| 41 | +import org.truffleruby.language.control.SequenceNode; |
41 | 42 | import org.truffleruby.language.control.UnlessNodeGen;
|
42 | 43 | import org.truffleruby.language.defined.DefinedNode;
|
43 | 44 | import org.truffleruby.language.dispatch.RubyCallNode;
|
|
64 | 65 |
|
65 | 66 | import java.nio.charset.StandardCharsets;
|
66 | 67 | import java.util.Arrays;
|
| 68 | +import java.util.List; |
67 | 69 |
|
| 70 | +// NOTE: we should avoid SourceIndexLength in YARPTranslator, instead pass a Nodes.Node as location, |
| 71 | +// because that's inefficient and there is typically no need for such an object since YARP location info is correct. |
68 | 72 | public final class YARPTranslator extends AbstractNodeVisitor<RubyNode> {
|
69 | 73 |
|
70 | 74 | private final RubyLanguage language;
|
@@ -251,21 +255,19 @@ public RubyNode visitClassVariableOperatorWriteNode(Nodes.ClassVariableOperatorW
|
251 | 255 | }
|
252 | 256 |
|
253 | 257 | public RubyNode visitClassVariableReadNode(Nodes.ClassVariableReadNode node) {
|
254 |
| - final SourceIndexLength sourceSection = new SourceIndexLength(node.startOffset, node.length); |
255 | 258 | final RubyNode rubyNode = new ReadClassVariableNode(
|
256 |
| - getLexicalScopeNode("class variable lookup", sourceSection), |
| 259 | + getLexicalScopeNode("class variable lookup", node), |
257 | 260 | toString(node));
|
258 | 261 |
|
259 | 262 | assignNodePositionInSource(node, rubyNode);
|
260 | 263 | return rubyNode;
|
261 | 264 | }
|
262 | 265 |
|
263 | 266 | public RubyNode visitClassVariableWriteNode(Nodes.ClassVariableWriteNode node) {
|
264 |
| - final SourceIndexLength sourceSection = new SourceIndexLength(node.startOffset, node.length); |
265 | 267 | final RubyNode rhs = node.value.accept(this);
|
266 | 268 |
|
267 | 269 | final RubyNode rubyNode = new WriteClassVariableNode(
|
268 |
| - getLexicalScopeNode("set dynamic class variable", sourceSection), |
| 270 | + getLexicalScopeNode("set dynamic class variable", node), |
269 | 271 | toString(node.name_loc),
|
270 | 272 | rhs);
|
271 | 273 |
|
@@ -451,8 +453,7 @@ public RubyNode visitIfNode(Nodes.IfNode node) {
|
451 | 453 | } else {
|
452 | 454 | // if (condition)
|
453 | 455 | // end
|
454 |
| - final SourceIndexLength sourceSection = new SourceIndexLength(node.startOffset, node.length); |
455 |
| - rubyNode = Translator.sequence(sourceSection, Arrays.asList(conditionNode, new NilLiteralNode(true))); |
| 456 | + rubyNode = sequence(node, Arrays.asList(conditionNode, new NilLiteralNode(true))); |
456 | 457 | }
|
457 | 458 |
|
458 | 459 | return rubyNode;
|
@@ -786,14 +787,12 @@ public RubyNode visitSplatNode(Nodes.SplatNode node) {
|
786 | 787 | }
|
787 | 788 |
|
788 | 789 | public RubyNode visitStatementsNode(Nodes.StatementsNode node) {
|
789 |
| - var location = new SourceIndexLength(node.startOffset, node.length); |
790 |
| - |
791 | 790 | var body = node.body;
|
792 | 791 | var translated = new RubyNode[body.length];
|
793 | 792 | for (int i = 0; i < body.length; i++) {
|
794 | 793 | translated[i] = body[i].accept(this);
|
795 | 794 | }
|
796 |
| - return Translator.sequence(location, Arrays.asList(translated)); |
| 795 | + return sequence(node, Arrays.asList(translated)); |
797 | 796 | }
|
798 | 797 |
|
799 | 798 | public RubyNode visitStringConcatNode(Nodes.StringConcatNode node) {
|
@@ -859,8 +858,7 @@ public RubyNode visitUnlessNode(Nodes.UnlessNode node) {
|
859 | 858 | } else {
|
860 | 859 | // unless (condition)
|
861 | 860 | // end
|
862 |
| - final SourceIndexLength sourceSection = new SourceIndexLength(node.startOffset, node.length); |
863 |
| - rubyNode = Translator.sequence(sourceSection, Arrays.asList(conditionNode, new NilLiteralNode(true))); |
| 861 | + rubyNode = sequence(node, Arrays.asList(conditionNode, new NilLiteralNode(true))); |
864 | 862 | }
|
865 | 863 |
|
866 | 864 | return rubyNode;
|
@@ -891,27 +889,11 @@ protected RubyNode defaultVisit(Nodes.Node node) {
|
891 | 889 | throw new Error("Unknown node: " + node);
|
892 | 890 | }
|
893 | 891 |
|
894 |
| - protected RubyNode translateNodeOrNil(SourceIndexLength sourceSection, Nodes.Node node) { |
895 |
| - final RubyNode rubyNode; |
896 |
| - if (node == null) { |
897 |
| - rubyNode = nilNode(sourceSection); |
898 |
| - } else { |
899 |
| - rubyNode = node.accept(this); |
900 |
| - } |
901 |
| - return rubyNode; |
902 |
| - } |
903 |
| - |
904 |
| - protected RubyNode nilNode(SourceIndexLength sourceSection) { |
905 |
| - final RubyNode literal = new NilLiteralNode(false); |
906 |
| - literal.unsafeSetSourceSection(sourceSection); |
907 |
| - return literal; |
908 |
| - } |
909 |
| - |
910 |
| - private RubyNode getLexicalScopeNode(String kind, SourceIndexLength sourceSection) { |
| 892 | + private RubyNode getLexicalScopeNode(String kind, Nodes.Node yarpNode) { |
911 | 893 | if (environment.isDynamicConstantLookup()) {
|
912 | 894 | if (language.options.LOG_DYNAMIC_CONSTANT_LOOKUP) {
|
913 | 895 | RubyLanguage.LOGGER.info(() -> kind + " at " +
|
914 |
| - RubyLanguage.getCurrentContext().fileLine(sourceSection.toSourceSection(source))); |
| 896 | + RubyLanguage.getCurrentContext().fileLine(getSourceSection(yarpNode))); |
915 | 897 | }
|
916 | 898 | return new GetDynamicLexicalScopeNode();
|
917 | 899 | } else {
|
@@ -946,15 +928,37 @@ private String toString(Nodes.SymbolNode node) {
|
946 | 928 | return new String(node.unescaped);
|
947 | 929 | }
|
948 | 930 |
|
949 |
| - private void assignNodePositionInSource(Nodes.Node yarpNode, RubyNode rubyNode) { |
| 931 | + private SourceSection getSourceSection(Nodes.Node yarpNode) { |
| 932 | + return source.createSection(yarpNode.startOffset, yarpNode.length); |
| 933 | + } |
| 934 | + |
| 935 | + private static void assignNodePositionInSource(Nodes.Node yarpNode, RubyNode rubyNode) { |
950 | 936 | rubyNode.unsafeSetSourceSection(yarpNode.startOffset, yarpNode.length);
|
951 | 937 | copyNewlineFlag(yarpNode, rubyNode);
|
952 | 938 | }
|
953 | 939 |
|
954 |
| - private void copyNewlineFlag(Nodes.Node yarpNode, RubyNode rubyNode) { |
| 940 | + private static void copyNewlineFlag(Nodes.Node yarpNode, RubyNode rubyNode) { |
955 | 941 | if (yarpNode.hasNewLineFlag()) {
|
956 | 942 | rubyNode.unsafeSetIsNewLine();
|
957 | 943 | }
|
958 | 944 | }
|
959 | 945 |
|
| 946 | + private static RubyNode sequence(Nodes.Node yarpNode, List<RubyNode> sequence) { |
| 947 | + assert !yarpNode.hasNewLineFlag() : "Expected node passed to sequence() to not have a newline flag"; |
| 948 | + final List<RubyNode> flattened = Translator.flatten(sequence, true); |
| 949 | + |
| 950 | + if (flattened.isEmpty()) { |
| 951 | + final RubyNode nilNode = new NilLiteralNode(true); |
| 952 | + assignNodePositionInSource(yarpNode, nilNode); |
| 953 | + return nilNode; |
| 954 | + } else if (flattened.size() == 1) { |
| 955 | + return flattened.get(0); |
| 956 | + } else { |
| 957 | + final RubyNode[] flatSequence = flattened.toArray(RubyNode.EMPTY_ARRAY); |
| 958 | + var sequenceNode = new SequenceNode(flatSequence); |
| 959 | + assignNodePositionInSource(yarpNode, sequenceNode); |
| 960 | + return sequenceNode; |
| 961 | + } |
| 962 | + } |
| 963 | + |
960 | 964 | }
|
0 commit comments