internal static Type GetCanonicalDotNetType(Type type) { var baseTypes = type.GetInterfaces().ToList(); if (type.BaseType != null) { baseTypes.Add(type.BaseType); } foreach (var baseType in baseTypes) { var attr = TypeUtils.GetCustomAttributesData(baseType).FirstOrDefault(a => a.AttributeType.Name == Constants.GenerateCanonicalDotNetTypeScriptTypeAttributeAttributeName); if (attr != null) { return(baseType); } var parentCanonical = GetCanonicalDotNetType(baseType); if (parentCanonical != null) { return(parentCanonical); } } return(null); }
internal static string GetTypescriptNamespace(Type type) { var parentToAugument = TypeBuilder.GetParentTypeToAugument(type); if (parentToAugument != null) { type = parentToAugument; } string DoGetTypescriptNamespace(object typeOrAssembly) { var customAttributes = typeOrAssembly is Type type?TypeUtils.GetCustomAttributesData(type) : TypeUtils.GetAssemblyCustomAttributesData((Assembly)typeOrAssembly); var attr = customAttributes.FirstOrDefault(a => a.AttributeType.Name == Constants.GenerateTypeScriptNamespaceAttributeName && a.ConstructorArguments.Count == 1 && a.ConstructorArguments[0].Value is string); return((string)attr?.ConstructorArguments[0].Value); } for (var currentType = type; currentType != null; currentType = currentType.DeclaringType) { var ns = DoGetTypescriptNamespace(currentType); if (ns != null) { return(ns); } } return(DoGetTypescriptNamespace(type.Assembly)); }
internal static bool ShouldGenerateDotNetTypeNamesAsJsDocComment(Type type) { bool DoShouldGenerateDotNetTypeNamesAsJsDocComment(object typeOrAssembly) { var customAttributes = typeOrAssembly is Type type?TypeUtils.GetCustomAttributesData(type) : TypeUtils.GetAssemblyCustomAttributesData((Assembly)typeOrAssembly); var attr = customAttributes.FirstOrDefault(a => a.AttributeType.Name == Constants.GenerateDotNetTypeNamesAsJsDocCommentAttributeName); return(attr != null); } if (DoShouldGenerateDotNetTypeNamesAsJsDocComment(type.Assembly)) { return(true); } for (var currentType = type; currentType != null; currentType = currentType.DeclaringType) { var shouldGenerate = DoShouldGenerateDotNetTypeNamesAsJsDocComment(currentType); if (shouldGenerate) { return(true); } } return(false); }
private static string GetTypeMemberName(Type type) { // No reason to create a type member on an abstract type since the purpose of the type member // is to identify a concrete type if (type.IsAbstract) { return(null); } var typeMemberName = (string)null; var currentType = type; while (currentType != null) { var attr = TypeUtils.GetCustomAttributesData(currentType).FirstOrDefault(a => a.AttributeType.Name == Constants.GenerateTypeScriptTypeMemberAttributeName); if (attr != null) { if (attr.ConstructorArguments[0].Value is string name) { typeMemberName = name; } else { typeMemberName = Constants.DefaultTypeMemberName; } break; } currentType = currentType.BaseType; } return(typeMemberName); }
private static TsInterfaceMember BuildMember(MemberInfo member, IList <Type> interfaces, TypeBuilderConfig config, string currentTsNamespace) { var interfaceProperties = interfaces.SelectMany(i => TypeUtils.GetRelevantAndBaseProperties(i).Where(p => p.Name == member.Name)); var allPropertiesToCheckForIgnore = new List <MemberInfo>(); allPropertiesToCheckForIgnore.Add(member); allPropertiesToCheckForIgnore.AddRange(interfaceProperties); var currentType = member.DeclaringType?.BaseType; while (currentType != null) { var baseProperties = TypeUtils.GetRelevantAndBaseProperties(currentType).Where(p => p.Name == member.Name); allPropertiesToCheckForIgnore.AddRange(baseProperties); currentType = currentType.BaseType; } foreach (var propertyToCheckForIgnore in allPropertiesToCheckForIgnore) { var attributes = TypeUtils.GetCustomAttributesData(propertyToCheckForIgnore); if (attributes.All(a => a.AttributeType.Name != Constants.TypeScriptTypeAttributeName)) { if (attributes.Any(a => a.AttributeType.FullName == "Newtonsoft.Json.JsonIgnoreAttribute")) { return(null); } if (attributes.Any(a => a.AttributeType.FullName == config.CustomTypeScriptIgnoreAttributeFullName)) { return(null); } if (attributes.Any(a => a.AttributeType.Name == Constants.TypeScriptIgnoreAttributeName)) { return(null); } } } string name = FindNameFromJsonPropertyAttribute(member); if (string.IsNullOrEmpty(name)) { name = StringUtils.ToCamelCase(member.Name); } var membersToCheckForOptional = new List <MemberInfo> { member }; membersToCheckForOptional.AddRange(member.DeclaringType.GetInterfaces().SelectMany(i => i.GetMember(member.Name)).Where(m => m != null)); var isOptional = membersToCheckForOptional.SelectMany(m => TypeUtils.GetCustomAttributesData(m)).FirstOrDefault(a => a.AttributeType.Name == Constants.TypeScriptOptionalAttributeName) != null; return(new TsInterfaceMember(name, BuildTsTypeReferenceToPropertyType(member, config, currentTsNamespace, isOptional), member, isOptional)); }
private static string GetDerivedTypesUnionName(Type type) { var attr = TypeUtils.GetCustomAttributesData(type).FirstOrDefault(a => a.AttributeType.Name == Constants.GenerateTypeScriptDerivedTypesUnionAttributeName); if (attr == null) { return(null); } return(attr.ConstructorArguments.Count > 0 && attr.ConstructorArguments[0].Value is string unionName ? unionName : (TypeUtils.GetNameWithoutGenericArity(type) + "Types")); }
private static string FindNameFromJsonPropertyAttribute(MemberInfo member) { string LookupSingle(MemberInfo m) { var jsonPropertyAttribute = TypeUtils.GetCustomAttributesData(m).FirstOrDefault(a => a.AttributeType.FullName == "Newtonsoft.Json.JsonPropertyAttribute"); if (jsonPropertyAttribute != null) { if (jsonPropertyAttribute.NamedArguments?.Any(x => x.MemberName == "PropertyName") == true) { return(jsonPropertyAttribute.NamedArguments.First(x => x.MemberName == "PropertyName").TypedValue.Value as string); } else if (jsonPropertyAttribute.ConstructorArguments.Count > 0) { return(jsonPropertyAttribute.ConstructorArguments[0].Value as string); } } return(null); } if (LookupSingle(member) is string result) { return(result); } foreach (var interfaceProperty in member.DeclaringType?.GetInterfaces().SelectMany(i => TypeUtils.GetRelevantAndBaseProperties(i).Where(p => p.Name == member.Name)) ?? new List <PropertyInfo>()) { if (LookupSingle(interfaceProperty) is string interfaceResult) { return(interfaceResult); } } var currentType = member.DeclaringType?.BaseType; while (currentType != null) { var baseProperties = TypeUtils.GetRelevantAndBaseProperties(currentType).Where(p => p.Name == member.Name); foreach (var baseProperty in baseProperties) { if (LookupSingle(baseProperty) is string baseResult) { return(baseResult); } } currentType = currentType.BaseType; } return(null); }
internal static Type GetParentTypeToAugument(Type type) { var attr = TypeUtils.GetCustomAttributesData(type).FirstOrDefault(a => a.AttributeType.Name == Constants.TypeScriptAugumentParentAttributeName); if (attr != null) { var baseTypes = type.GetInterfaces().ToList(); if (type.BaseType != null && !TypeUtils.Is <object>(type.BaseType)) { baseTypes.Insert(0, type.BaseType); } return(baseTypes.FirstOrDefault()); } return(null); }
private bool ShouldTypeBeGenerated(Type type) { while (type != null) { var customAttributes = TypeUtils.GetCustomAttributesData(type); var gtsda = customAttributes.FirstOrDefault(a => a.AttributeType.Name == Constants.GenerateTypeScriptDefinitionAttributeName); if (gtsda != null) { return(gtsda.ConstructorArguments.Count == 0 || !(gtsda.ConstructorArguments[0].Value is bool value) || value); } if (customAttributes.Any(a => a.AttributeType.Name == Constants.GenerateTypeScriptDefinitionAttributeName) || customAttributes.Any(a => a.AttributeType.Name == Constants.GenerateTypeScriptNamespaceAttributeName)) { return(true); } type = type.DeclaringType; } return(false); }
private static CustomAttributeData GetTypeScriptTypeAttribute(List <CustomAttributeData> attributes) { var explicitTypeAttribute = attributes.FirstOrDefault(a => a.AttributeType?.Name == Constants.TypeScriptTypeAttributeName && a.ConstructorArguments.Count == 1); if (explicitTypeAttribute != null) { return(explicitTypeAttribute); } foreach (var attribute in attributes) { var attributeAttributes = TypeUtils.GetCustomAttributesData(attribute.AttributeType); var attributeAttribute = attributeAttributes.FirstOrDefault(a => a.AttributeType?.Name == Constants.TypeScriptTypeAttributeName && a.ConstructorArguments.Count == 1); if (attributeAttribute != null) { return(attributeAttribute); } } return(null); }
private static CustomAttributeData GetTypeScriptTypeAttribute(Type type) { return(GetTypeScriptTypeAttribute(TypeUtils.GetCustomAttributesData(type))); }
private static CustomAttributeData GetTypeScriptTypeAttribute(MemberInfo member) { return(GetTypeScriptTypeAttribute(TypeUtils.GetCustomAttributesData(member))); }
public override string GetSource(string outputFilePath, Config config, GeneratorContext generatorContext) { var indent = " "; var result = new StringBuilder(); var name = Name; if (_parentToAugument != null) { name = _parentToAugument.Name; } var typeScriptClassComment = generatorContext.GetTypeScriptComment(_type); if (typeScriptClassComment == null) { var interfaces = _type.GetInterfaces(); foreach (var iface in interfaces) { typeScriptClassComment = generatorContext.GetTypeScriptComment(iface); if (typeScriptClassComment != null) { break; } } } if (TypeBuilder.ShouldGenerateDotNetTypeNamesAsJsDocComment(_type)) { var dotNetTypeAttr = TypeUtils.GetCustomAttributesData(_type).FirstOrDefault(a => a.AttributeType.Name == Constants.GenerateTypeScriptDotNetNameAttributeName && a.ConstructorArguments.Count == 1 ); var type = _type; if (dotNetTypeAttr?.ConstructorArguments[0].Value is Type t) { type = t; } var canonicalType = TypeBuilder.GetCanonicalDotNetType(type); var dotNetTypeComment = $"@DotNetTypeName {TypeUtils.GetFullName(type)},{type.Assembly.GetName().Name}"; result.Append($"{indent}/**"); if (typeScriptClassComment != null) { result.Append(config.NewLine); result.Append(FormatTypeScriptComment(typeScriptClassComment, indent, config.NewLine)); result.Append(config.NewLine); result.Append($"{indent} *"); result.Append(config.NewLine); } if (canonicalType != null) { result.Append(config.NewLine); result.Append($"{indent} * {dotNetTypeComment}"); result.Append(config.NewLine); result.Append($"{indent} * @DotNetCanonicalTypeName {TypeUtils.GetFullName(canonicalType)},{canonicalType.Assembly.GetName().Name}"); result.Append(config.NewLine); result.Append($"{indent} */"); } else { result.Append($" {dotNetTypeComment} */"); } result.Append(config.NewLine); } else { if (typeScriptClassComment != null) { result.Append($"{indent}/**"); result.Append(config.NewLine); result.Append(FormatTypeScriptComment(typeScriptClassComment, indent, config.NewLine)); result.Append(config.NewLine); result.Append($"{indent} */"); result.Append(config.NewLine); } } result.Append($"{indent}interface {name}"); if (_typeParameters.Length > 0) { result.Append("<") .Append(string.Join(", ", _typeParameters)) .Append(">"); } if (_extends.Length > 0) { var extends = _parentToAugument != null?_extends.Where(e => !e.Equals(_parentToAugument)).ToList() : _extends.ToList(); if (extends.Any()) { result.Append(" extends ").Append(extends[0].GetSource()); for (int i = 1; i < extends.Count; i++) { result.Append(", ").Append(extends[i].GetSource()); } } } result.Append(" {"); result.Append(config.NewLine); if (_typeMemberName != null) { // TODO: Should the value here be configurable? Perhaps you want the FQN? result.Append($"{indent} {_typeMemberName}: '{name}';"); result.Append(config.NewLine); } var memberTypeWrapper = TypeBuilder.GetWrapperTypeForMembers(_type, config); foreach (var m in _members) { var optional = ""; if (m.IsOptional || m.Type.IsOptional) { if (m.IsOptional || m.Type.IsOptional) { optional = "?"; } } var typeScriptMemberComment = generatorContext.GetTypeScriptComment(m.MemberInfo); if (typeScriptMemberComment == null) { var interfaceMembers = m.MemberInfo.DeclaringType.GetInterfaces().SelectMany(i => i.GetMember(m.MemberInfo.Name)).Where(m => m != null).ToList(); foreach (var interfaceMember in interfaceMembers) { typeScriptMemberComment = generatorContext.GetTypeScriptComment(interfaceMember); if (typeScriptMemberComment != null) { break; } } } if (typeScriptMemberComment != null) { result.Append($"{indent} /**"); result.Append(config.NewLine); result.Append(FormatTypeScriptComment(typeScriptMemberComment, indent + " ", config.NewLine)); result.Append(config.NewLine); result.Append($"{indent} */"); result.Append(config.NewLine); } result.Append($"{indent} {FixName(m.Name)}{optional}: {WrapType(m.Type.GetSource(), memberTypeWrapper)};"); result.Append(config.NewLine); } result.Append(indent).Append("}"); result.Append(config.NewLine); if (_derivedTypesUnionGeneration?.DerivedTypeReferences.Length > 0) { result.Append(config.NewLine); result.Append($"{indent}type {_derivedTypesUnionGeneration.DerivedTypesUnionName} ={config.NewLine}{indent} | {string.Join($"{config.NewLine}{indent} | ", _derivedTypesUnionGeneration.DerivedTypeReferences.Select(t => t.GetSource()))};"); result.Append(config.NewLine); } return(result.ToString()); }