示例#1
0
        private static object ConstructRubyStruct(RubyConstructor /*!*/ ctor, string /*!*/ structName, Node /*!*/ node)
        {
            MappingNode mapping = node as MappingNode;

            if (mapping == null)
            {
                throw new ConstructorException("can only construct struct from mapping node");
            }

            if (structName.Length == 0)
            {
                // TODO:
                throw new NotSupportedException("anonymous structs not supported");
            }

            RubyContext context = ctor.GlobalScope.Context;
            RubyModule  module;

            // TODO: MRI calls "members" on an arbitrary object

            // MRI checks Struct first, then falls back to Object
            if (!context.TryGetModule(ctor.GlobalScope, "Struct::" + structName, out module) &&
                !context.TryGetModule(ctor.GlobalScope, structName, out module))
            {
                throw RubyExceptions.CreateTypeError("Undefined struct `{0}'", structName);
            }

            RubyClass cls = module as RubyClass;

            if (cls == null)
            {
                throw RubyExceptions.CreateTypeError("`{0}' is not a class", structName);
            }

            RubyStruct newStruct = RubyStruct.Create(cls);

            foreach (var pair in ctor.ConstructMapping(mapping))
            {
                var attributeName = pair.Key as MutableString;
                int index;

                // TODO: encoding
                if (attributeName != null && newStruct.TryGetIndex(attributeName.ToString(), out index))
                {
                    newStruct[index] = pair.Value;
                }
            }
            return(newStruct);
        }
示例#2
0
        public static object /*!*/ CreateObject(RubyClass /*!*/ theClass)
        {
            Assert.NotNull(theClass);

            Type baseType = theClass.GetUnderlyingSystemType();

            if (baseType == typeof(RubyStruct))
            {
                return(RubyStruct.Create(theClass));
            }

            object          result;
            BindingFlags    bindingFlags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
            ConstructorInfo ci;

            if (IsAvailable(ci = baseType.GetConstructor(bindingFlags, null, Type.EmptyTypes, null)))
            {
                result = ci.Invoke(new object[0] {
                });
            }
            else if (IsAvailable(ci = baseType.GetConstructor(bindingFlags, null, _ccTypes1, null)))
            {
                result = ci.Invoke(new object[1] {
                    theClass
                });
            }
            else if (IsAvailable(ci = baseType.GetConstructor(bindingFlags, null, _ccTypes2, null)))
            {
                result = ci.Invoke(new object[1] {
                    theClass.Context
                });
            }
            else
            {
                string message = String.Format("Class {0} does not have a valid constructor", theClass.Name);
                throw new NotSupportedException(message);
            }
            return(result);
        }
示例#3
0
        public static object ConstructRubyStruct(IConstructor ctor, string className, Node node)
        {
            MappingNode mapping = node as MappingNode;

            if (mapping == null)
            {
                throw new ConstructorException("can only construct struct from mapping node");
            }

            RubyScope  scope = ctor.Scope;
            RubyModule module;
            RubyClass  cls;

            if (scope.RubyContext.TryGetModule(scope.GlobalScope, className, out module))
            {
                cls = module as RubyClass;
                if (cls == null)
                {
                    throw new ConstructorException("Struct type name must be Ruby class");
                }
            }
            else
            {
                RubyModule structModule = scope.RubyContext.GetModule(typeof(RubyStruct));
                cls = RubyUtils.GetConstant(scope, structModule, className, false) as RubyClass;
                if (cls == null)
                {
                    throw new ConstructorException(String.Format("Cannot find struct class \"{0}\"", className));
                }
            }

            RubyStruct newStruct = RubyStruct.Create(cls);

            foreach (var pair in ctor.ConstructMapping(mapping))
            {
                RubyStructOps.SetValue(newStruct, SymbolTable.StringToId(pair.Key.ToString()), pair.Value);
            }
            return(newStruct);
        }