/**
 * Copyright 2005-2007 Ye Zheng
 * Distributed under the GNU General Public License 2.0
 */

package com.xruby.runtime.lang;

public class RubySingletonClass extends RubyClass {

    private RubyValue owner_;

    public RubySingletonClass(RubyValue owner, RubyClass superclass, RubyModule scope) {
        super(null, superclass, scope);
        owner_ = owner;
        owner.setRubyClass(this);
        this.setInstanceVariable(owner, RubyID.attachedID);

        if (owner instanceof RubySingletonClass) {
            RubySingletonClass klass = (RubySingletonClass)owner;
            this.setRubyClass(this);
            RubyClass singletonsuper = klass.getSuperClass().getRealClass().getRubyClass();
            klass.setSuperClass(singletonsuper);
        } else {
            RubyClass metasuper = superclass.getRealClass().getRubyClass();
            if (metasuper != null) {
                this.setRubyClass(metasuper);
            }
        }
    }

    public RubyValue getConstant(String name) {
        RubyValue v = getOwnConstant(name);
        if (null != v) {
            return v;
        }

        if (owner_ instanceof RubyModule) {
            v = ((RubyModule)owner_).getConstant(name);
            if (null != v) {
                return v;
            }
        }

        return super.getConstant(name);
    }

    public RubyValue getClassVariable(String name) {
        if (owner_ instanceof RubyModule) {
            return ((RubyModule)owner_).getClassVariable(name);
        } else {
            return super.getClassVariable(name);
        }
    }

    public boolean isSingleton() {
        return true;
    }

    public boolean isRealClass() {
        return false;
    }

    public RubyValue allocObject(RubyBlock block) {
        throw new RubyException(RubyRuntime.TypeErrorClass, "can't create instance of virtual class");
    }
}

/**
 * Copyright 2005-2007 Ye Zheng
 * Distributed under the GNU General Public License 2.0
 */

package com.xruby.runtime.lang;

public class RubySingletonClass extends RubyClass {

    private RubyValue owner_;

    public RubySingletonClass(RubyValue owner, RubyClass superclass, RubyModule scope) {
        super(null, superclass, scope);
        owner_ = owner;
        owner.setRubyClass(this);
        this.setInstanceVariable(owner, RubyID.attachedID);

        if (owner instanceof RubySingletonClass) {
            RubySingletonClass klass = (RubySingletonClass)owner;
            this.setRubyClass(this);
            RubyClass singletonsuper = klass.getSuperClass().getRealClass().getRubyClass();
            klass.setSuperClass(singletonsuper);
        } else {
            RubyClass metasuper = superclass.getRealClass().getRubyClass();
            if (metasuper != null) {
                this.setRubyClass(metasuper);
            }
        }
    }

    public RubyValue getConstant(String name) {
        RubyValue v = getOwnConstant(name);
        if (null != v) {
            return v;
        }

        if (owner_ instanceof RubyModule) {
            v = ((RubyModule)owner_).getConstant(name);
            if (null != v) {
                return v;
            }
        }

        //TODO this will call 'getOwnConstant' again, which is a waste of time
        return super.getConstant(name);
    }

    public RubyValue getClassVariable(String name) {
        if (owner_ instanceof RubyModule) {
            return ((RubyModule)owner_).getClassVariable(name);
        } else {
            return super.getClassVariable(name);
        }
    }

    public boolean isSingleton() {
        return true;
    }

    public boolean isRealClass() {
        return false;
    }

    public RubyValue allocObject(RubyBlock block) {
        throw new RubyException(RubyRuntime.TypeErrorClass, "can't create instance of virtual class");
    }
}

add a TODO