Example #1
0
 public TypeDefinition(Type clrType, string name, string declaration, CtorDefinition ctor = null)
 {
     ClrType     = clrType;
     Name        = name;
     Declaration = declaration;
     Ctor        = ctor;
     Members     = new List <MemberDefinition>();
     Methods     = new List <MethodDefinition>();
 }
Example #2
0
        private static TypeDefinition PopulateTypeDefinition(Type type, TypeScriptContext context)
        {
            if (type.IsGenericParameter)
            {
                return(null);
            }
            var typeCode = Type.GetTypeCode(type);

            if (typeCode != TypeCode.Object)
            {
                return(null);
            }
            if (SkipCheck(type.ToString(), context.Options))
            {
                return(null);
            }

            if (type.IsConstructedGenericType)
            {
                type.GetGenericArguments().ToList().ForEach(t => PopulateTypeDefinition(t, context));
                type = type.GetGenericTypeDefinition();
            }

            var existing = context.Types.FirstOrDefault(t => t.ClrType == type);

            if (existing != null)
            {
                return(existing);
            }

            var interfaceRefs = GetInterfaces(type, context);

            var useInterface = context.Options.UseInterfaceForClasses;
            var isInterface  = type.IsInterface || (useInterface != null && useInterface(type));
            var baseTypeRef  = string.Empty;

            if (type.IsClass)
            {
                if (type.BaseType != typeof(object) && PopulateTypeDefinition(type.BaseType, context) != null)
                {
                    baseTypeRef = GetTypeRef(type.BaseType, context);
                }
                else if (context.Options.DefaultBaseType != null)
                {
                    baseTypeRef = context.Options.DefaultBaseType(type);
                }
            }

            string declaration, typeName;

            if (!type.IsGenericType)
            {
                typeName = declaration = ApplyRename(type.Name, context);
            }
            else
            {
                var genericPrms = type.GetGenericArguments().Select(g => {
                    var constraints = g.GetGenericParameterConstraints()
                                      .Where(c => PopulateTypeDefinition(c, context) != null)
                                      .Select(c => GetTypeRef(c, context))
                                      .ToList();

                    if (g.IsClass &&
                        (useInterface == null || !useInterface(type)) &&
                        g.GenericParameterAttributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint))
                    {
                        constraints.Add($"{{ new(): {g.Name} }}");
                    }

                    if (constraints.Any())
                    {
                        return($"{g.Name} extends {string.Join(" & ", constraints)}");
                    }

                    return(g.Name);
                });

                typeName = ApplyRename(StripGenericFromName(type.Name), context);
                var genericPrmStr = string.Join(", ", genericPrms);
                declaration = $"{typeName}<{genericPrmStr}>";
            }

            CtorDefinition ctor = null;

            if (isInterface)
            {
                declaration = $"export interface {declaration}";

                if (!string.IsNullOrEmpty(baseTypeRef))
                {
                    interfaceRefs.Insert(0, baseTypeRef);
                }
            }
            else
            {
                var abs = type.IsAbstract ? " abstract" : string.Empty;
                declaration = $"export{abs} class {declaration}";

                if (!string.IsNullOrEmpty(baseTypeRef))
                {
                    declaration = $"{declaration} extends {baseTypeRef}";
                }

                var ctorGenerator = context.Options.CtorGenerator;
                if (ctorGenerator != null)
                {
                    ctor = ctorGenerator(type);
                }
            }

            if (interfaceRefs.Any())
            {
                var imp             = isInterface ? "extends" : "implements";
                var interfaceRefStr = string.Join(", ", interfaceRefs);
                declaration = $"{declaration} {imp} {interfaceRefStr}";
            }

            var typeDef = new TypeDefinition(type, typeName, declaration, ctor);

            context.Types.Add(typeDef);
            typeDef.Members.AddRange(GetMembers(type, context));
            typeDef.Methods.AddRange(GetMethods(type, context));

            return(typeDef);
        }