forked from jruby/jruby
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDNode.java
More file actions
103 lines (84 loc) · 3.42 KB
/
Copy pathDNode.java
File metadata and controls
103 lines (84 loc) · 3.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package org.jruby.ast;
import org.jcodings.Encoding;
import org.jruby.Ruby;
import org.jruby.RubyFixnum;
import org.jruby.RubyFloat;
import org.jruby.RubyString;
import org.jruby.RubySymbol;
import org.jruby.javasupport.util.RuntimeHelpers;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.runtime.Block;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
import org.jruby.util.DefinedMessage;
import org.jruby.util.StringSupport;
/**
* Base class for all D (e.g. Dynamic) node types like DStrNode, DSymbolNode, etc...
*/
public abstract class DNode extends ListNode {
protected Encoding encoding; // If encoding is set then we should obey 1.9 semantics.
public DNode(ISourcePosition position) {
this(position, null);
}
public DNode(ISourcePosition position, Encoding encoding) {
super(position);
this.encoding = encoding;
}
public Encoding getEncoding() {
return encoding;
}
@Override
public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
return buildDynamicString(runtime, context, self, aBlock);
}
// Enebo: Without massive rethink of AST system I think we are stuck with an if check
public boolean is19() {
return encoding != null;
}
public boolean isSameEncoding(StrNode strNode) {
return strNode.getValue().getEncoding() == encoding;
}
protected RubyString allocateString(Ruby runtime) {
RubyString string = RubyString.newString(runtime, new ByteList());
if (is19()) string.setEncoding(encoding);
return string;
}
public void appendToString(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock, RubyString string, Node node) {
if (node instanceof StrNode) {
StrNode strNode = (StrNode)node;
if (!is19() || isSameEncoding(strNode)) {
string.getByteList().append(strNode.getValue());
} else {
string.cat19(strNode.getValue(), strNode.getCodeRange());
}
} else if (node instanceof EvStrNode) {
EvStrNode evStrNode = (EvStrNode)node;
Node bodyNode = evStrNode.getBody();
if (bodyNode == null) return;
IRubyObject body = bodyNode.interpret(runtime, context, self, aBlock);
if (is19()) {
RuntimeHelpers.shortcutAppend(string, body);
} else {
RuntimeHelpers.shortcutAppend18(string, body);
}
} else if (is19()) {
string.append19(node.interpret(runtime, context, self, aBlock));
} else {
string.append(node.interpret(runtime, context, self, aBlock));
}
}
public RubyString buildDynamicString(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
RubyString string = allocateString(runtime);
int size = size();
for (int i = 0; i < size; i++) {
appendToString(runtime, context, self, aBlock, string, get(i));
}
return string;
}
@Override
public RubyString definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
RubyString definition = super.definition(runtime, context, self, aBlock);
return is19() && definition == null ? runtime.getDefinedMessage(DefinedMessage.EXPRESSION) : definition;
}
}