Package net.cakenet.jsaton.script.ruby

Source Code of net.cakenet.jsaton.script.ruby.RubyExtractor$RubyDebugObjectProvider

package net.cakenet.jsaton.script.ruby;

import net.cakenet.jsaton.script.debug.*;
import net.cakenet.jsaton.script.debug.collections.*;
import org.jruby.*;
import org.jruby.java.proxies.JavaProxy;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.builtin.Variable;

import java.lang.reflect.Array;
import java.util.BitSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class RubyExtractor implements VariableExtractor<IRubyObject> {
    public DebugObject extractFrom(final Object o) {
        return new OnDemandDebugObject(new RubyDebugObjectProvider(o));
    }

    private DebugObject provide(final Object o) {
        if(o == null)
            return new SimpleDebugObject(null, null, "nil");

        if(o instanceof RubyNil)
            return new SimpleDebugObject(null, null, "nil");

        if(o instanceof DebugObject)
            return (DebugObject) o;

        Class c = o.getClass();
        if(c.isArray()) {
            final int len = Array.getLength(o);
            DebugArrayObject dao = new DebugArrayObject(new DebugArrayProvider() {
                private BitSet map = new BitSet(len);
                private DebugArrayElement[] provided = new DebugArrayElement[len];

                public int size() {
                    return len;
                }

                public DebugArrayElement get(int index) {
                    if(map.get(index))
                        return provided[index];
                    DebugObject v = extractFrom(Array.get(o, index));
                    DebugArrayElement created = new DebugArrayElement(index, v);
                    provided[index] = created;
                    map.set(index);
                    return created;
                }

                public int indexOf(Object child) {
                    for(int i = 0; i < provided.length; i++) {
                        Object p = map.get(i)? provided[i]: get(i);
                        if(p == child || (p != null && p.equals(child)))
                            return i;
                    }
                    return -1;
                }
            });
            return dao;
        }

        IRubyObject iro = (IRubyObject) o;

        if(o instanceof JavaProxy)
            return JavaExtractor.instance.extractFrom(((JavaProxy) o).getObject());
        if(iro instanceof RubyArray)
            return extractFrom(((RubyArray) iro).toJavaArray());
        if (iro instanceof RubyHash) {
            final RubyHash hash = (RubyHash) o;
            final Iterator kit = hash.directKeySet().iterator();
            final Iterator vit = hash.directValues().iterator();
            DebugObject dobj = new DebugMapObject(new AbstractDebugMapProvider() {
                protected DebugMapElement next() {
                    DebugObject val = extractFrom(vit.next());
                    DebugObject key = extractFrom(kit.next());
                    return new DebugMapElement(key, val);
                }

                public int size() {
                    return hash.size();
                }
            });
            return dobj;
        }
        // numeric...
        if(iro instanceof RubyFloat)
            return new SimpleDebugObject(null, iro.getType().toString(), ((RubyFloat) iro).getDoubleValue());
        if(iro instanceof RubyNumeric)
            return new SimpleDebugObject(null, iro.getType().toString(),
                    JavaExtractor.instance.extractFrom(((RubyNumeric) iro).getBigIntegerValue()));
        if(iro instanceof RubyString)
            return new SimpleDebugObject(null, iro.getType().toString(),
                    JavaExtractor.instance.extractFrom(((RubyString) iro).getUnicodeValue()));
        if(iro instanceof RubySymbol)
            return new SimpleDebugObject(null, iro.getType().toString(), ":" + iro.asJavaString());

        RubyClass clazz = iro.getType();
        List<String> names = iro.getVariableNameList();
        List<Variable<Object>> values = iro.getVariableList();
        SimpleDebugObject dobj =  new SimpleDebugObject(null, iro.getType().toString(), iro);
        List<DebugObject> vars = new LinkedList<>();
        for(int i = 0; i < names.size(); i++) {
            DebugObject val = extractFrom(values.get(i).getValue());
            val.setName(names.get(i));
            vars.add(val);
        }
        List<String> classVarNames = clazz.getClassVariableNameList();
        for(String classVarName: classVarNames) {
            DebugObject val = extractFrom(clazz.getClassVar(classVarName));
            val.setName(classVarName);
            vars.add(val);
        }
        dobj.variables = vars;
        return dobj;
    }

    class RubyDebugObjectProvider implements DebugObjectProvider {
        private Object source;

        public RubyDebugObjectProvider(Object source) {
            this.source = source;
        }

        public DebugObject provide() {
            return RubyExtractor.this.provide(source);
        }
    }
}
TOP

Related Classes of net.cakenet.jsaton.script.ruby.RubyExtractor$RubyDebugObjectProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.