public static JsTypeFunction Define(string name, JsTypeFunction prototype) { JsTypeFunction typeFunction = null; // Create constructor function, which is a superconstructor that takes in the actual // constructor as the first argument, and the rest of the arguments are passed directly // to that constructor. These subconstructors are not Javascript constructors -- they // are not called via new, they exist for initialization only. typeFunction = Jsni.function(constructor => { if (constructor != null || !(Jsni.instanceof(Jsni.@this(), typeFunction))) { Jsni.invoke(Jsni.member(typeFunction, SpecialNames.StaticInitializer)); } if (constructor != null) { Jsni.apply(constructor, Jsni.@this(), Jsni.call(Jsni.reference("Array.prototype.slice"), Jsni.arguments(), 1.As < JsObject > ()).As <JsArray>()); } if (!Jsni.instanceof(Jsni.@this(), typeFunction)) { return(typeFunction); } else { return(Jsni.@this()); } }).As <JsTypeFunction>(); Jsni.memberset(typeFunction, "toString", Jsni.function(() => name.As <JsObject>())); Jsni.memberset(typeFunction, SpecialNames.TypeName, name.As <JsString>()); Jsni.memberset(typeFunction, "prototype", Jsni.@new(prototype)); return(typeFunction); }
public static T[] FastArrayCopy <T>(T[] array) { JsFunction function = Jsni.procedure(() => {}); function.prototype = array.As <JsObject>(); return(Jsni.@new(function).As <T[]>()); }
public static JsTypeFunction DefineTypeParameter(string name, JsTypeFunction prototype) { var result = Define(name, prototype); result.memberset(SpecialNames.CreateType, Jsni.function(() => { var type = Type.CreateTypeParameter(name, prototype); result.Type = type; return(result); })); return(result); }
public static JsFunction DefineStaticConstructor(JsTypeFunction enclosingType, JsFunction implementation) { return(Jsni.procedure(() => { if (enclosingType.IsStaticInitialized) { return; } enclosingType.IsStaticInitialized = true; implementation.invoke(); })); }
public static JsTypeFunction DefineTypeParameter(JsFunction assembly, string name, JsTypeFunction prototype) { var result = Define(assembly, null, name, false, Jsni.array(), prototype, Jsni.procedure(() => {})); result.memberset(SpecialNames.IsTypeParameter, true); result.memberset(SpecialNames.CreateType, Jsni.function(() => { var type = Type.CreateTypeParameter(name, prototype); result.Type = type; type.thisType = result; return(result); })); return(result); }
public static JsFunction CreateConstructor(JsTypeFunction enclosingType, JsFunction implementation) { implementation.memberset(SpecialNames.TypeField, enclosingType); implementation.memberset(SpecialNames.New, Jsni.function(() => { /* * if (!enclosingType.IsPrototypeInitialized) * { * enclosingType.IsPrototypeInitialized = true; * enclosingType.prototype = Jsni.@new(enclosingType.PrototypeFactory.invoke()); * } */ return(Jsni.@new(enclosingType, implementation, Jsni.arguments())); })); return(implementation); }
public static JsFunction CreateDelegate(JsObject thisExpression, JsFunction lambda, JsTypeFunction delegateType = null, string delegateKey = null) { delegateType = delegateType ?? Jsni.reference("System.Delegate").As <JsTypeFunction>(); JsFunction delegateFunc = null; delegateFunc = Jsni.function(() => { return(lambda.apply(delegateFunc.As <Delegate>().Target.As <JsObject>(), Jsni.arguments().As <JsArray>())); }); delegateFunc.prototype = Jsni.@new(delegateType); delegateFunc.memberset("get_Target", Jsni.function(() => thisExpression)); delegateFunc.memberset("GetType", Jsni.function(() => delegateType.GetTypeFromType.invoke())); Jsni.memberset(delegateFunc, SpecialNames.TypeField, delegateType); Jsni.memberset(delegateFunc, "Invoke", delegateFunc); Jsni.memberset(delegateFunc, "DynamicInvoke", Jsni.function(args => delegateFunc.apply(delegateFunc, args.As <JsArray>()))); Jsni.memberset(delegateFunc, "GetHashCode", Jsni.function(() => lambda.toString().GetHashCode().As <JsObject>())); Jsni.memberset(delegateFunc, "lambda", lambda); Jsni.memberset(delegateFunc, "Equals", Jsni.function(x => x != null && lambda == x.member("lambda"))); return(delegateFunc); }
public static JsFunction CreateDelegate(JsObject thisExpression, JsTypeFunction delegateType, JsFunction lambda, string delegateKey = null) { if (delegateKey != null) { if (thisExpression[delegateKey]) { return(thisExpression[delegateKey].As <JsFunction>()); } } else { if (lambda.member("$delegate") != null) { return(lambda.member("$delegate").As <JsFunction>()); } } JsFunction delegateFunc = null; delegateFunc = Jsni.function(() => { return(lambda.apply(delegateFunc.As <Delegate>().Target.As <JsObject>(), Jsni.arguments().As <JsArray>())); }); delegateFunc.prototype = Jsni.@new(delegateType); Jsni.type <object>().TypeInitializer.invoke(delegateFunc, delegateFunc); Jsni.type <Delegate>().TypeInitializer.invoke(delegateFunc, delegateFunc); Jsni.type <MulticastDelegate>().TypeInitializer.invoke(delegateFunc, delegateFunc); delegateType.TypeInitializer.invoke(delegateFunc, delegateFunc); Jsni.invoke(Jsni.member(Jsni.member(Jsni.type <MulticastDelegate>().prototype, "$ctor"), "call"), delegateFunc, thisExpression, new[] { delegateFunc }.As <JsArray>()); Jsni.memberset(delegateFunc, SpecialNames.TypeField, delegateType); if (delegateKey != null) { thisExpression[delegateKey] = delegateFunc; } else { lambda.memberset("$delegate", delegateFunc); } return(delegateFunc); }
public static Type SafeGetType(object o) { var jsObject = o.As <JsObject>(); if (jsObject.member("GetType") != null) { return(jsObject.member("GetType").invoke().As <Type>()); } var type = Jsni._typeof(jsObject); if (type == "boolean") { return(typeof(bool)); } if (type == "number") { return(typeof(Number)); } throw new Exception("Unable to determine type of: " + o); }
public static string SafeToString(object o) { return(o == null ? "" : Jsni._typeof(o.As <JsObject>()) == "boolean" ? o.As <JsObject>().toString().As <string>() : o.ToString()); }
internal static JsTypeFunction MakeArrayType(JsTypeFunction elementType) { if (elementType.ArrayType == null) { var baseType = MakeGenericTypeFactory(Jsni.type(typeof(GenericArray <>)), Jsni.array(elementType)); var arrayType = Jsni.procedure(() => {}).As <JsTypeFunction>(); arrayType.prototype = Jsni.@new(baseType); Jsni.apply( Jsni.type <Object>().TypeInitializer, Jsni.@this(), Jsni.array(arrayType, arrayType.prototype)); Jsni.apply( Jsni.type <Array>().TypeInitializer, Jsni.@this(), Jsni.invoke( Jsni.member(Jsni.array(arrayType, arrayType.prototype), "concat"), elementType ).As <JsArray>()); arrayType.TypeInitializer = Jsni.procedure((t, p) => { p.___type = arrayType; t.As <JsTypeFunction>().TypeName = elementType.TypeName + "[]"; t.As <JsTypeFunction>().BaseType = baseType; t.As <JsTypeFunction>().ElementType = elementType; t.As <JsTypeFunction>().GetTypeFromType = Jsni.function(() => Type._GetTypeFromTypeFunc(Jsni.@this().As <JsTypeFunction>()).As <JsObject>()); t.As <JsTypeFunction>().CreateTypeField = Jsni.function(() => { var lastIndex = elementType.TypeName.LastIndexOf('.'); if (lastIndex == -1) { lastIndex = 0; } else { lastIndex++; } var type = new Type(elementType.TypeName.Substring(lastIndex) + "[]", new Attribute[0]); arrayType.Type = type; type.Init( elementType.TypeName + "[]", TypeAttributes.Public, elementType, Jsni.type <Array>(), typeof(Array).interfaces.Concat(new[] { SpecialFunctions.MakeGenericTypeFactory(Jsni.type(typeof(IEnumerable <>)), Jsni.array(elementType)) }).ToArray(), new JsTypeFunction[0], new FieldInfo[0], new MethodInfo[0], new ConstructorInfo[0], new PropertyInfo[0], new EventInfo[0], false, false, false, false, elementType, null); return(type.As <JsObject>()); }); }, SpecialNames.TypeInitializerTypeFunction, SpecialNames.TypeInitializerPrototype); Jsni.call(arrayType.TypeInitializer, Jsni.@this(), arrayType, arrayType.prototype); var result = arrayType; elementType.ArrayType = result; } return(elementType.ArrayType); }
internal static JsTypeFunction MakeGenericTypeFactory(JsTypeFunction unconstructedType, JsArray typeArgs) { var cache = Jsni.member(unconstructedType, SpecialNames.TypeCache); if (cache == null) { cache = new JsObject(); unconstructedType.memberset(SpecialNames.TypeCache, cache); } var keyArray = Jsni.call <JsArray>(x => x.slice(0), typeArgs, 0.As < JsNumber > ()).As <JsArray>(); var keyParts = new JsArray(); for (var i = 0; i < keyArray.length; i++) { keyParts[i] = keyArray[i].member(SpecialNames.TypeName); } var keyString = keyParts.join(", "); var result = cache[keyString]; if (result == null) { var lastIndexOfDollar = unconstructedType.TypeName.LastIndexOf('`'); var newTypeName = unconstructedType.TypeName.Substring(0, lastIndexOfDollar) + "<" + keyString + ">"; var prototype = unconstructedType.BaseType; if (prototype.member("$")) { prototype = prototype.member("$").apply(null, typeArgs).As <JsTypeFunction>(); } var generic = Define(newTypeName, prototype); generic.memberset(SpecialNames.UnconstructedType, unconstructedType); // unconstructedType.$TypeInitializer.apply(this, [generic, generic.prototype].concat(Array.prototype.slice.call(arguments, 0))); Jsni.apply( Jsni.member(unconstructedType, SpecialNames.TypeInitializer), unconstructedType, Jsni.invoke( Jsni.member(Jsni.array(generic, generic.prototype), "concat"), keyArray ).As <JsArray>()); generic.TypeInitializer = Jsni.procedure((t, p) => { p.___type = generic; t.As <JsTypeFunction>().BaseType = unconstructedType; t.As <JsTypeFunction>().GetTypeFromType = Jsni.function(() => Type._GetTypeFromTypeFunc(Jsni.@this().As <JsTypeFunction>()).As <JsObject>()); t.As <JsTypeFunction>().CreateTypeField = Jsni.function(() => { var unconstructedTypeType = Type._GetTypeFromTypeFunc(unconstructedType); var type = new Type(newTypeName, new Attribute[0]); generic.Type = type; type.Init( newTypeName, unconstructedTypeType.typeAttributes, generic, unconstructedType.BaseType, unconstructedTypeType.interfaces, InitializeArray(typeArgs, Jsni.type <JsTypeFunction>()).As <JsTypeFunction[]>(), unconstructedTypeType.fields, unconstructedTypeType.methods, unconstructedTypeType.constructors, unconstructedTypeType.properties, unconstructedTypeType.events, false, false, true, false, null, unconstructedType); return(type.As <JsObject>()); }); }, SpecialNames.TypeInitializerTypeFunction, SpecialNames.TypeInitializerPrototype); Jsni.call(generic.TypeInitializer, Jsni.@this(), generic, generic.prototype); result = generic; cache[keyString] = result; } return(result.As <JsTypeFunction>()); }
internal static JsTypeFunction MakeGenericTypeFactory(JsTypeFunction unconstructedType, JsArray typeArgs) { var cache = Jsni.member(unconstructedType, SpecialNames.TypeCache); if (cache == null) { cache = new JsObject(); unconstructedType.memberset(SpecialNames.TypeCache, cache); } var keyArray = Jsni.call <JsArray>(x => x.slice(0), typeArgs, 0.As < JsNumber > ()).As <JsArray>(); var keyParts = new JsArray(); for (var i = 0; i < keyArray.length; i++) { keyParts[i] = keyArray[i].member(SpecialNames.TypeName); } var keyString = keyParts.join(", "); var result = cache[keyString]; if (result == null) { var lastIndexOfDollar = unconstructedType.TypeName.LastIndexOf('`'); var newTypeName = unconstructedType.TypeName.Substring(0, lastIndexOfDollar) + "<" + keyString + ">"; var prototype = unconstructedType.BaseType; if (prototype.member("$")) { prototype = prototype.member("$").apply(null, typeArgs).As <JsTypeFunction>(); } var generic = Define(newTypeName, prototype); generic.memberset(SpecialNames.UnconstructedType, unconstructedType); // unconstructedType.$TypeInitializer.apply(this, [generic, generic.prototype].concat(Array.prototype.slice.call(arguments, 0))); Jsni.apply( Jsni.member(unconstructedType, SpecialNames.TypeInitializer), unconstructedType, Jsni.invoke( Jsni.member(Jsni.array(generic, generic.prototype), "concat"), keyArray ).As <JsArray>()); generic.TypeInitializer = Jsni.procedure((t, p) => { p.___type = generic; t.As <JsTypeFunction>().BaseType = unconstructedType; t.As <JsTypeFunction>().GetTypeFromType = Jsni.function(() => Type._GetTypeFromTypeFunc(Jsni.@this().As <JsTypeFunction>()).As <JsObject>()); t.As <JsTypeFunction>().TypeName = newTypeName; t.As <JsTypeFunction>().CreateTypeField = Jsni.function(() => { var unconstructedTypeType = Type._GetTypeFromTypeFunc(unconstructedType); var type = new Type(newTypeName, new Attribute[0]); generic.Type = type; type.thisType = generic; var typeParameters = unconstructedTypeType.typeArguments; var typeArguments = InitializeArray(typeArgs, Jsni.type <JsTypeFunction>()).As <JsTypeFunction[]>(); Func <Type, JsTypeFunction> reifyGenerics = null; reifyGenerics = theType => { if (theType == null) { return(null); } if (theType.IsArray) { var elementType = theType.GetElementType(); var arrayType = MakeArrayType(reifyGenerics(elementType)); return(arrayType); } if (theType.IsGenericParameter) { for (int i = 0; i < typeArguments.Length; i++) { var typeParameter = typeParameters[i]; var typeArgument = typeArguments[i]; if (typeParameter.TypeName == theType.FullName) { return(typeArgument); } } } else if (theType.IsGenericTypeDefinition) { return(MakeGenericTypeFactory(theType.thisType, theType.GenericTypeArguments.Select(x => reifyGenerics(x)).ToArray().As <JsArray>())); } else if (theType.IsGenericType) { JsTypeFunction[] newTypeArguments = null; for (var i = 0; i < theType.typeArguments.Length; i++) { var theTypeArgument = theType.typeArguments[i]; for (var j = 0; j < typeParameters.Length; j++) { var typeParameter = typeParameters[j]; var typeArgument = typeArguments[j]; if (theTypeArgument == typeParameter) { if (newTypeArguments == null) { newTypeArguments = new JsTypeFunction[theType.typeArguments.Length]; for (var k = 0; k < theType.typeArguments.Length; k++) { newTypeArguments[k] = theType.typeArguments[k]; } } newTypeArguments[i] = typeArgument; } } } if (newTypeArguments != null) { return(MakeGenericTypeFactory(theType.unconstructedType, newTypeArguments.As <JsArray>())); } else { return(theType.thisType); } } return(theType.thisType); }; var newInterfaces = unconstructedTypeType.interfaces.ToArray(); for (var i = 0; i < newInterfaces.Length; i++) { var intf = newInterfaces[i]; intf = reifyGenerics(Type._GetTypeFromTypeFunc(intf)); newInterfaces[i] = intf; } var newConstructors = unconstructedTypeType.constructors.ToArray(); for (var i = 0; i < newConstructors.Length; i++) { var constructor = newConstructors[i]; var parameters = constructor.GetParameters(); for (var j = 0; j < parameters.Length; j++) { var parameter = parameters[j]; var parameterType = reifyGenerics(parameter.ParameterType); parameter = new ParameterInfo(parameter.Name, parameterType, j, parameter.Attributes, parameter.DefaultValue, parameter.attributes); parameters[j] = parameter; } newConstructors[i] = new ConstructorInfo(constructor.Name, generic.prototype[constructor.Name].As <JsFunction>(), parameters, constructor.Attributes, constructor.attributes); } var newProperties = unconstructedTypeType.properties.ToArray(); for (var i = 0; i < newProperties.Length; i++) { var property = newProperties[i]; var propertyTypeType = property.PropertyType; var propertyType = reifyGenerics(propertyTypeType); newProperties[i] = new PropertyInfo(property.Name, propertyType, property.GetGetMethod(), property.GetSetMethod(), property.GetIndexParameters(), property.attributes); } var newMethods = unconstructedTypeType.methods.ToArray(); for (var i = 0; i < newMethods.Length; i++) { var method = newMethods[i]; var returnTypeType = method.ReturnType; var returnType = reifyGenerics(returnTypeType); var parameters = method.GetParameters(); for (var j = 0; j < parameters.Length; j++) { var parameter = parameters[j]; var parameterType = reifyGenerics(parameter.ParameterType); parameter = new ParameterInfo(parameter.Name, parameterType, j, parameter.Attributes, parameter.DefaultValue, parameter.attributes); parameters[j] = parameter; } method = new MethodInfo(method.Name, method.jsMethod, parameters, returnType, method.Attributes, method.attributes); newMethods[i] = method; } type.Init( newTypeName, unconstructedTypeType.typeAttributes, generic, unconstructedType.BaseType, newInterfaces, typeArguments, unconstructedTypeType.fields, newMethods, newConstructors, newProperties, unconstructedTypeType.events, false, unconstructedTypeType.IsAbstract, unconstructedTypeType.IsInterface, false, true, false, unconstructedTypeType.IsEnum, null, unconstructedType); return(type.As <JsObject>()); }); }, SpecialNames.TypeInitializerTypeFunction, SpecialNames.TypeInitializerPrototype); Jsni.call(generic.TypeInitializer, Jsni.@this(), generic, generic.prototype); result = generic; cache[keyString] = result; } return(result.As <JsTypeFunction>()); }
public static JsTypeFunction Define(JsFunction assembly, JsTypeFunction enclosingType, string name, bool isGenericType, JsArray typeParameters, JsObject prototype, JsFunction typeInitializer) { JsTypeFunction typeFunction = null; var isTypeInitialized = false; // Create constructor function, which is a superconstructor that takes in the actual // constructor as the first argument, and the rest of the arguments are passed directly // to that constructor. These subconstructors are not Javascript constructors -- they // are not called via new, they exist for initialization only. typeFunction = Jsni.function((constructor, args) => { if (constructor != null || !(Jsni.instanceof(Jsni.@this(), typeFunction))) { if (!isGenericType || typeFunction.UnconstructedType != null) { typeFunction.member(SpecialNames.StaticInitializer).invoke(); } } if (constructor != null) { constructor.apply(Jsni.@this(), args.As <JsArray>()); } if (!Jsni.instanceof(Jsni.@this(), typeFunction)) { return(typeFunction); } else { return(Jsni.@this()); } }).As <JsTypeFunction>(); typeFunction.GetAssembly = assembly; assembly.member(SpecialNames.AssemblyTypesArray).member("push").invoke(typeFunction); typeFunction.memberset("toString", Jsni.function(() => name.As <JsObject>())); typeFunction.EnclosingType = enclosingType; typeFunction.TypeName = name; typeFunction.prototype = Jsni.@new(prototype); typeFunction.IsPrototypeInitialized = false; typeFunction.TypeInitializer = Jsni.procedure((_t, p) => { var t = _t.As <JsTypeFunction>(); if (isGenericType) { var unconstructedType = t.UnconstructedType ?? t; t.GenericTypeFunction = Jsni.function(() => { return(Jsni.reference(SpecialNames.MakeGenericTypeConstructor).As <JsFunction>().call(unconstructedType, unconstructedType, Jsni.arguments()).As <JsFunction>().invoke()); }); } t.GetTypeFromType = Jsni.function(() => { return(Type._GetTypeFromTypeFunc(Jsni.@this().As <JsTypeFunction>()).As <JsObject>()); }); p.memberset(SpecialNames.TypeName, t.member(SpecialNames.TypeName)); p.___type = t; t.BaseType = prototype.As <JsTypeFunction>(); typeInitializer.apply(Jsni.@this(), Jsni.arguments().As <JsArray>()); }); typeFunction.CallTypeInitializer = Jsni.procedure(() => { typeFunction.TypeInitializer.apply(enclosingType, Jsni.array(typeFunction, typeFunction.prototype).concat(typeParameters)); }); return(typeFunction); }
internal static JsTypeFunction MakeGenericTypeFactory(JsTypeFunction unconstructedType, JsArray typeArgs) { var cache = Jsni.member(unconstructedType, SpecialNames.TypeCache); JsObject result = null; if (typeArgs.length > 0) { if (cache == null) { cache = new JsObject(); unconstructedType.memberset(SpecialNames.TypeCache, cache); } JsObject currentCache = cache; for (var i = 0; i < typeArgs.length - 1; i++) { var nextCache = currentCache[typeArgs[i].member(SpecialNames.TypeName)]; if (nextCache == null) { nextCache = new JsObject(); currentCache[typeArgs[i].member(SpecialNames.TypeName)] = nextCache; } currentCache = nextCache; } cache = currentCache; result = cache[typeArgs[typeArgs.length - 1].member(SpecialNames.TypeName)]; } else { result = cache; } // JsObject keyString; // First two if statements are optimizations for performance reasons to avoid heap allocation when possible. /* * if (typeArgs.length == 0) * keyString = ""; * else if (typeArgs.length == 1) * keyString = typeArgs[0].member(SpecialNames.TypeName); * else * { * var keyArray = Jsni.call<JsArray>(x => x.slice(0), typeArgs, 0.As<JsNumber>()).As<JsArray>(); * var keyParts = new JsArray(); * for (var i = 0; i < keyArray.length; i++) * { * keyParts[i] = keyArray[i].member(SpecialNames.TypeName); * } * keyString = keyParts.join(", "); * } * * var result = cache[keyString]; */ if (result == null) { var keyArray = Jsni.call <JsArray>(x => x.slice(0), typeArgs, 0.As < JsNumber > ()).As <JsArray>(); var keyParts = new JsArray(); for (var i = 0; i < keyArray.length; i++) { keyParts[i] = keyArray[i].member(SpecialNames.TypeName); } var keyString = keyParts.join(", "); var lastIndexOfDollar = unconstructedType.TypeName.LastIndexOf('`'); if (lastIndexOfDollar == -1) { lastIndexOfDollar = unconstructedType.TypeName.Length; } var newTypeName = unconstructedType.TypeName.Substring(0, lastIndexOfDollar) + "<" + keyString + ">"; var prototype = unconstructedType.BaseType; if (prototype.member("$")) { var baseArgs = unconstructedType.BaseTypeArgs.slice(0); for (var i = 0; i < baseArgs.length; i++) { var baseArg = (JsTypeFunction)baseArgs[i]; if (baseArg.IsTypeParameter) { for (var j = 0; j < unconstructedType.TypeArgs.length; j++) { var typeArg = unconstructedType.TypeArgs[j]; if (typeArg == baseArg) { baseArgs[i] = typeArgs[j]; } } } } prototype = prototype.member("$").apply(null, baseArgs).As <JsTypeFunction>(); } var typeInitializer = Jsni.procedure((_t, p) => { var t = _t.As <JsTypeFunction>(); p.___type = t; t.As <JsTypeFunction>().BaseType = unconstructedType; t.As <JsTypeFunction>().GetTypeFromType = Jsni.function(() => Type._GetTypeFromTypeFunc(Jsni.@this().As <JsTypeFunction>()).As <JsObject>()); t.As <JsTypeFunction>().TypeName = newTypeName; t.As <JsTypeFunction>().CreateTypeField = Jsni.function(() => { var unconstructedTypeType = Type._GetTypeFromTypeFunc(unconstructedType); var type = new Type(newTypeName, new Attribute[0]); t.Type = type; type.thisType = t; var typeParameters = unconstructedTypeType.typeArguments; var typeArguments = InitializeArray(typeArgs, Jsni.type <JsTypeFunction>()).As <JsTypeFunction[]>(); Func <Type, JsTypeFunction> reifyGenerics = null; reifyGenerics = theType => { if (theType == null) { return(null); } if (theType.IsArray) { var elementType = theType.GetElementType(); var arrayType = MakeArrayType(reifyGenerics(elementType)); return(arrayType); } if (theType.IsGenericParameter) { for (int i = 0; i < typeArguments.Length; i++) { var typeParameter = typeParameters[i]; var typeArgument = typeArguments[i]; if (typeParameter.TypeName == theType.FullName) { return(typeArgument); } } } else if (theType.IsGenericTypeDefinition) { return(MakeGenericTypeFactory(theType.thisType, theType.GenericTypeArguments.Select(x => reifyGenerics(x)).ToArray().As <JsArray>())); } else if (theType.IsGenericType) { JsTypeFunction[] newTypeArguments = null; for (var i = 0; i < theType.typeArguments.Length; i++) { var theTypeArgument = theType.typeArguments[i]; for (var j = 0; j < typeParameters.Length; j++) { var typeParameter = typeParameters[j]; var typeArgument = typeArguments[j]; if (theTypeArgument == typeParameter) { if (newTypeArguments == null) { newTypeArguments = new JsTypeFunction[theType.typeArguments.Length]; for (var k = 0; k < theType.typeArguments.Length; k++) { newTypeArguments[k] = theType.typeArguments[k]; } } newTypeArguments[i] = typeArgument; } } } if (newTypeArguments != null) { return(MakeGenericTypeFactory(theType.unconstructedType, newTypeArguments.As <JsArray>())); } else { return(theType.thisType); } } return(theType.thisType); }; var newInterfaces = unconstructedTypeType.interfaces.ToArray(); for (var i = 0; i < newInterfaces.Length; i++) { var intf = newInterfaces[i]; intf = reifyGenerics(Type._GetTypeFromTypeFunc(intf)); newInterfaces[i] = intf; } var newConstructors = unconstructedTypeType.constructors.ToArray(); for (var i = 0; i < newConstructors.Length; i++) { var constructor = newConstructors[i]; var parameters = constructor.GetParameters(); for (var j = 0; j < parameters.Length; j++) { var parameter = parameters[j]; var parameterType = reifyGenerics(parameter.ParameterType); parameter = new ParameterInfo(parameter.Name, parameterType, j, parameter.Attributes, parameter.DefaultValue, parameter.attributes); parameters[j] = parameter; } newConstructors[i] = new ConstructorInfo(constructor.Name, t.prototype[constructor.Name].As <JsFunction>(), parameters, constructor.Attributes, constructor.attributes); } var newProperties = unconstructedTypeType.properties.ToArray(); for (var i = 0; i < newProperties.Length; i++) { var property = newProperties[i]; var propertyTypeType = property.PropertyType; var propertyType = reifyGenerics(propertyTypeType); newProperties[i] = new PropertyInfo(property.Name, propertyType, property.GetGetMethod(), property.GetSetMethod(), property.GetIndexParameters(), property.attributes); } var newMethods = unconstructedTypeType.methods.ToArray(); for (var i = 0; i < newMethods.Length; i++) { var method = newMethods[i]; var returnTypeType = method.ReturnType; var returnType = reifyGenerics(returnTypeType); var parameters = method.GetParameters(); for (var j = 0; j < parameters.Length; j++) { var parameter = parameters[j]; var parameterType = reifyGenerics(parameter.ParameterType); parameter = new ParameterInfo(parameter.Name, parameterType, j, parameter.Attributes, parameter.DefaultValue, parameter.attributes); parameters[j] = parameter; } method = new MethodInfo(method.Name, method.jsMethod, parameters, returnType, method.Attributes, method.attributes); newMethods[i] = method; } type.Init( newTypeName, (int)((unconstructedTypeType.typeFlags | TypeFlags.GenericType) & ~TypeFlags.GenericTypeDefenition), t, prototype, newInterfaces, typeArguments, unconstructedTypeType.fields, newMethods, newConstructors, newProperties, unconstructedTypeType.events, null, unconstructedType); return(type.As <JsObject>()); }); }, SpecialNames.TypeInitializerTypeFunction, SpecialNames.TypeInitializerPrototype); var generic = Define(unconstructedType.GetAssembly, unconstructedType.EnclosingType, newTypeName, true, Jsni.array(), prototype, typeInitializer); generic.memberset(SpecialNames.UnconstructedType, unconstructedType); // unconstructedType.$TypeInitializer.apply(this, [generic, generic.prototype].concat(Array.prototype.slice.call(arguments, 0))); unconstructedType.member(SpecialNames.TypeInitializer).apply( unconstructedType, Jsni.array(generic, generic.prototype).member("concat").invoke(keyArray).As <JsArray>() ); Jsni.call(generic.TypeInitializer, Jsni.@this(), generic, generic.prototype); result = generic; if (typeArgs.length == 0) { unconstructedType.memberset(SpecialNames.TypeCache, result); } else { cache[typeArgs[typeArgs.length - 1].member(SpecialNames.TypeName)] = result; } } return(result.As <JsTypeFunction>()); }