
org.jruby.ast.DNode Maven / Gradle / Ivy
package org.jruby.ast;
import org.jcodings.Encoding;
import org.jruby.Ruby;
import org.jruby.RubyString;
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.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) {
ByteList bytes = new ByteList();
if (is19()) bytes.setEncoding(encoding);
return RubyString.newStringShared(runtime, bytes, StringSupport.CR_7BIT);
}
public void appendToString(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock, RubyString string, Node node) {
if (node instanceof StrNode && (!is19() || isSameEncoding((StrNode) node))) {
string.getByteList().append(((StrNode) node).getValue());
} 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 ByteList definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
ByteList definition = super.definition(runtime, context, self, aBlock);
return is19() && definition == null ? EXPRESSION_BYTELIST : definition;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy