/// <summary> /// Adds all classes annotated with the TsClassAttribute from an assembly to the model. /// </summary> /// <param name="assembly">The assembly with classes to add</param> public void Add(Assembly assembly) { try { foreach (var type in assembly.GetTypes().Where(t => (t.GetCustomAttribute <TsClassAttribute>(false) != null && TsType.GetTypeFamily(t) == TsTypeFamily.Class) || (t.GetCustomAttribute <TsEnumAttribute>(false) != null && TsType.GetTypeFamily(t) == TsTypeFamily.Enum) || (t.GetCustomAttribute <TsInterfaceAttribute>(false) != null && TsType.GetTypeFamily(t) == TsTypeFamily.Class) )) { Add(type); } } catch (ReflectionTypeLoadException e) { var availableTypes = e.Types.Where(t => t != null && t.GetCustomAttribute <TsClassAttribute>(false) != null && TsType.GetTypeFamily(t) == TsTypeFamily.Class || t.GetCustomAttribute <TsEnumAttribute>(false) != null && TsType.GetTypeFamily(t) == TsTypeFamily.Enum || t.GetCustomAttribute <TsInterfaceAttribute>(false) != null && TsType.GetTypeFamily(t) == TsTypeFamily.Class); foreach (var type in availableTypes) { Add(type); } } }
/// <summary> /// Resolves TsType to the more specialized type. /// </summary> /// <param name="toResolve">The type to resolve.</param> /// <returns></returns> private TsType ResolveType(TsType toResolve, TsPropertyVisibilityFormatter propertyVisibilityFormatter, bool useOpenGenericDefinition = true) { if (!(toResolve is TsType)) { return(toResolve); } if (_knownTypes.ContainsKey(toResolve.Type)) { return(_knownTypes[toResolve.Type]); } else if (toResolve.Type.IsGenericType && useOpenGenericDefinition) { // We stored its open type definition instead TsType openType = null; if (_knownTypes.TryGetValue(toResolve.Type.GetGenericTypeDefinition(), out openType)) { return(openType); } } else if (toResolve.Type.IsGenericType) { var genericType = TsType.Create(toResolve.Type, propertyVisibilityFormatter); _knownTypes[toResolve.Type] = genericType; return(genericType); } var typeFamily = TsType.GetTypeFamily(toResolve.Type); TsType type = null; switch (typeFamily) { case TsTypeFamily.System: type = new TsSystemType(toResolve.Type); break; case TsTypeFamily.Collection: type = this.CreateCollectionType(toResolve, propertyVisibilityFormatter); break; case TsTypeFamily.Enum: type = new TsEnum(toResolve.Type); break; default: type = TsType.Any; break; } _knownTypes[toResolve.Type] = type; return(type); }
/// <summary> /// Adds all classes annotated with the TsClassAttribute from an assembly to the model. /// </summary> /// <param name="assembly">The assembly with classes to add</param> public void Add(Assembly assembly) { foreach (var type in assembly.GetTypes().Where(t => (t.GetCustomAttribute <TsClassAttribute>(false) != null && TsType.GetTypeFamily(t) == TsTypeFamily.Class) || (t.GetCustomAttribute <TsEnumAttribute>(false) != null && TsType.GetTypeFamily(t) == TsTypeFamily.Enum) || (t.GetCustomAttribute <TsInterfaceAttribute>(false) != null && TsType.GetTypeFamily(t) == TsTypeFamily.Class) )) { this.Add(type); } }
public void WhenGetTypeFamilyForObject_TypeIsReturned() { var family = TsType.GetTypeFamily(typeof(object)); Assert.Equal(TsTypeFamily.Type, family); }
public void WhenGetTypeFamilyForIEnumerable_ClassIsReturned() { var family = TsType.GetTypeFamily(typeof(List <int>)); Assert.Equal(TsTypeFamily.Collection, family); }
public void WhenGetTypeFamilyForEnum_EnumIsReturned() { var family = TsType.GetTypeFamily(typeof(CustomerKind)); Assert.Equal(TsTypeFamily.Enum, family); }
public void WhenGetTypeFamilyForClass_ClassIsReturned() { var family = TsType.GetTypeFamily(typeof(Address)); Assert.Equal(TsTypeFamily.Class, family); }
private static void ProcessTypes(IEnumerable <Type> types, TypeScriptFluent generator) { foreach (var clrType in types.Where(t => t != typeof(void))) { if (generator.ModelBuilder.ContainsType(clrType)) { continue; } var clrTypeToUse = clrType; if (typeof(Task).GetDnxCompatible().IsAssignableFrom(clrTypeToUse)) { if (clrTypeToUse.GetDnxCompatible().IsGenericType) { clrTypeToUse = clrTypeToUse.GetDnxCompatible().GetGenericArguments()[0]; } else { continue; // Ignore non-generic Task as we can't know what type it will really be } } if (clrTypeToUse.IsNullable()) { clrTypeToUse = clrTypeToUse.GetUnderlyingNullableType(); } // Ignore compiler generated types if (clrTypeToUse.GetDnxCompatible().GetCustomAttribute(typeof(CompilerGeneratedAttribute)) != null) { continue; } // No need to add types which TypeLite considers built-in if (TsType.GetTypeFamily(clrTypeToUse) == TsTypeFamily.System) { continue; } // Skip all other System types unless a custom converter is registered for it if (clrTypeToUse.Namespace.StartsWith("System")) { if (!generator.IsTypeConvertorRegistered(clrTypeToUse)) { continue; } } if (clrTypeToUse.IsIDictionary()) { continue; } if (clrTypeToUse == typeof(string) || clrTypeToUse.GetDnxCompatible().IsPrimitive || clrTypeToUse == typeof(object)) { continue; } bool isClassOrArray = clrTypeToUse.GetDnxCompatible().IsClass || clrTypeToUse.GetDnxCompatible().IsInterface; TsModuleMember member = null; if (clrTypeToUse.IsArray) { ProcessTypes(new[] { clrTypeToUse.GetElementType() }, generator); } else if (clrTypeToUse.GetDnxCompatible().IsGenericType) { ProcessTypes(clrTypeToUse.GetDnxCompatible().GetGenericArguments(), generator); bool isEnumerable = typeof(IEnumerable).GetDnxCompatible().IsAssignableFrom(clrTypeToUse); if (!isEnumerable) { member = generator.ModelBuilder.Add(clrTypeToUse, !isClassOrArray); } } else { member = generator.ModelBuilder.Add(clrTypeToUse, !isClassOrArray); } var classModel = member as TsClass; if (isClassOrArray && classModel != null) { var references = classModel.Properties .Where(model => !model.IsIgnored) .Select(m => m.PropertyType) .Concat(classModel.GenericArguments) .Select(m => m.Type) .Where(t => !t.IsIDictionary()) .ToArray(); ProcessTypes(references, generator); } } }
public void WhenGetTypeFamilyForDateTime_SystemIsReturned() { var family = TsType.GetTypeFamily(typeof(DateTime)); Assert.Equal(TsTypeFamily.System, family); }
public void WhenGetTypeFamilyForString_SystemIsReturned() { var family = TsType.GetTypeFamily(typeof(string)); Assert.Equal(TsTypeFamily.System, family); }
public void WhenGetTypeFamilyForNullableStruct_ClassIsReturned() { var family = TsType.GetTypeFamily(typeof(PointStruct?)); Assert.Equal(TsTypeFamily.Class, family); }
public void WhenGetTypeFamilyForNullableSystemType_SystemTypeIsReturned() { var family = TsType.GetTypeFamily(typeof(int?)); Assert.Equal(TsTypeFamily.System, family); }
/// <summary> /// Adds classes referenced by the class to the model /// </summary> /// <param name="classModel"></param> private void AddReferences(TsClass classModel) { foreach (var property in classModel.Properties.Where(model => !model.IsIgnored)) { var propertyTypeFamily = TsType.GetTypeFamily(property.PropertyType.Type); if (propertyTypeFamily == TsTypeFamily.Collection) { var collectionItemType = TsType.GetEnumerableType(property.PropertyType.Type); while (collectionItemType != null) { var typeFamily = TsType.GetTypeFamily(collectionItemType); switch (typeFamily) { case TsTypeFamily.Class: this.Add(collectionItemType); collectionItemType = null; break; case TsTypeFamily.Enum: this.AddEnum(new TsEnum(collectionItemType)); collectionItemType = null; break; case TsTypeFamily.Collection: collectionItemType = TsType.GetEnumerableType(collectionItemType); break; default: collectionItemType = null; break; } } } else if (propertyTypeFamily == TsTypeFamily.Class) { this.Add(property.PropertyType.Type); } } foreach (var genericArgument in classModel.GenericArguments) { var propertyTypeFamily = TsType.GetTypeFamily(genericArgument.Type); if (propertyTypeFamily == TsTypeFamily.Collection) { var collectionItemType = TsType.GetEnumerableType(genericArgument.Type); if (collectionItemType != null) { var typeFamily = TsType.GetTypeFamily(collectionItemType); switch (typeFamily) { case TsTypeFamily.Class: this.Add(collectionItemType); break; case TsTypeFamily.Enum: this.AddEnum(new TsEnum(collectionItemType)); break; } } } else if (propertyTypeFamily == TsTypeFamily.Class) { this.Add(genericArgument.Type); } } }
/// <summary> /// Adds all classes annotated with the TsClassAttribute from an assembly to the model. /// </summary> /// <param name="assembly">The assembly with classes to add.</param> /// <returns>Instance of the <see cref="DefinitionOptionsBuilder"/> that enables fluent configuration.</returns> public DefinitionOptionsBuilder For(Assembly assembly) { foreach (var type in assembly.GetTypes().Where(t => (t.GetTypeInfo().GetCustomAttribute <TsClassAttribute>(false) != null && TsType.GetTypeFamily(t) == TsTypeFamily.Class) || (t.GetTypeInfo().GetCustomAttribute <TsEnumAttribute>(false) != null && TsType.GetTypeFamily(t) == TsTypeFamily.Enum) || (t.GetTypeInfo().GetCustomAttribute <TsInterfaceAttribute>(false) != null && TsType.GetTypeFamily(t) == TsTypeFamily.Class) )) { For(type); } return(this); }
/// <summary> /// Adds classes referenced by the class to the model /// </summary> /// <param name="classModel"></param> private void AddReferences(TsClass classModel, Dictionary <Type, TypeConvertor> typeConvertors) { foreach (var property in classModel.Properties.Where(model => !model.IsIgnored)) { var propertyTypeFamily = TsType.GetTypeFamily(property.PropertyType.Type); if (propertyTypeFamily == TsTypeFamily.Collection) { var collectionItemType = TsType.GetEnumerableType(property.PropertyType.Type); while (collectionItemType != null) { var typeFamily = TsType.GetTypeFamily(collectionItemType); switch (typeFamily) { case TsTypeFamily.Class: this.Add(collectionItemType); collectionItemType = null; break; case TsTypeFamily.Enum: this.AddEnum(new TsEnum(collectionItemType)); collectionItemType = null; break; case TsTypeFamily.Collection: var previousCollectionItemType = collectionItemType; collectionItemType = TsType.GetEnumerableType(collectionItemType); if (collectionItemType == previousCollectionItemType) { collectionItemType = null; } break; default: collectionItemType = null; break; } } } else if (propertyTypeFamily == TsTypeFamily.Class) { if (typeConvertors == null || !typeConvertors.ContainsKey(property.PropertyType.Type)) { this.Add(property.PropertyType.Type); } else { this.Add(property.PropertyType.Type, false, typeConvertors); } } } foreach (var genericArgument in classModel.GenericArguments) { var propertyTypeFamily = TsType.GetTypeFamily(genericArgument.Type); if (propertyTypeFamily == TsTypeFamily.Collection) { var collectionItemType = TsType.GetEnumerableType(genericArgument.Type); if (collectionItemType != null) { var typeFamily = TsType.GetTypeFamily(collectionItemType); switch (typeFamily) { case TsTypeFamily.Class: this.Add(collectionItemType); break; case TsTypeFamily.Enum: this.AddEnum(new TsEnum(collectionItemType)); break; } } } else if (propertyTypeFamily == TsTypeFamily.Class) { this.Add(genericArgument.Type); } } }
/// <summary> /// Adds type and optionally referenced classes to the model. /// </summary> /// <param name="clrType">The type to add to the model.</param> /// <param name="includeReferences">bool value indicating whether classes referenced by T should be added to the model.</param> /// <returns>type added to the model</returns> public TsModuleMember Add(Type clrType, bool includeReferences, Dictionary <Type, TypeConvertor> typeConvertors = null) { var typeFamily = TsType.GetTypeFamily(clrType); if (typeFamily != TsTypeFamily.Class && typeFamily != TsTypeFamily.Enum) { throw new ArgumentException(string.Format("Type '{0}' isn't class or struct. Only classes and structures can be added to the model", clrType.FullName)); } if (clrType.IsNullable()) { return(this.Add(clrType.GetNullableValueType(), includeReferences, typeConvertors)); } if (typeFamily == TsTypeFamily.Enum) { var enumType = new TsEnum(clrType); this.AddEnum(enumType); return(enumType); } if (clrType.IsGenericType) { if (!this.Classes.ContainsKey(clrType)) { var openGenericType = clrType.GetGenericTypeDefinition(); var added = new TsClass(openGenericType); this.Classes[openGenericType] = added; if (includeReferences) { this.AddReferences(added, typeConvertors); foreach (var e in added.Properties.Where(p => p.PropertyType.Type.IsEnum)) { this.AddEnum(e.PropertyType as TsEnum); } } } } if (!this.Classes.ContainsKey(clrType)) { var added = new TsClass(clrType); this.Classes[clrType] = added; if (clrType.IsGenericParameter) { added.IsIgnored = true; } if (clrType.IsGenericType) { added.IsIgnored = true; } if (added.BaseType != null) { this.Add(added.BaseType.Type); } if (includeReferences) { this.AddReferences(added, typeConvertors); foreach (var e in added.Properties.Where(p => p.PropertyType.Type.IsEnum)) { this.AddEnum(e.PropertyType as TsEnum); } } foreach (var @interface in added.Interfaces) { this.Add(@interface.Type); } return(added); } else { return(this.Classes[clrType]); } }
public void WhenGetTypeFamilyForDecimal_SystemIsReturned() { var family = TsType.GetTypeFamily(typeof(decimal)); Assert.Equal(TsTypeFamily.System, family); }