public JsExpressionStatement StoreClassCreateType(INamedTypeSymbol type) { var explicitName = type.GetAttributeValue<string>(Context.Instance.JsAttributeType, "Name"); var fullTypeName = type.GetFullName(); var baseType = type.BaseType != null ? Type(type.BaseType, true) : Js.Null(); var body = new JsBlockStatement(); body.Assign(Js.This().Member(SpecialNames.TypeField), CreateObject(Context.Instance.TypeConstructor, Js.Primitive(type.Name), CreateAttributes(type))); TypeFlags typeFlags = 0; if (type.ContainingType == null) { switch (type.DeclaredAccessibility) { case Accessibility.Public: typeFlags |= TypeFlags.Public; break; case Accessibility.Internal: typeFlags |= TypeFlags.Internal; break; default: throw new Exception(); } } else { switch (type.DeclaredAccessibility) { case Accessibility.Public: typeFlags |= TypeFlags.Public; break; case Accessibility.Internal: typeFlags |= TypeFlags.Internal; break; case Accessibility.Private: typeFlags |= TypeFlags.Private; break; case Accessibility.Protected: typeFlags |= TypeFlags.Protected; break; case Accessibility.ProtectedOrInternal: typeFlags |= TypeFlags.Private | TypeFlags.Internal; break; default: throw new Exception(); } } if (type.TypeKind == TypeKind.Interface) { typeFlags |= TypeFlags.Interface; } else if (type.TypeKind == TypeKind.Class) { typeFlags |= TypeFlags.Class; } else if (type.TypeKind == TypeKind.Enum) { typeFlags |= TypeFlags.Enum; } if (type.IsAbstract) { typeFlags |= TypeFlags.Abstract; } else if (type.IsSealed) { typeFlags |= TypeFlags.Sealed; } if (type.IsValueType) { typeFlags |= TypeFlags.ValueType; } if (type.IsPrimitive()) { typeFlags |= TypeFlags.Primitive; } if (type.IsGenericType || type.IsAnonymousTypeWithTypeParameters()) { typeFlags |= TypeFlags.GenericType; } if (type.TypeParameters.Any()) { typeFlags |= TypeFlags.GenericTypeDefenition; } if (type.TypeKind == TypeKind.TypeParameter) { typeFlags |= TypeFlags.GenericParameter; } var arguments = new List<JsExpression> { Js.Primitive(explicitName ?? fullTypeName), // Param1: fullTypeName Js.Primitive((int)typeFlags), Type(type, true), baseType, CreateInterfaceReferences(type), MakeArray(Js.Array(type.TypeParameters.Select(x => Js.Reference(x.Name)).Concat(type.GetAnonymousTypeParameters().Select(x => Js.Reference(x.Item2))).ToArray()), Context.Instance.TypeArray) }; if (!Context.Instance.Compilation.Assembly.IsReflectionMinimized()) { arguments.AddRange(new[] { CreateFieldInfos(type), CreateMethodInfos(type, false), CreateMethodInfos(type, true), CreatePropertyInfos(type), CreateEventInfos(type) }); } body.Express(Invoke(Js.This().Member(SpecialNames.TypeField), Context.Instance.TypeInit, arguments.ToArray())); body.Return(Js.This().Member(SpecialNames.TypeField)); var result = StoreInType(SpecialNames.CreateType, Js.Function().Body(body).Compact()); return result; }