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); }
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); }
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); }