public void AddProperties(StringBuilderWrapper sb, MetadataType type, bool includeResponseStatus) { var makeExtensible = Config.MakeDataContractsExtensible && type.Inherits == null; var wasAdded = false; var dataMemberIndex = 1; if (type.Properties != null) { foreach (var prop in type.Properties) { if (wasAdded) sb.AppendLine(); var propType = Type(prop.Type, prop.GenericArgs); wasAdded = AppendComments(sb, prop.Description); wasAdded = AppendDataMember(sb, prop.DataMember, dataMemberIndex++) || wasAdded; wasAdded = AppendAttributes(sb, prop.Attributes) || wasAdded; if (!type.IsInterface()) { sb.AppendLine("member val {1}:{0} = {2} with get,set".Fmt( propType, prop.Name.SafeToken(), GetDefaultLiteral(prop, type))); } else { sb.AppendLine("abstract {1}:{0} with get,set".Fmt( propType, prop.Name.SafeToken())); } } } if (type.IsInterface()) return; if (includeResponseStatus) { if (wasAdded) sb.AppendLine(); wasAdded = true; AppendDataMember(sb, null, dataMemberIndex++); sb.AppendLine("member val ResponseStatus:ResponseStatus = null with get,set"); } if (makeExtensible && (type.Properties == null || type.Properties.All(x => x.Name != "ExtensionData"))) { if (wasAdded) sb.AppendLine(); wasAdded = true; sb.AppendLine("member val ExtensionData:ExtensionDataObject = null with get,set"); } }
public void AddProperties(StringBuilderWrapper sb, MetadataType type, bool includeResponseStatus) { var makeExtensible = Config.MakeDataContractsExtensible && type.Inherits == null; var @virtual = Config.MakeVirtual && !type.IsInterface() ? "Overridable " : ""; var wasAdded = false; var dataMemberIndex = 1; if (type.Properties != null) { foreach (var prop in type.Properties) { if (wasAdded) sb.AppendLine(); var propType = Type(prop.Type, prop.GenericArgs, includeNested:true); wasAdded = AppendComments(sb, prop.Description); wasAdded = AppendDataMember(sb, prop.DataMember, dataMemberIndex++) || wasAdded; wasAdded = AppendAttributes(sb, prop.Attributes) || wasAdded; var visibility = type.IsInterface() ? "" : "Public "; sb.AppendLine("{0}{1}Property {2} As {3}".Fmt( visibility, @virtual, EscapeKeyword(prop.Name).SafeToken(), propType)); } } if (type.IsInterface()) return; if (includeResponseStatus) { if (wasAdded) sb.AppendLine(); wasAdded = true; wasAdded = AppendDataMember(sb, null, dataMemberIndex++); sb.AppendLine("Public {0}Property ResponseStatus As ResponseStatus".Fmt(@virtual)); } if (makeExtensible && (type.Properties == null || type.Properties.All(x => x.Name != "ExtensionData"))) { if (wasAdded) sb.AppendLine(); wasAdded = true; sb.AppendLine("Public {0}Property ExtensionData As ExtensionDataObject Implements IExtensibleDataObject.ExtensionData".Fmt(@virtual)); } }
public void AddProperties(StringBuilderWrapper sb, MetadataType type) { var makeExtensible = Config.MakeDataContractsExtensible && type.Inherits == null; var @virtual = Config.MakeVirtual ? "virtual " : ""; var wasAdded = false; var dataMemberIndex = 1; if (type.Properties != null) { foreach (var prop in type.Properties) { if (wasAdded) sb.AppendLine(); var propType = Type(prop.Type, prop.GenericArgs); wasAdded = AppendDataMember(sb, prop.DataMember, dataMemberIndex++); wasAdded = AppendAttributes(sb, prop.Attributes) || wasAdded; sb.AppendLine("public {0}{1} {2} {{ get; set; }}".Fmt(@virtual, propType, prop.Name.SafeToken())); } } if (Config.AddResponseStatus && (type.Properties == null || type.Properties.All(x => x.Name != "ResponseStatus"))) { if (wasAdded) sb.AppendLine(); wasAdded = true; AppendDataMember(sb, null, dataMemberIndex++); sb.AppendLine("public {0}ResponseStatus ResponseStatus {{ get; set; }}".Fmt(@virtual)); } if (makeExtensible && (type.Properties == null || type.Properties.All(x => x.Name != "ExtensionData"))) { if (wasAdded) sb.AppendLine(); wasAdded = true; sb.AppendLine("public {0}ExtensionDataObject ExtensionData {{ get; set; }}".Fmt(@virtual)); } }
public string GetCode(MetadataTypes metadata, IRequest request, INativeTypesMetadata nativeTypes) { var typeNamespaces = new HashSet<string>(); RemoveIgnoredTypes(metadata); metadata.Types.Each(x => typeNamespaces.Add(x.Namespace)); metadata.Operations.Each(x => typeNamespaces.Add(x.Request.Namespace)); var defaultImports = new List<string>(DefaultImports); if (!Config.DefaultImports.IsEmpty()) { defaultImports = Config.DefaultImports; } else if (ReferencesGson(metadata)) { if (!defaultImports.Contains(GSonAnnotationsNamespace)) defaultImports.Add(GSonAnnotationsNamespace); if (!defaultImports.Contains(GSonReflectNamespace)) defaultImports.Add(GSonReflectNamespace); } var defaultNamespace = Config.GlobalNamespace ?? DefaultGlobalNamespace; Func<string, string> defaultValue = k => request.QueryString[k].IsNullOrEmpty() ? "//" : ""; var sbInner = StringBuilderCache.Allocate(); var sb = new StringBuilderWrapper(sbInner); sb.AppendLine("/* Options:"); sb.AppendLine("Date: {0}".Fmt(DateTime.Now.ToString("s").Replace("T", " "))); sb.AppendLine("Version: {0}".Fmt(Env.ServiceStackVersion)); sb.AppendLine("Tip: {0}".Fmt(HelpMessages.NativeTypesDtoOptionsTip.Fmt("//"))); sb.AppendLine("BaseUrl: {0}".Fmt(Config.BaseUrl)); sb.AppendLine(); sb.AppendLine("{0}Package: {1}".Fmt(defaultValue("Package"), Config.Package)); sb.AppendLine("{0}GlobalNamespace: {1}".Fmt(defaultValue("GlobalNamespace"), defaultNamespace)); sb.AppendLine("{0}AddPropertyAccessors: {1}".Fmt(defaultValue("AddPropertyAccessors"), Config.AddPropertyAccessors)); sb.AppendLine("{0}SettersReturnThis: {1}".Fmt(defaultValue("SettersReturnThis"), Config.SettersReturnThis)); sb.AppendLine("{0}AddServiceStackTypes: {1}".Fmt(defaultValue("AddServiceStackTypes"), Config.AddServiceStackTypes)); sb.AppendLine("{0}AddResponseStatus: {1}".Fmt(defaultValue("AddResponseStatus"), Config.AddResponseStatus)); sb.AppendLine("{0}AddDescriptionAsComments: {1}".Fmt(defaultValue("AddDescriptionAsComments"), Config.AddDescriptionAsComments)); sb.AppendLine("{0}AddImplicitVersion: {1}".Fmt(defaultValue("AddImplicitVersion"), Config.AddImplicitVersion)); sb.AppendLine("{0}IncludeTypes: {1}".Fmt(defaultValue("IncludeTypes"), Config.IncludeTypes.Safe().ToArray().Join(","))); sb.AppendLine("{0}ExcludeTypes: {1}".Fmt(defaultValue("ExcludeTypes"), Config.ExcludeTypes.Safe().ToArray().Join(","))); sb.AppendLine("{0}TreatTypesAsStrings: {1}".Fmt(defaultValue("TreatTypesAsStrings"), Config.TreatTypesAsStrings.Safe().ToArray().Join(","))); sb.AppendLine("{0}DefaultImports: {1}".Fmt(defaultValue("DefaultImports"), defaultImports.Join(","))); sb.AppendLine("*/"); sb.AppendLine(); foreach (var typeName in Config.TreatTypesAsStrings.Safe()) { TypeAliases[typeName] = "String"; } if (Config.Package != null) { sb.AppendLine("package {0};".Fmt(Config.Package)); sb.AppendLine(); } string lastNS = null; var existingTypes = new HashSet<string>(); var requestTypes = metadata.Operations.Select(x => x.Request).ToHashSet(); var requestTypesMap = metadata.Operations.ToSafeDictionary(x => x.Request); var responseTypes = metadata.Operations .Where(x => x.Response != null) .Select(x => x.Response).ToHashSet(); var types = metadata.Types.ToHashSet(); AllTypes.AddRange(requestTypes); AllTypes.AddRange(responseTypes); AllTypes.AddRange(types); //TypeScript doesn't support reusing same type name with different generic airity var conflictPartialNames = AllTypes.Map(x => x.Name).Distinct() .GroupBy(g => g.LeftPart('`')) .Where(g => g.Count() > 1) .Select(g => g.Key) .ToList(); this.conflictTypeNames = AllTypes .Where(x => conflictPartialNames.Any(name => x.Name.StartsWith(name))) .Map(x => x.Name); defaultImports.Each(x => sb.AppendLine("import {0};".Fmt(x))); sb.AppendLine(); sb.AppendLine("public class {0}".Fmt(defaultNamespace.SafeToken())); sb.AppendLine("{"); //ServiceStack core interfaces foreach (var type in AllTypes) { var fullTypeName = type.GetFullName(); if (requestTypes.Contains(type)) { if (!existingTypes.Contains(fullTypeName)) { MetadataType response = null; MetadataOperationType operation; if (requestTypesMap.TryGetValue(type, out operation)) { response = operation.Response; } lastNS = AppendType(ref sb, type, lastNS, new CreateTypeOptions { ImplementsFn = () => { if (!Config.AddReturnMarker && !type.ReturnVoidMarker && type.ReturnMarkerTypeName == null) return null; if (type.ReturnVoidMarker) return "IReturnVoid"; if (type.ReturnMarkerTypeName != null) return Type("IReturn`1", new[] { Type(type.ReturnMarkerTypeName) }); return response != null ? Type("IReturn`1", new[] { Type(response.Name, response.GenericArgs) }) : null; }, IsRequest = true, }); existingTypes.Add(fullTypeName); } } else if (responseTypes.Contains(type)) { if (!existingTypes.Contains(fullTypeName) && !Config.IgnoreTypesInNamespaces.Contains(type.Namespace)) { lastNS = AppendType(ref sb, type, lastNS, new CreateTypeOptions { IsResponse = true, }); existingTypes.Add(fullTypeName); } } else if (types.Contains(type) && !existingTypes.Contains(fullTypeName)) { lastNS = AppendType(ref sb, type, lastNS, new CreateTypeOptions { IsType = true }); existingTypes.Add(fullTypeName); } } sb.AppendLine(); sb.AppendLine("}"); return StringBuilderCache.ReturnAndFree(sbInner); }
public void AppendDataContract(StringBuilderWrapper sb, MetadataDataContract dcMeta) { if (dcMeta == null) { if (Config.AddDataContractAttributes) sb.AppendLine("@DataContract()"); return; } var dcArgs = ""; if (dcMeta.Name != null || dcMeta.Namespace != null) { if (dcMeta.Name != null) dcArgs = "Name={0}".Fmt(dcMeta.Name.QuotedSafeValue()); if (dcMeta.Namespace != null) { if (dcArgs.Length > 0) dcArgs += ", "; dcArgs += "Namespace={0}".Fmt(dcMeta.Namespace.QuotedSafeValue()); } dcArgs = "({0})".Fmt(dcArgs); } sb.AppendLine("@DataContract{0}".Fmt(dcArgs)); }
public bool AppendAttributes(StringBuilderWrapper sb, List<MetadataAttribute> attributes) { if (attributes == null || attributes.Count == 0) return false; var existingAttrs = new HashSet<string>(); foreach (var attr in attributes) { //Java 7 doesn't allow repeating attrs var prefix = existingAttrs.Contains(attr.Name) ? "// " : ""; existingAttrs.Add(attr.Name); if ((attr.Args == null || attr.Args.Count == 0) && (attr.ConstructorArgs == null || attr.ConstructorArgs.Count == 0)) { sb.AppendLine(prefix + "@{0}()".Fmt(attr.Name)); } else { var args = StringBuilderCacheAlt.Allocate(); if (attr.ConstructorArgs != null) { if (attr.ConstructorArgs.Count > 1) prefix = "// "; foreach (var ctorArg in attr.ConstructorArgs) { if (args.Length > 0) args.Append(", "); args.Append("{0}".Fmt(TypeValue(ctorArg.Type, ctorArg.Value))); } } else if (attr.Args != null) { foreach (var attrArg in attr.Args) { if (args.Length > 0) args.Append(", "); args.Append("{0}={1}".Fmt(attrArg.Name, TypeValue(attrArg.Type, attrArg.Value))); } } sb.AppendLine(prefix + "@{0}({1})".Fmt(attr.Name, StringBuilderCacheAlt.ReturnAndFree(args))); } } return true; }
public void AppendComments(StringBuilderWrapper sb, string desc) { if (desc == null) return; sb.AppendLine("/**"); sb.AppendLine("* {0}".Fmt(desc.SafeComment())); sb.AppendLine("*/"); }
public void AddProperties(StringBuilderWrapper sb, MetadataType type, bool initCollections, bool includeResponseStatus) { var wasAdded = false; var dataMemberIndex = 1; foreach (var prop in type.Properties.Safe()) { if (wasAdded) sb.AppendLine(); var propTypeName = Type(prop.Type, prop.GenericArgs); var propType = FindType(prop.Type, prop.TypeNamespace, prop.GenericArgs); var optional = ""; var defaultValue = ""; if (propTypeName.EndsWith("?")) { propTypeName = propTypeName.Substring(0, propTypeName.Length - 1); optional = "?"; } if (Config.MakePropertiesOptional) { optional = "?"; } if (prop.Attributes.Safe().FirstOrDefault(x => x.Name == "Required") != null) { optional = "?"; //always use optional } if (prop.IsArray()) { optional = ""; defaultValue = " = []"; } else if (initCollections && !prop.GenericArgs.IsEmpty()) { if (ArrayTypes.Contains(prop.Type)) { optional = ""; defaultValue = " = []"; } if (DictionaryTypes.Contains(prop.Type)) { optional = ""; defaultValue = " = [:]"; } } if (propType.IsInterface() || IgnorePropertyNames.Contains(prop.Name)) { sb.AppendLine("//{0}:{1} ignored. Swift doesn't support interface properties" .Fmt(prop.Name.SafeToken().PropertyStyle(), propTypeName)); continue; } else if (IgnorePropertyTypeNames.Contains(propTypeName)) { sb.AppendLine("//{0}:{1} ignored. Type could not be extended in Swift" .Fmt(prop.Name.SafeToken().PropertyStyle(), propTypeName)); continue; } wasAdded = AppendDataMember(sb, prop.DataMember, dataMemberIndex++); wasAdded = AppendAttributes(sb, prop.Attributes) || wasAdded; if (type.IsInterface()) { sb.AppendLine("var {0}:{1}{2} {{ get set }}".Fmt( prop.Name.SafeToken().PropertyStyle(), propTypeName, optional)); } else { sb.AppendLine("public var {0}:{1}{2}{3}".Fmt( prop.Name.SafeToken().PropertyStyle(), propTypeName, optional, defaultValue)); } } if (includeResponseStatus) { if (wasAdded) sb.AppendLine(); AppendDataMember(sb, null, dataMemberIndex++); sb.AppendLine("public var {0}:ResponseStatus?".Fmt(typeof(ResponseStatus).Name.PropertyStyle())); } }
private void AddEnumExtension(ref StringBuilderWrapper sbExt, MetadataType type) { if (type.EnumNames == null) return; sbExt.AppendLine(); var typeName = Type(type.Name, type.GenericArgs); sbExt.AppendLine("extension {0} : StringSerializable".Fmt(typeName)); sbExt.AppendLine("{"); sbExt = sbExt.Indent(); sbExt.AppendLine("public static var typeName:String {{ return \"{0}\" }}".Fmt(typeName)); //toJson() sbExt.AppendLine("public func toJson() -> String {"); sbExt = sbExt.Indent(); sbExt.AppendLine("return jsonStringRaw(toString())"); sbExt = sbExt.UnIndent(); sbExt.AppendLine("}"); //toString() sbExt.AppendLine("public func toString() -> String {"); sbExt = sbExt.Indent(); sbExt.AppendLine("switch self {"); foreach (var name in type.EnumNames) { sbExt.AppendLine("case .{0}: return \"{0}\"".Fmt(name)); } sbExt.AppendLine("}"); sbExt = sbExt.UnIndent(); sbExt.AppendLine("}"); //fromString() sbExt.AppendLine("public static func fromString(strValue:String) -> {0}? {{".Fmt(typeName)); sbExt = sbExt.Indent(); sbExt.AppendLine("switch strValue {"); foreach (var name in type.EnumNames) { sbExt.AppendLine("case \"{0}\": return .{0}".Fmt(name)); } sbExt.AppendLine("default: return nil"); sbExt.AppendLine("}"); sbExt = sbExt.UnIndent(); sbExt.AppendLine("}"); //fromObject() sbExt.AppendLine("public static func fromObject(any:AnyObject) -> {0}? {{".Fmt(typeName)); sbExt = sbExt.Indent(); sbExt.AppendLine("switch any {"); sbExt.AppendLine("case let i as Int: return {0}(rawValue: i)".Fmt(typeName)); sbExt.AppendLine("case let s as String: return fromString(s)"); sbExt.AppendLine("default: return nil"); sbExt.AppendLine("}"); sbExt = sbExt.UnIndent(); sbExt.AppendLine("}"); sbExt = sbExt.UnIndent(); sbExt.AppendLine("}"); }
private string AppendType(ref StringBuilderWrapper sb, MetadataType type, string lastNS, CreateTypeOptions options) { sb = sb.Indent(); sb.AppendLine(); AppendComments(sb, type.Description); if (type.Routes != null) { AppendAttributes(sb, type.Routes.ConvertAll(x => x.ToMetadataAttribute())); } AppendAttributes(sb, type.Attributes); AppendDataContract(sb, type.DataContract); if (type.IsEnum.GetValueOrDefault()) { sb.AppendLine("enum {0}".Fmt(Type(type.Name, type.GenericArgs))); sb.AppendLine("{"); sb = sb.Indent(); if (type.EnumNames != null) { for (var i = 0; i < type.EnumNames.Count; i++) { var name = type.EnumNames[i]; var value = type.EnumValues != null ? type.EnumValues[i] : null; sb.AppendLine(value == null ? "{0},".Fmt(name.PropertyStyle()) : "{0} = {1},".Fmt(name.PropertyStyle(), value)); } } sb = sb.UnIndent(); sb.AppendLine("}"); } else { var extends = new List<string>(); //: BaseClass, Interfaces if (type.Inherits != null) extends.Add(Type(type.Inherits).InheritedType()); if (options.ImplementsFn != null) { var implStr = options.ImplementsFn(); if (!string.IsNullOrEmpty(implStr)) extends.Add(implStr); } var extend = extends.Count > 0 ? " extends " + (string.Join(", ", extends.ToArray())) : ""; sb.AppendLine("interface {0}{1}".Fmt(Type(type.Name, type.GenericArgs), extend)); sb.AppendLine("{"); sb = sb.Indent(); var addVersionInfo = Config.AddImplicitVersion != null && options.IsRequest; if (addVersionInfo) { sb.AppendLine("{0}?: number; //{1}".Fmt("Version".PropertyStyle(), Config.AddImplicitVersion)); } AddProperties(sb, type, includeResponseStatus: Config.AddResponseStatus && options.IsResponse && type.Properties.Safe().All(x => x.Name != typeof(ResponseStatus).Name)); sb = sb.UnIndent(); sb.AppendLine("}"); } sb = sb.UnIndent(); return lastNS; }
private string AppendType(ref StringBuilderWrapper sb, MetadataType type, string lastNS, CreateTypeOptions options) { sb.AppendLine(); AppendComments(sb, type.Description); if (type.Routes != null) { AppendAttributes(sb, type.Routes.ConvertAll(x => x.ToMetadataAttribute())); } AppendAttributes(sb, type.Attributes); AppendDataContract(sb, type.DataContract); if (type.IsEnum.GetValueOrDefault()) { if (type.IsEnumInt.GetValueOrDefault() || type.EnumNames.IsEmpty()) { var typeDeclaration = !Config.ExportAsTypes ? "enum" : "export enum"; sb.AppendLine("{0} {1}".Fmt(typeDeclaration, Type(type.Name, type.GenericArgs))); sb.AppendLine("{"); sb = sb.Indent(); if (type.EnumNames != null) { for (var i = 0; i < type.EnumNames.Count; i++) { var name = type.EnumNames[i]; var value = type.EnumValues != null ? type.EnumValues[i] : null; sb.AppendLine(value == null //Enum Value's are not impacted by JS Style ? "{0},".Fmt(name) : "{0} = {1},".Fmt(name, value)); } } sb = sb.UnIndent(); sb.AppendLine("}"); } else { var sbType = StringBuilderCache.Allocate(); var typeDeclaration = !Config.ExportAsTypes ? "type" : "export type"; sbType.Append("{0} {1} = ".Fmt(typeDeclaration, Type(type.Name, type.GenericArgs))); for (var i = 0; i < type.EnumNames.Count; i++) { if (i > 0) sbType.Append(" | "); sbType.Append('"').Append(type.EnumNames[i]).Append('"'); } sbType.Append(";"); sb.AppendLine(StringBuilderCache.ReturnAndFree(sbType)); } } else { var extends = new List<string>(); //: BaseClass, Interfaces if (type.Inherits != null) extends.Add(Type(type.Inherits).InDeclarationType()); string responseTypeExpression = null; var interfaces = new List<string>(); var implStr = options.ImplementsFn?.Invoke(); if (!string.IsNullOrEmpty(implStr)) { interfaces.Add(implStr); if (implStr.StartsWith("IReturn<")) { var types = implStr.RightPart('<'); var returnType = types.Substring(0, types.Length - 1); if (returnType == "any") returnType = "Object"; // This is to avoid invalid syntax such as "return new string()" string replaceReturnType; if (primitiveDefaultValues.TryGetValue(returnType, out replaceReturnType)) returnType = replaceReturnType; responseTypeExpression = replaceReturnType == null ? "createResponse() {{ return new {0}(); }}".Fmt(returnType) : "createResponse() {{ return {0}; }}".Fmt(returnType); } else if (implStr == "IReturnVoid") { responseTypeExpression = "createResponse() {}"; } } var isClass = Config.ExportAsTypes && !type.IsInterface.GetValueOrDefault(); var extend = extends.Count > 0 ? " extends " + extends[0] : ""; if (interfaces.Count > 0) { if (isClass) { extend += " implements " + string.Join(", ", interfaces.ToArray()); } else { if (string.IsNullOrEmpty(extend)) extend = " extends "; else extend += ", "; extend += string.Join(", ", interfaces.ToArray()); } } var typeDeclaration = !Config.ExportAsTypes ? "interface" : $"export {(isClass ? "class" : "interface")}"; sb.AppendLine("{0} {1}{2}".Fmt(typeDeclaration, Type(type.Name, type.GenericArgs), extend)); sb.AppendLine("{"); sb = sb.Indent(); var addVersionInfo = Config.AddImplicitVersion != null && options.IsRequest; if (addVersionInfo) { sb.AppendLine("{0}{1}: number; //{2}".Fmt( "Version".PropertyStyle(), isClass ? "" : "?", Config.AddImplicitVersion)); } AddProperties(sb, type, includeResponseStatus: Config.AddResponseStatus && options.IsResponse && type.Properties.Safe().All(x => x.Name != typeof(ResponseStatus).Name)); if (Config.ExportAsTypes && responseTypeExpression != null) { sb.AppendLine(responseTypeExpression); sb.AppendLine("getTypeName() {{ return \"{0}\"; }}".Fmt(type.Name)); } sb = sb.UnIndent(); sb.AppendLine("}"); } return lastNS; }
public string GetCode(MetadataTypes metadata, IRequest request, INativeTypesMetadata nativeTypes) { var typeNamespaces = new HashSet<string>(); metadata.RemoveIgnoredTypes(Config); metadata.Types.Each(x => typeNamespaces.Add(x.Namespace)); metadata.Operations.Each(x => typeNamespaces.Add(x.Request.Namespace)); var defaultImports = !Config.DefaultImports.IsEmpty() ? Config.DefaultImports : DefaultImports; var globalNamespace = Config.GlobalNamespace; Func<string, string> defaultValue = k => request.QueryString[k].IsNullOrEmpty() ? "//" : ""; var sbInner = StringBuilderCache.Allocate(); var sb = new StringBuilderWrapper(sbInner); sb.AppendLine("/* Options:"); sb.AppendLine("Date: {0}".Fmt(DateTime.Now.ToString("s").Replace("T", " "))); sb.AppendLine("Version: {0}".Fmt(Env.ServiceStackVersion)); sb.AppendLine("Tip: {0}".Fmt(HelpMessages.NativeTypesDtoOptionsTip.Fmt("//"))); sb.AppendLine("BaseUrl: {0}".Fmt(Config.BaseUrl)); sb.AppendLine(); sb.AppendLine("{0}GlobalNamespace: {1}".Fmt(defaultValue("GlobalNamespace"), Config.GlobalNamespace)); //sb.AppendLine("{0}ExportAsTypes: {1}".Fmt(defaultValue("ExportAsTypes"), Config.ExportAsTypes)); sb.AppendLine("{0}MakePropertiesOptional: {1}".Fmt(defaultValue("MakePropertiesOptional"), Config.MakePropertiesOptional)); sb.AppendLine("{0}AddServiceStackTypes: {1}".Fmt(defaultValue("AddServiceStackTypes"), Config.AddServiceStackTypes)); sb.AppendLine("{0}AddResponseStatus: {1}".Fmt(defaultValue("AddResponseStatus"), Config.AddResponseStatus)); sb.AppendLine("{0}AddImplicitVersion: {1}".Fmt(defaultValue("AddImplicitVersion"), Config.AddImplicitVersion)); sb.AppendLine("{0}AddDescriptionAsComments: {1}".Fmt(defaultValue("AddDescriptionAsComments"), Config.AddDescriptionAsComments)); sb.AppendLine("{0}IncludeTypes: {1}".Fmt(defaultValue("IncludeTypes"), Config.IncludeTypes.Safe().ToArray().Join(","))); sb.AppendLine("{0}ExcludeTypes: {1}".Fmt(defaultValue("ExcludeTypes"), Config.ExcludeTypes.Safe().ToArray().Join(","))); sb.AppendLine("{0}DefaultImports: {1}".Fmt(defaultValue("DefaultImports"), defaultImports.Join(","))); sb.AppendLine("*/"); sb.AppendLine(); string lastNS = null; var existingTypes = new HashSet<string>(); var requestTypes = metadata.Operations.Select(x => x.Request).ToHashSet(); var requestTypesMap = metadata.Operations.ToSafeDictionary(x => x.Request); var responseTypes = metadata.Operations .Where(x => x.Response != null) .Select(x => x.Response).ToHashSet(); // Base Types need to be written first var types = CreateSortedTypeList(metadata.Types); allTypes = new List<MetadataType>(); allTypes.AddRange(types); allTypes.AddRange(responseTypes); allTypes.AddRange(requestTypes); allTypes.RemoveAll(x => x.IgnoreType(Config)); allTypes = FilterTypes(allTypes); //TypeScript doesn't support reusing same type name with different generic airity var conflictPartialNames = allTypes.Map(x => x.Name).Distinct() .GroupBy(g => g.LeftPart('`')) .Where(g => g.Count() > 1) .Select(g => g.Key) .ToList(); this.conflictTypeNames = allTypes .Where(x => conflictPartialNames.Any(name => x.Name.StartsWith(name))) .Map(x => x.Name); defaultImports.Each(x => sb.AppendLine("import {0};".Fmt(x))); if (!string.IsNullOrEmpty(globalNamespace)) { var moduleDef = Config.ExportAsTypes ? "" : "declare "; sb.AppendLine(); sb.AppendLine("{0}module {1}".Fmt(moduleDef, globalNamespace.SafeToken())); sb.AppendLine("{"); sb = sb.Indent(); } //ServiceStack core interfaces foreach (var type in allTypes) { var fullTypeName = type.GetFullName(); if (requestTypes.Contains(type)) { if (!existingTypes.Contains(fullTypeName)) { MetadataType response = null; MetadataOperationType operation; if (requestTypesMap.TryGetValue(type, out operation)) { response = operation.Response; } lastNS = AppendType(ref sb, type, lastNS, new CreateTypeOptions { ImplementsFn = () => { if (!Config.AddReturnMarker && !type.ReturnVoidMarker && type.ReturnMarkerTypeName == null) return null; if (type.ReturnVoidMarker) return "IReturnVoid"; if (type.ReturnMarkerTypeName != null) return Type("IReturn`1", new[] { Type(type.ReturnMarkerTypeName).InDeclarationType() }); return response != null ? Type("IReturn`1", new[] { Type(response.Name, response.GenericArgs).InDeclarationType() }) : null; }, IsRequest = true, }); existingTypes.Add(fullTypeName); } } else if (responseTypes.Contains(type)) { if (!existingTypes.Contains(fullTypeName) && !Config.IgnoreTypesInNamespaces.Contains(type.Namespace)) { lastNS = AppendType(ref sb, type, lastNS, new CreateTypeOptions { IsResponse = true, }); existingTypes.Add(fullTypeName); } } else if (types.Contains(type) && !existingTypes.Contains(fullTypeName)) { lastNS = AppendType(ref sb, type, lastNS, new CreateTypeOptions { IsType = true }); existingTypes.Add(fullTypeName); } } if (!string.IsNullOrEmpty(globalNamespace)) { sb = sb.UnIndent(); sb.AppendLine(); sb.AppendLine("}"); } return StringBuilderCache.ReturnAndFree(sbInner); }
public string GetCode(MetadataTypes metadata, IRequest request) { var namespaces = new HashSet<string>(); Config.DefaultNamespaces.Each(x => namespaces.Add(x)); var typeNamespaces = new HashSet<string>(); metadata.Types.Each(x => typeNamespaces.Add(x.Namespace)); metadata.Operations.Each(x => typeNamespaces.Add(x.Request.Namespace)); // Look first for shortest Namespace ending with `ServiceModel` convention, else shortest ns var globalNamespace = Config.GlobalNamespace ?? typeNamespaces.Where(x => x.EndsWith("ServiceModel")) .OrderBy(x => x).FirstOrDefault() ?? typeNamespaces.OrderBy(x => x).First(); Func<string, string> defaultValue = k => request.QueryString[k].IsNullOrEmpty() ? "//" : ""; var sb = new StringBuilderWrapper(new StringBuilder()); sb.AppendLine("(* Options:"); sb.AppendLine("Date: {0}".Fmt(DateTime.Now.ToString("s").Replace("T", " "))); sb.AppendLine("Version: {0}".Fmt(metadata.Version)); sb.AppendLine("BaseUrl: {0}".Fmt(Config.BaseUrl)); sb.AppendLine(); sb.AppendLine("{0}MakeDataContractsExtensible: {1}".Fmt(defaultValue("MakeDataContractsExtensible"), Config.MakeDataContractsExtensible)); sb.AppendLine("{0}AddReturnMarker: {1}".Fmt(defaultValue("AddReturnMarker"), Config.AddReturnMarker)); sb.AppendLine("{0}AddDescriptionAsComments: {1}".Fmt(defaultValue("AddDescriptionAsComments"), Config.AddDescriptionAsComments)); sb.AppendLine("{0}AddDataContractAttributes: {1}".Fmt(defaultValue("AddDataContractAttributes"), Config.AddDataContractAttributes)); sb.AppendLine("{0}AddIndexesToDataMembers: {1}".Fmt(defaultValue("AddIndexesToDataMembers"), Config.AddIndexesToDataMembers)); sb.AppendLine("{0}AddResponseStatus: {1}".Fmt(defaultValue("AddResponseStatus"), Config.AddResponseStatus)); sb.AppendLine("{0}AddImplicitVersion: {1}".Fmt(defaultValue("AddImplicitVersion"), Config.AddImplicitVersion)); sb.AppendLine("{0}InitializeCollections: {1}".Fmt(defaultValue("InitializeCollections"), Config.InitializeCollections)); //sb.AppendLine("{0}AddDefaultXmlNamespace: {1}".Fmt(defaultValue("AddDefaultXmlNamespace"), Config.AddDefaultXmlNamespace)); //sb.AppendLine("{0}DefaultNamespaces: {1}".Fmt(defaultValue("DefaultNamespaces"), Config.DefaultNamespaces.ToArray().Join(", "))); sb.AppendLine("*)"); sb.AppendLine(); //if (Config.AddDataContractAttributes // && Config.AddDefaultXmlNamespace != null) //{ // sb.AppendLine(); // var list = namespaces.Where(x => !Config.DefaultNamespaces.Contains(x)).ToList(); // list.ForEach(x => // sb.AppendLine("[<assembly: ContractNamespace(\"{0}\", ClrNamespace=\"{1}\")>]" // .Fmt(Config.AddDefaultXmlNamespace, x))); // if (list.Count > 0) // { // sb.AppendLine("do()"); //http://scottseely.com/2009/01/23/f-assembly-level-attributes-assemblyinfo-fs-and-do/ // } //} //sb.AppendLine(); string lastNS = null; var existingOps = new HashSet<string>(); var requestTypes = metadata.Operations.Select(x => x.Request).ToHashSet(); var requestTypesMap = metadata.Operations.ToSafeDictionary(x => x.Request); var responseTypes = metadata.Operations .Where(x => x.Response != null) .Select(x => x.Response).ToHashSet(); var types = metadata.Types.ToHashSet(); var allTypes = new List<MetadataType>(); allTypes.AddRange(types); allTypes.AddRange(responseTypes); allTypes.AddRange(requestTypes); var orderedTypes = allTypes.OrderTypesByDeps(); sb.AppendLine("namespace {0}".Fmt(globalNamespace.SafeToken())); sb.AppendLine(); foreach (var ns in namespaces) { sb.AppendLine("open " + ns); } foreach (var type in orderedTypes) { var fullTypeName = type.GetFullName(); if (requestTypes.Contains(type)) { if (!existingOps.Contains(fullTypeName)) { MetadataType response = null; MetadataOperationType operation; if (requestTypesMap.TryGetValue(type, out operation)) { response = operation.Response; } lastNS = AppendType(ref sb, type, lastNS, new CreateTypeOptions { ImplementsFn = () => { if (!Config.AddReturnMarker && !type.ReturnVoidMarker && type.ReturnMarkerTypeName == null) return null; if (type.ReturnVoidMarker) return "IReturnVoid"; if (type.ReturnMarkerTypeName != null) return Type("IReturn`1", new[] { Type(type.ReturnMarkerTypeName) }); return response != null ? Type("IReturn`1", new[] { Type(type.Name, type.GenericArgs) }) : null; }, IsRequest = true, }); existingOps.Add(fullTypeName); } } else if (responseTypes.Contains(type)) { if (!existingOps.Contains(fullTypeName) && !Config.IgnoreTypesInNamespaces.Contains(type.Namespace)) { lastNS = AppendType(ref sb, type, lastNS, new CreateTypeOptions { IsResponse = true, }); existingOps.Add(fullTypeName); } } else if (types.Contains(type) && !existingOps.Contains(fullTypeName)) { lastNS = AppendType(ref sb, type, lastNS, new CreateTypeOptions { IsType = true }); } } sb.AppendLine(); return sb.ToString(); }
private string AppendType(ref StringBuilderWrapper sb, MetadataType type, string lastNS, CreateTypeOptions options) { if (type == null || (type.Namespace != null && type.Namespace.StartsWith("System"))) return lastNS; sb = sb.Indent(); sb.AppendLine(); AppendComments(sb, type.Description); if (type.Routes != null) { AppendAttributes(sb, type.Routes.ConvertAll(x => x.ToMetadataAttribute())); } AppendAttributes(sb, type.Attributes); AppendDataContract(sb, type.DataContract); if (type.IsEnum.GetValueOrDefault()) { sb.AppendLine("type {0} =".Fmt(Type(type.Name, type.GenericArgs))); sb = sb.Indent(); if (type.EnumNames != null) { for (var i = 0; i < type.EnumNames.Count; i++) { var name = type.EnumNames[i]; var value = type.EnumValues != null ? type.EnumValues[i] : i.ToString(); sb.AppendLine("| {0} = {1}".Fmt(name, value)); } } sb = sb.UnIndent(); } else { //sb.AppendLine("[<CLIMutable>]"); // only for Record Types sb.AppendLine("[<AllowNullLiteral>]"); sb.AppendLine("type {0}() = ".Fmt(Type(type.Name, type.GenericArgs))); sb = sb.Indent(); var startLen = sb.Length; //: BaseClass, Interfaces if (type.Inherits != null) sb.AppendLine("inherit {0}()".Fmt(Type(type.Inherits))); if (options.ImplementsFn != null) { var implStr = options.ImplementsFn(); if (!string.IsNullOrEmpty(implStr)) sb.AppendLine("interface {0}".Fmt(implStr)); } var makeExtensible = Config.MakeDataContractsExtensible && type.Inherits == null; if (makeExtensible) { sb.AppendLine("interface IExtensibleDataObject with"); sb.AppendLine(" member val ExtensionData:ExtensionDataObject = null with get, set"); sb.AppendLine("end"); } var addVersionInfo = Config.AddImplicitVersion != null && options.IsOperation; if (addVersionInfo) { sb.AppendLine("member val Version:int = {0} with get, set".Fmt(Config.AddImplicitVersion)); } AddProperties(sb, type); if (sb.Length == startLen) sb.AppendLine("class end"); sb = sb.UnIndent(); } sb = sb.UnIndent(); return lastNS; }
public bool AppendDataMember(StringBuilderWrapper sb, MetadataDataMember dmMeta, int dataMemberIndex) { if (dmMeta == null) { if (Config.AddDataContractAttributes) { sb.AppendLine(Config.AddIndexesToDataMembers ? $"[DataMember(Order={dataMemberIndex})]" : "[DataMember]"); return true; } return false; } var dmArgs = ""; if (dmMeta.Name != null || dmMeta.Order != null || dmMeta.IsRequired != null || dmMeta.EmitDefaultValue != null || Config.AddIndexesToDataMembers) { if (dmMeta.Name != null) dmArgs = $"Name={dmMeta.Name.QuotedSafeValue()}"; if (dmMeta.Order != null || Config.AddIndexesToDataMembers) { if (dmArgs.Length > 0) dmArgs += ", "; dmArgs += $"Order={dmMeta.Order ?? dataMemberIndex}"; } if (dmMeta.IsRequired != null) { if (dmArgs.Length > 0) dmArgs += ", "; dmArgs += $"IsRequired={dmMeta.IsRequired.ToString().ToLower()}"; } if (dmMeta.EmitDefaultValue != null) { if (dmArgs.Length > 0) dmArgs += ", "; dmArgs += $"EmitDefaultValue={dmMeta.EmitDefaultValue.ToString().ToLower()}"; } dmArgs = $"({dmArgs})"; } sb.AppendLine($"[DataMember{dmArgs}]"); return true; }
private void ExtractTypeAliases(CreateTypeOptions options, List<string> typeAliases, List<string> extends, ref StringBuilderWrapper sbExt) { var implStr = options.ImplementsFn(); if (!string.IsNullOrEmpty(implStr)) { var interfaceParts = implStr.SplitOnFirst('<'); if (interfaceParts.Length > 1) { implStr = interfaceParts[0]; //Strip 'I' prefix for interfaces and use as typealias for protocol var alias = implStr.StartsWith("I") ? implStr.Substring(1) : implStr; var genericType = interfaceParts[1].Substring(0, interfaceParts[1].Length - 1); typeAliases.Add("public typealias {0} = {1}".Fmt(alias, genericType)); } extends.Add(implStr); } }
private void AddTypeExtension(ref StringBuilderWrapper sbExt, MetadataType type, bool initCollections) { //Swift doesn't support extensions on same protocol used by Base and Sub types if (type.IsAbstract()) return; var typeName = Type(type.Name, type.GenericArgs); var typeNameOnly = typeName.SplitOnFirst('<')[0]; sbExt.AppendLine(); sbExt.AppendLine("extension {0} : JsonSerializable".Fmt(typeNameOnly)); sbExt.AppendLine("{"); sbExt = sbExt.Indent(); sbExt.AppendLine("public static var typeName:String {{ return \"{0}\" }}".Fmt(typeName)); //func typeConfig() var isGenericType = !type.GenericArgs.IsEmpty(); if (!isGenericType) { sbExt.AppendLine("public static var metadata = Metadata.create(["); sbExt = sbExt.Indent(); } else { //Swift 2.0 doesn't allow stored static properties on generic types yet sbExt.AppendLine("public static var metadata:Metadata {"); sbExt = sbExt.Indent(); sbExt.AppendLine("return Metadata.create(["); } sbExt = sbExt.Indent(); foreach (var prop in GetPropertes(type)) { var propType = FindType(prop.Type, prop.TypeNamespace, prop.GenericArgs); if (propType.IsInterface() || IgnorePropertyTypeNames.Contains(prop.Type) || IgnorePropertyNames.Contains(prop.Name)) continue; var fnName = "property"; if (prop.IsArray() || ArrayTypes.Contains(prop.Type)) { fnName = initCollections ? "arrayProperty" : "optionalArrayProperty"; } else if (DictionaryTypes.Contains(prop.Type)) { fnName = initCollections ? "objectProperty" : "optionalObjectProperty"; } else { if (propType != null && !propType.IsEnum.GetValueOrDefault()) { fnName = "optionalObjectProperty"; } else { fnName = "optionalProperty"; } } var propName = prop.Name.SafeToken().PropertyStyle(); var unescapedName = propName.UnescapeReserved(); sbExt.AppendLine("Type<{0}>.{1}(\"{2}\", get: {{ $0.{3} }}, set: {{ $0.{3} = $1 }}),".Fmt( typeName, fnName, unescapedName, propName)); } sbExt = sbExt.UnIndent(); sbExt.AppendLine("])"); sbExt = sbExt.UnIndent(); if (isGenericType) { sbExt.AppendLine("}"); } sbExt = sbExt.UnIndent(); sbExt.AppendLine("}"); }
public void AddProperties(StringBuilderWrapper sb, MetadataType type, bool includeResponseStatus) { var wasAdded = false; var dataMemberIndex = 1; if (type.Properties != null) { foreach (var prop in type.Properties) { if (wasAdded) sb.AppendLine(); var propType = Type(prop.Type, prop.GenericArgs); var optional = ""; if (propType.EndsWith("?")) { propType = propType.Substring(0, propType.Length - 1); optional = "?"; } if (Config.MakePropertiesOptional) { optional = "?"; } if (prop.Attributes.Safe().FirstOrDefault(x => x.Name == "Required") != null) { optional = ""; } wasAdded = AppendDataMember(sb, prop.DataMember, dataMemberIndex++); wasAdded = AppendAttributes(sb, prop.Attributes) || wasAdded; sb.AppendLine("{1}{2}: {0};".Fmt(propType, prop.Name.SafeToken().PropertyStyle(), optional)); } } if (includeResponseStatus) { if (wasAdded) sb.AppendLine(); AppendDataMember(sb, null, dataMemberIndex++); sb.AppendLine("{0}?: ResponseStatus;".Fmt(typeof(ResponseStatus).Name.PropertyStyle())); } }
public string GetCode(MetadataTypes metadata, IRequest request) { var typeNamespaces = new HashSet<string>(); RemoveIgnoredTypes(metadata); metadata.Types.Each(x => typeNamespaces.Add(x.Namespace)); metadata.Operations.Each(x => typeNamespaces.Add(x.Request.Namespace)); var defaultImports = !Config.DefaultImports.IsEmpty() ? Config.DefaultImports : DefaultImports; Func<string, string> defaultValue = k => request.QueryString[k].IsNullOrEmpty() ? "//" : ""; var sb = new StringBuilderWrapper(new StringBuilder()); var sbExt = new StringBuilderWrapper(new StringBuilder()); sb.AppendLine("/* Options:"); sb.AppendLine("Date: {0}".Fmt(DateTime.Now.ToString("s").Replace("T", " "))); sb.AppendLine("SwiftVersion: 2.0"); sb.AppendLine("Version: {0}".Fmt(Env.ServiceStackVersion)); sb.AppendLine("Tip: {0}".Fmt(HelpMessages.NativeTypesDtoOptionsTip.Fmt("//"))); sb.AppendLine("BaseUrl: {0}".Fmt(Config.BaseUrl)); sb.AppendLine(); sb.AppendLine("{0}BaseClass: {1}".Fmt(defaultValue("BaseClass"), Config.BaseClass)); sb.AppendLine("{0}AddModelExtensions: {1}".Fmt(defaultValue("AddModelExtensions"), Config.AddModelExtensions)); sb.AppendLine("{0}AddServiceStackTypes: {1}".Fmt(defaultValue("AddServiceStackTypes"), Config.AddServiceStackTypes)); sb.AppendLine("{0}IncludeTypes: {1}".Fmt(defaultValue("IncludeTypes"), Config.IncludeTypes.Safe().ToArray().Join(","))); sb.AppendLine("{0}ExcludeTypes: {1}".Fmt(defaultValue("ExcludeTypes"), Config.ExcludeTypes.Safe().ToArray().Join(","))); sb.AppendLine("{0}ExcludeGenericBaseTypes: {1}".Fmt(defaultValue("ExcludeGenericBaseTypes"), Config.ExcludeGenericBaseTypes)); sb.AppendLine("{0}AddResponseStatus: {1}".Fmt(defaultValue("AddResponseStatus"), Config.AddResponseStatus)); sb.AppendLine("{0}AddImplicitVersion: {1}".Fmt(defaultValue("AddImplicitVersion"), Config.AddImplicitVersion)); sb.AppendLine("{0}InitializeCollections: {1}".Fmt(defaultValue("InitializeCollections"), Config.InitializeCollections)); sb.AppendLine("{0}TreatTypesAsStrings: {1}".Fmt(defaultValue("TreatTypesAsStrings"), Config.TreatTypesAsStrings.Safe().ToArray().Join(","))); sb.AppendLine("{0}DefaultImports: {1}".Fmt(defaultValue("DefaultImports"), defaultImports.Join(","))); sb.AppendLine("*/"); sb.AppendLine(); foreach (var typeName in Config.TreatTypesAsStrings.Safe()) { TypeAliases[typeName] = "String"; } string lastNS = null; var existingTypes = new HashSet<string>(); var requestTypes = metadata.Operations.Select(x => x.Request).ToHashSet(); var requestTypesMap = metadata.Operations.ToSafeDictionary(x => x.Request); var responseTypes = metadata.Operations .Where(x => x.Response != null) .Select(x => x.Response).ToHashSet(); var types = metadata.Types.ToHashSet(); AllTypes.AddRange(requestTypes); AllTypes.AddRange(responseTypes); AllTypes.AddRange(types); //Swift doesn't support reusing same type name with different generic airity var conflictPartialNames = AllTypes.Map(x => x.Name).Distinct() .GroupBy(g => g.SplitOnFirst('`')[0]) .Where(g => g.Count() > 1) .Select(g => g.Key) .ToList(); this.conflictTypeNames = AllTypes .Where(x => conflictPartialNames.Any(name => x.Name.StartsWith(name))) .Map(x => x.Name); defaultImports.Each(x => sb.AppendLine("import {0};".Fmt(x))); //ServiceStack core interfaces foreach (var type in AllTypes) { var fullTypeName = type.GetFullName(); if (requestTypes.Contains(type)) { if (!existingTypes.Contains(fullTypeName)) { MetadataType response = null; MetadataOperationType operation; if (requestTypesMap.TryGetValue(type, out operation)) { response = operation.Response; } lastNS = AppendType(ref sb, ref sbExt, type, lastNS, new CreateTypeOptions { ImplementsFn = () => { if (!Config.AddReturnMarker && !type.ReturnVoidMarker && type.ReturnMarkerTypeName == null) return null; if (type.ReturnVoidMarker) return "IReturnVoid"; if (type.ReturnMarkerTypeName != null) return ReturnType("IReturn`1", new[] { Type(type.ReturnMarkerTypeName) }); return response != null ? ReturnType("IReturn`1", new[] { Type(response.Name, response.GenericArgs) }) : null; }, IsRequest = true, }); existingTypes.Add(fullTypeName); } } else if (responseTypes.Contains(type)) { if (!existingTypes.Contains(fullTypeName) && !Config.IgnoreTypesInNamespaces.Contains(type.Namespace)) { lastNS = AppendType(ref sb, ref sbExt, type, lastNS, new CreateTypeOptions { IsResponse = true, }); existingTypes.Add(fullTypeName); } } else if (types.Contains(type) && !existingTypes.Contains(fullTypeName)) { lastNS = AppendType(ref sb, ref sbExt, type, lastNS, new CreateTypeOptions { IsType = true }); existingTypes.Add(fullTypeName); } } if (Config.AddModelExtensions) { sb.AppendLine(); sb.AppendLine(sbExt.ToString()); } return sb.ToString(); }
public string GetCode(MetadataTypes metadata, IRequest request, INativeTypesMetadata nativeTypes) { var typeNamespaces = new HashSet<string>(); metadata.RemoveIgnoredTypes(Config); metadata.Types.Each(x => typeNamespaces.Add(x.Namespace)); metadata.Operations.Each(x => typeNamespaces.Add(x.Request.Namespace)); var defaultImports = !Config.DefaultImports.IsEmpty() ? Config.DefaultImports : DefaultImports; // Look first for shortest Namespace ending with `ServiceModel` convention, else shortest ns var globalNamespace = Config.GlobalNamespace ?? typeNamespaces.Where(x => x.EndsWith("ServiceModel")) .OrderBy(x => x).FirstOrDefault() ?? typeNamespaces.OrderBy(x => x).First(); Func<string, string> defaultValue = k => request.QueryString[k].IsNullOrEmpty() ? "//" : ""; var sb = new StringBuilderWrapper(new StringBuilder()); sb.AppendLine("/* Options:"); sb.AppendLine("Date: {0}".Fmt(DateTime.Now.ToString("s").Replace("T", " "))); sb.AppendLine("Version: {0}".Fmt(Env.ServiceStackVersion)); sb.AppendLine("BaseUrl: {0}".Fmt(Config.BaseUrl)); sb.AppendLine(); sb.AppendLine("{0}GlobalNamespace: {1}".Fmt(defaultValue("GlobalNamespace"), Config.GlobalNamespace)); sb.AppendLine("{0}MakePropertiesOptional: {1}".Fmt(defaultValue("MakePropertiesOptional"), Config.MakePropertiesOptional)); sb.AppendLine("{0}AddServiceStackTypes: {1}".Fmt(defaultValue("AddServiceStackTypes"), Config.AddServiceStackTypes)); sb.AppendLine("{0}AddResponseStatus: {1}".Fmt(defaultValue("AddResponseStatus"), Config.AddResponseStatus)); sb.AppendLine("{0}AddImplicitVersion: {1}".Fmt(defaultValue("AddImplicitVersion"), Config.AddImplicitVersion)); sb.AppendLine("{0}IncludeTypes: {1}".Fmt(defaultValue("IncludeTypes"), Config.IncludeTypes.Safe().ToArray().Join(","))); sb.AppendLine("{0}ExcludeTypes: {1}".Fmt(defaultValue("ExcludeTypes"), Config.ExcludeTypes.Safe().ToArray().Join(","))); sb.AppendLine("{0}DefaultImports: {1}".Fmt(defaultValue("DefaultImports"), defaultImports.Join(","))); sb.AppendLine("*/"); sb.AppendLine(); string lastNS = null; var existingTypes = new HashSet<string>(); var requestTypes = metadata.Operations.Select(x => x.Request).ToHashSet(); var requestTypesMap = metadata.Operations.ToSafeDictionary(x => x.Request); var responseTypes = metadata.Operations .Where(x => x.Response != null) .Select(x => x.Response).ToHashSet(); var types = metadata.Types.ToHashSet(); var allTypes = new List<MetadataType>(); allTypes.AddRange(types); allTypes.AddRange(responseTypes); allTypes.AddRange(requestTypes); allTypes.RemoveAll(x => x.IgnoreType(Config)); //TypeScript doesn't support reusing same type name with different generic airity var conflictPartialNames = allTypes.Map(x => x.Name).Distinct() .GroupBy(g => g.SplitOnFirst('`')[0]) .Where(g => g.Count() > 1) .Select(g => g.Key) .ToList(); this.conflictTypeNames = allTypes .Where(x => conflictPartialNames.Any(name => x.Name.StartsWith(name))) .Map(x => x.Name); defaultImports.Each(x => sb.AppendLine("import {0};".Fmt(x))); sb.AppendLine(); sb.AppendLine("declare module {0}".Fmt(globalNamespace.SafeToken())); sb.AppendLine("{"); //ServiceStack core interfaces foreach (var type in allTypes) { var fullTypeName = type.GetFullName(); if (requestTypes.Contains(type)) { if (!existingTypes.Contains(fullTypeName)) { MetadataType response = null; MetadataOperationType operation; if (requestTypesMap.TryGetValue(type, out operation)) { response = operation.Response; } lastNS = AppendType(ref sb, type, lastNS, new CreateTypeOptions { ImplementsFn = () => { if (!Config.AddReturnMarker && !type.ReturnVoidMarker && type.ReturnMarkerTypeName == null) return null; if (type.ReturnVoidMarker) return "IReturnVoid"; if (type.ReturnMarkerTypeName != null) return Type("IReturn`1", new[] { Type(type.ReturnMarkerTypeName) }); return response != null ? Type("IReturn`1", new[] { Type(response.Name, response.GenericArgs) }) : null; }, IsRequest = true, }); existingTypes.Add(fullTypeName); } } else if (responseTypes.Contains(type)) { if (!existingTypes.Contains(fullTypeName) && !Config.IgnoreTypesInNamespaces.Contains(type.Namespace)) { lastNS = AppendType(ref sb, type, lastNS, new CreateTypeOptions { IsResponse = true, }); existingTypes.Add(fullTypeName); } } else if (types.Contains(type) && !existingTypes.Contains(fullTypeName)) { lastNS = AppendType(ref sb, type, lastNS, new CreateTypeOptions { IsType = true }); existingTypes.Add(fullTypeName); } } sb.AppendLine(); sb.AppendLine("}"); return sb.ToString(); }
public bool AppendAttributes(StringBuilderWrapper sb, List<MetadataAttribute> attributes) { if (attributes == null || attributes.Count == 0) return false; foreach (var attr in attributes) { if ((attr.Args == null || attr.Args.Count == 0) && (attr.ConstructorArgs == null || attr.ConstructorArgs.Count == 0)) { sb.AppendLine("// @{0}()".Fmt(attr.Name)); } else { var args = new StringBuilder(); if (attr.ConstructorArgs != null) { foreach (var ctorArg in attr.ConstructorArgs) { if (args.Length > 0) args.Append(", "); args.Append("{0}".Fmt(TypeValue(ctorArg.Type, ctorArg.Value))); } } else if (attr.Args != null) { foreach (var attrArg in attr.Args) { if (args.Length > 0) args.Append(", "); args.Append("{0}={1}".Fmt(attrArg.Name, TypeValue(attrArg.Type, attrArg.Value))); } } sb.AppendLine("// @{0}({1})".Fmt(attr.Name, args)); } } return true; }
private string AppendType(ref StringBuilderWrapper sb, MetadataType type, string lastNS, List<MetadataType> allTypes, CreateTypeOptions options) { if (type.IsNested.GetValueOrDefault() && !options.IsNestedType) return lastNS; var ns = Config.GlobalNamespace ?? type.Namespace; if (ns != lastNS) { if (lastNS != null) sb.AppendLine("}"); lastNS = ns; sb.AppendLine(); sb.AppendLine("namespace {0}".Fmt(ns.SafeToken())); sb.AppendLine("{"); } sb = sb.Indent(); sb.AppendLine(); AppendComments(sb, type.Description); if (type.Routes != null) { AppendAttributes(sb, type.Routes.ConvertAll(x => x.ToMetadataAttribute())); } AppendAttributes(sb, type.Attributes); AppendDataContract(sb, type.DataContract); if (Config.AddGeneratedCodeAttributes) sb.AppendLine("[GeneratedCode(\"AddServiceStackReference\", \"{0}\")]".Fmt(Env.VersionString)); if (type.IsEnum.GetValueOrDefault()) { sb.AppendLine("public enum {0}".Fmt(Type(type.Name, type.GenericArgs))); sb.AppendLine("{"); sb = sb.Indent(); if (type.EnumNames != null) { for (var i = 0; i < type.EnumNames.Count; i++) { var name = type.EnumNames[i]; var value = type.EnumValues != null ? type.EnumValues[i] : null; sb.AppendLine(value == null ? "{0},".Fmt(name) : "{0} = {1},".Fmt(name, value)); } } sb = sb.UnIndent(); sb.AppendLine("}"); } else { var partial = Config.MakePartial ? "partial " : ""; var defType = type.IsInterface() ? "interface" : "class"; sb.AppendLine("public {0}{1} {2}".Fmt(partial, defType, Type(type.Name, type.GenericArgs))); //: BaseClass, Interfaces var inheritsList = new List<string>(); if (type.Inherits != null) { inheritsList.Add(Type(type.Inherits, includeNested:true)); } if (options.ImplementsFn != null) { var implStr = options.ImplementsFn(); if (!string.IsNullOrEmpty(implStr)) inheritsList.Add(implStr); if (!type.Implements.IsEmpty()) type.Implements.Each(x => inheritsList.Add(Type(x))); } var makeExtensible = Config.MakeDataContractsExtensible && type.Inherits == null; if (makeExtensible) inheritsList.Add("IExtensibleDataObject"); if (inheritsList.Count > 0) sb.AppendLine(" : {0}".Fmt(string.Join(", ", inheritsList.ToArray()))); sb.AppendLine("{"); sb = sb.Indent(); AddConstuctor(sb, type, options); AddProperties(sb, type, includeResponseStatus: Config.AddResponseStatus && options.IsResponse && type.Properties.Safe().All(x => x.Name != typeof(ResponseStatus).Name)); foreach (var innerTypeRef in type.InnerTypes.Safe()) { var innerType = allTypes.FirstOrDefault(x => x.Name == innerTypeRef.Name); if (innerType == null) continue; sb = sb.UnIndent(); AppendType(ref sb, innerType, lastNS, allTypes, new CreateTypeOptions { IsNestedType = true }); sb = sb.Indent(); } sb = sb.UnIndent(); sb.AppendLine("}"); } sb = sb.UnIndent(); return lastNS; }
public void AddProperties(StringBuilderWrapper sb, MetadataType type, bool includeResponseStatus, bool addPropertyAccessors, string settersReturnType) { var wasAdded = false; var sbInner = StringBuilderCacheAlt.Allocate(); var sbAccessors = new StringBuilderWrapper(sbInner); if (addPropertyAccessors) { sbAccessors.AppendLine(); sbAccessors = sbAccessors.Indent().Indent(); } var dataMemberIndex = 1; if (type.Properties != null) { foreach (var prop in type.Properties) { if (wasAdded) sb.AppendLine(); var propType = Type(prop.Type, prop.GenericArgs); var fieldName = prop.Name.SafeToken().PropertyStyle(); var accessorName = fieldName.ToPascalCase(); wasAdded = AppendComments(sb, prop.Description); wasAdded = AppendDataMember(sb, prop.DataMember, dataMemberIndex++) || wasAdded; wasAdded = AppendAttributes(sb, prop.Attributes) || wasAdded; if (!fieldName.IsKeyWord()) { sb.AppendLine("public {0} {1} = null;".Fmt(propType, fieldName)); } else { var originalName = fieldName; fieldName = Char.ToUpper(fieldName[0]) + fieldName.SafeSubstring(1); sb.AppendLine("@SerializedName(\"{0}\") public {1} {2} = null;".Fmt(originalName, propType, fieldName)); } if (addPropertyAccessors) sbAccessors.AppendPropertyAccessor(propType, fieldName, accessorName, settersReturnType); } } if (includeResponseStatus) { if (wasAdded) sb.AppendLine(); AppendDataMember(sb, null, dataMemberIndex++); sb.AppendLine("public ResponseStatus {0} = null;".Fmt(typeof(ResponseStatus).Name.PropertyStyle())); if (addPropertyAccessors) sbAccessors.AppendPropertyAccessor("ResponseStatus", "ResponseStatus", settersReturnType); } if (sbAccessors.Length > 0) sb.AppendLine(StringBuilderCacheAlt.ReturnAndFree(sbInner).TrimEnd()); //remove last \n }
private void AddConstuctor(StringBuilderWrapper sb, MetadataType type, CreateTypeOptions options) { if (type.IsInterface()) return; var initCollections = feature.ShouldInitializeCollections(type, Config.InitializeCollections); if (Config.AddImplicitVersion == null && !initCollections) return; var collectionProps = new List<MetadataPropertyType>(); if (type.Properties != null && initCollections) collectionProps = type.Properties.Where(x => x.IsCollection()).ToList(); var addVersionInfo = Config.AddImplicitVersion != null && options.IsRequest; if (!addVersionInfo && collectionProps.Count <= 0) return; if (addVersionInfo) { var @virtual = Config.MakeVirtual ? "virtual " : ""; sb.AppendLine("public {0}int Version {{ get; set; }}".Fmt(@virtual)); sb.AppendLine(); } sb.AppendLine("public {0}()".Fmt(NameOnly(type.Name))); sb.AppendLine("{"); sb = sb.Indent(); if (addVersionInfo) sb.AppendLine("Version = {0};".Fmt(Config.AddImplicitVersion)); foreach (var prop in collectionProps) { sb.AppendLine("{0} = new {1}{{}};".Fmt( prop.Name.SafeToken(), Type(prop.Type, prop.GenericArgs, includeNested: true))); } sb = sb.UnIndent(); sb.AppendLine("}"); sb.AppendLine(); }
public bool AppendComments(StringBuilderWrapper sb, string desc) { if (desc != null && Config.AddDescriptionAsComments) { sb.AppendLine("/**"); sb.AppendLine("* {0}".Fmt(desc.SafeComment())); sb.AppendLine("*/"); } return false; }
public string GetCode(MetadataTypes metadata, IRequest request) { var namespaces = Config.GetDefaultNamespaces(metadata); metadata.RemoveIgnoredTypesForNet(Config); if (Config.GlobalNamespace == null) { metadata.Types.Each(x => namespaces.Add(x.Namespace)); metadata.Operations.Each(x => namespaces.Add(x.Request.Namespace)); } else { namespaces.Add(Config.GlobalNamespace); } Func<string,string> defaultValue = k => request.QueryString[k].IsNullOrEmpty() ? "//" : ""; var sbInner = StringBuilderCache.Allocate(); var sb = new StringBuilderWrapper(sbInner); sb.AppendLine("/* Options:"); sb.AppendLine("Date: {0}".Fmt(DateTime.Now.ToString("s").Replace("T"," "))); sb.AppendLine("Version: {0}".Fmt(Env.ServiceStackVersion)); sb.AppendLine("Tip: {0}".Fmt(HelpMessages.NativeTypesDtoOptionsTip.Fmt("//"))); sb.AppendLine("BaseUrl: {0}".Fmt(Config.BaseUrl)); sb.AppendLine(); sb.AppendLine("{0}GlobalNamespace: {1}".Fmt(defaultValue("GlobalNamespace"), Config.GlobalNamespace)); sb.AppendLine("{0}MakePartial: {1}".Fmt(defaultValue("MakePartial"), Config.MakePartial)); sb.AppendLine("{0}MakeVirtual: {1}".Fmt(defaultValue("MakeVirtual"), Config.MakeVirtual)); sb.AppendLine("{0}MakeDataContractsExtensible: {1}".Fmt(defaultValue("MakeDataContractsExtensible"), Config.MakeDataContractsExtensible)); sb.AppendLine("{0}AddReturnMarker: {1}".Fmt(defaultValue("AddReturnMarker"), Config.AddReturnMarker)); sb.AppendLine("{0}AddDescriptionAsComments: {1}".Fmt(defaultValue("AddDescriptionAsComments"), Config.AddDescriptionAsComments)); sb.AppendLine("{0}AddDataContractAttributes: {1}".Fmt(defaultValue("AddDataContractAttributes"), Config.AddDataContractAttributes)); sb.AppendLine("{0}AddIndexesToDataMembers: {1}".Fmt(defaultValue("AddIndexesToDataMembers"), Config.AddIndexesToDataMembers)); sb.AppendLine("{0}AddGeneratedCodeAttributes: {1}".Fmt(defaultValue("AddGeneratedCodeAttributes"), Config.AddGeneratedCodeAttributes)); sb.AppendLine("{0}AddResponseStatus: {1}".Fmt(defaultValue("AddResponseStatus"), Config.AddResponseStatus)); sb.AppendLine("{0}AddImplicitVersion: {1}".Fmt(defaultValue("AddImplicitVersion"), Config.AddImplicitVersion)); sb.AppendLine("{0}InitializeCollections: {1}".Fmt(defaultValue("InitializeCollections"), Config.InitializeCollections)); sb.AppendLine("{0}IncludeTypes: {1}".Fmt(defaultValue("IncludeTypes"), Config.IncludeTypes.Safe().ToArray().Join(","))); sb.AppendLine("{0}ExcludeTypes: {1}".Fmt(defaultValue("ExcludeTypes"), Config.ExcludeTypes.Safe().ToArray().Join(","))); sb.AppendLine("{0}AddDefaultXmlNamespace: {1}".Fmt(defaultValue("AddDefaultXmlNamespace"), Config.AddDefaultXmlNamespace)); //[GeneratedCode] //sb.AppendLine("{0}DefaultNamespaces: {1}".Fmt(defaultValue("DefaultNamespaces"), Config.DefaultNamespaces.ToArray().Join(", "))); sb.AppendLine("*/"); sb.AppendLine(); namespaces.Where(x => !string.IsNullOrEmpty(x)) .Each(x => sb.AppendLine("using {0};".Fmt(x))); if (Config.AddGeneratedCodeAttributes) sb.AppendLine("using System.CodeDom.Compiler;"); if (Config.AddDataContractAttributes && Config.AddDefaultXmlNamespace != null) { sb.AppendLine(); namespaces.Where(x => !Config.DefaultNamespaces.Contains(x)).ToList() .ForEach(x => sb.AppendLine("[assembly: ContractNamespace(\"{0}\", ClrNamespace=\"{1}\")]" .Fmt(Config.AddDefaultXmlNamespace, x))); } sb.AppendLine(); string lastNS = null; var existingTypes = new HashSet<string>(); var requestTypes = metadata.Operations.Select(x => x.Request).ToHashSet(); var requestTypesMap = metadata.Operations.ToSafeDictionary(x => x.Request); var responseTypes = metadata.Operations .Where(x => x.Response != null) .Select(x => x.Response).ToHashSet(); var types = metadata.Types.ToHashSet(); var allTypes = new List<MetadataType>(); allTypes.AddRange(requestTypes); allTypes.AddRange(responseTypes); allTypes.AddRange(types); var orderedTypes = allTypes .OrderBy(x => x.Namespace) .ThenBy(x => x.Name); foreach (var type in orderedTypes) { var fullTypeName = type.GetFullName(); if (requestTypes.Contains(type)) { if (!existingTypes.Contains(fullTypeName)) { MetadataType response = null; MetadataOperationType operation; if (requestTypesMap.TryGetValue(type, out operation)) { response = operation.Response; } lastNS = AppendType(ref sb, type, lastNS, allTypes, new CreateTypeOptions { ImplementsFn = () => { if (!Config.AddReturnMarker && !type.ReturnVoidMarker && type.ReturnMarkerTypeName == null) return null; if (type.ReturnVoidMarker) return "IReturnVoid"; if (type.ReturnMarkerTypeName != null) return Type("IReturn`1", new[] { Type(type.ReturnMarkerTypeName) }); return response != null ? Type("IReturn`1", new[] { Type(response.Name, response.GenericArgs) }) : null; }, IsRequest = true, }); existingTypes.Add(fullTypeName); } } else if (responseTypes.Contains(type)) { if (!existingTypes.Contains(fullTypeName) && !Config.IgnoreTypesInNamespaces.Contains(type.Namespace)) { lastNS = AppendType(ref sb, type, lastNS, allTypes, new CreateTypeOptions { IsResponse = true, }); existingTypes.Add(fullTypeName); } } else if (types.Contains(type) && !existingTypes.Contains(fullTypeName)) { lastNS = AppendType(ref sb, type, lastNS, allTypes, new CreateTypeOptions { IsType = true }); existingTypes.Add(fullTypeName); } } if (lastNS != null) sb.AppendLine("}"); sb.AppendLine(); return StringBuilderCache.ReturnAndFree(sbInner); }
public bool AppendDataMember(StringBuilderWrapper sb, MetadataDataMember dmMeta, int dataMemberIndex) { if (dmMeta == null) { if (Config.AddDataContractAttributes) { sb.AppendLine(Config.AddIndexesToDataMembers ? "@DataMember(Order={0})".Fmt(dataMemberIndex) : "@DataMember()"); return true; } return false; } var dmArgs = ""; if (dmMeta.Name != null || dmMeta.Order != null || dmMeta.IsRequired != null || dmMeta.EmitDefaultValue != null || Config.AddIndexesToDataMembers) { if (dmMeta.Name != null) dmArgs = "Name={0}".Fmt(dmMeta.Name.QuotedSafeValue()); if (dmMeta.Order != null || Config.AddIndexesToDataMembers) { if (dmArgs.Length > 0) dmArgs += ", "; dmArgs += "Order={0}".Fmt(dmMeta.Order ?? dataMemberIndex); } if (dmMeta.IsRequired != null) { if (dmArgs.Length > 0) dmArgs += ", "; dmArgs += "IsRequired={0}".Fmt(dmMeta.IsRequired.ToString().ToLower()); } if (dmMeta.EmitDefaultValue != null) { if (dmArgs.Length > 0) dmArgs += ", "; dmArgs += "EmitDefaultValue={0}".Fmt(dmMeta.EmitDefaultValue.ToString().ToLower()); } dmArgs = "({0})".Fmt(dmArgs); } sb.AppendLine("@DataMember{0}".Fmt(dmArgs)); if (dmMeta.Name != null) { sb.AppendLine("@SerializedName(\"{0}\")".Fmt(dmMeta.Name)); } return true; }
public void AppendComments(StringBuilderWrapper sb, string desc) { if (desc == null) return; if (Config.AddDescriptionAsComments) { sb.AppendLine("///<summary>"); sb.AppendLine("///{0}".Fmt(desc.SafeComment())); sb.AppendLine("///</summary>"); } else { sb.AppendLine("[Description({0})]".Fmt(desc.QuotedSafeValue())); } }
private string AppendType(ref StringBuilderWrapper sb, MetadataType type, string lastNS, CreateTypeOptions options) { sb = sb.Indent(); sb.AppendLine(); AppendComments(sb, type.Description); if (type.Routes != null) { AppendAttributes(sb, type.Routes.ConvertAll(x => x.ToMetadataAttribute())); } AppendAttributes(sb, type.Attributes); AppendDataContract(sb, type.DataContract); var typeName = Type(type.Name, type.GenericArgs); if (type.IsEnum.GetValueOrDefault()) { sb.AppendLine("public static enum {0}".Fmt(typeName)); sb.AppendLine("{"); sb = sb.Indent(); if (type.EnumNames != null) { var hasIntValue = false; for (var i = 0; i < type.EnumNames.Count; i++) { var name = type.EnumNames[i]; var value = type.EnumValues != null ? type.EnumValues[i] : null; var delim = i == type.EnumNames.Count - 1 ? ";" : ","; var serializeAs = JsConfig.TreatEnumAsInteger || (type.Attributes.Safe().Any(x => x.Name == "Flags")) ? "@SerializedName(\"{0}\") ".Fmt(value) : ""; sb.AppendLine(value == null ? "{0}{1}".Fmt(name.ToPascalCase(), delim) : serializeAs + "{0}({1}){2}".Fmt(name.ToPascalCase(), value, delim)); hasIntValue = hasIntValue || value != null; } if (hasIntValue) { sb.AppendLine(); sb.AppendLine("private final int value;"); sb.AppendLine("{0}(final int intValue) {{ value = intValue; }}".Fmt(typeName)); sb.AppendLine("public int getValue() { return value; }"); } } sb = sb.UnIndent(); sb.AppendLine("}"); } else { var defType = type.IsInterface() ? "interface" : "class"; var extends = new List<string>(); //: BaseClass, Interfaces if (type.Inherits != null) extends.Add(Type(type.Inherits).InheritedType()); string responseTypeExpression = null; var interfaces = new List<string>(); if (options.ImplementsFn != null) { var implStr = options.ImplementsFn(); if (!string.IsNullOrEmpty(implStr)) { interfaces.Add(implStr); if (implStr.StartsWith("IReturn<")) { var types = implStr.RightPart('<'); var returnType = types.Substring(0, types.Length - 1); //Can't get .class from Generic Type definition responseTypeExpression = returnType.Contains("<") ? "new TypeToken<{0}>(){{}}.getType()".Fmt(returnType) : "{0}.class".Fmt(returnType); } } if (!type.Implements.IsEmpty()) { foreach (var interfaceRef in type.Implements) { interfaces.Add(Type(interfaceRef)); } } } var extend = extends.Count > 0 ? " extends " + extends[0] : ""; if (interfaces.Count > 0) extend += " implements " + string.Join(", ", interfaces.ToArray()); var addPropertyAccessors = Config.AddPropertyAccessors && !type.IsInterface(); var settersReturnType = addPropertyAccessors && Config.SettersReturnThis ? typeName : null; sb.AppendLine("public static {0} {1}{2}".Fmt(defType, typeName, extend)); sb.AppendLine("{"); sb = sb.Indent(); var addVersionInfo = Config.AddImplicitVersion != null && options.IsRequest; if (addVersionInfo) { sb.AppendLine("public Integer {0} = {1};".Fmt("Version".PropertyStyle(), Config.AddImplicitVersion)); if (addPropertyAccessors) sb.AppendPropertyAccessor("Integer", "Version", settersReturnType); } AddProperties(sb, type, includeResponseStatus: Config.AddResponseStatus && options.IsResponse && type.Properties.Safe().All(x => x.Name != typeof(ResponseStatus).Name), addPropertyAccessors: addPropertyAccessors, settersReturnType: settersReturnType); if (responseTypeExpression != null) { sb.AppendLine("private static Object responseType = {0};".Fmt(responseTypeExpression)); sb.AppendLine("public Object getResponseType() { return responseType; }"); } sb = sb.UnIndent(); sb.AppendLine("}"); } sb = sb.UnIndent(); return lastNS; }
private string AppendType(ref StringBuilderWrapper sb, ref StringBuilderWrapper sbExt, MetadataType type, string lastNS, CreateTypeOptions options) { //sb = sb.Indent(); var hasGenericBaseType = type.Inherits != null && !type.Inherits.GenericArgs.IsEmpty(); if (Config.ExcludeGenericBaseTypes && hasGenericBaseType) { sb.AppendLine("//Excluded {0} : {1}<{2}>".Fmt(type.Name, type.Inherits.Name.SplitOnFirst('`')[0], string.Join(",", type.Inherits.GenericArgs))); return lastNS; } sb.AppendLine(); AppendComments(sb, type.Description); if (type.Routes != null) { AppendAttributes(sb, type.Routes.ConvertAll(x => x.ToMetadataAttribute())); } AppendAttributes(sb, type.Attributes); AppendDataContract(sb, type.DataContract); if (type.IsEnum.GetValueOrDefault()) { sb.AppendLine("public enum {0} : Int".Fmt(Type(type.Name, type.GenericArgs))); sb.AppendLine("{"); sb = sb.Indent(); if (type.EnumNames != null) { for (var i = 0; i < type.EnumNames.Count; i++) { var name = type.EnumNames[i]; var value = type.EnumValues != null ? type.EnumValues[i] : null; sb.AppendLine(value == null ? "case {0}".Fmt(name) : "case {0} = {1}".Fmt(name, value)); } } sb = sb.UnIndent(); sb.AppendLine("}"); AddEnumExtension(ref sbExt, type); } else { var defType = "class"; var typeName = Type(type.Name, type.GenericArgs).AddGenericConstraints(); var extends = new List<string>(); //: BaseClass, Interfaces if (type.Inherits != null) { var baseType = Type(type.Inherits).InheritedType(); //Swift requires re-declaring base type generics definition on super type var genericDefPos = baseType.IndexOf("<"); if (genericDefPos >= 0) { //Need to declare BaseType is JsonSerializable var subBaseType = baseType.Substring(genericDefPos) .AddGenericConstraints(); typeName += subBaseType; } extends.Add(baseType); } else if (Config.BaseClass != null && !type.IsInterface()) { extends.Add(Config.BaseClass); } var typeAliases = new List<string>(); if (options.ImplementsFn != null) { //Swift doesn't support Generic Interfaces like IReturn<T> //Converting them into protocols with typealiases instead ExtractTypeAliases(options, typeAliases, extends, ref sbExt); if (!type.Implements.IsEmpty()) type.Implements.Each(x => extends.Add(Type(x))); } if (type.IsInterface()) { defType = "protocol"; //Extract Protocol Arguments into different typealiases if (!type.GenericArgs.IsEmpty()) { typeName = Type(type.Name, null); foreach (var arg in type.GenericArgs) { typeAliases.Add("public typealias {0} = {0}".Fmt(arg)); } } } var extend = extends.Count > 0 ? " : " + (string.Join(", ", extends.ToArray())) : ""; sb.AppendLine("public {0} {1}{2}".Fmt(defType, typeName, extend)); sb.AppendLine("{"); sb = sb.Indent(); if (typeAliases.Count > 0) { foreach (var typeAlias in typeAliases) { sb.AppendLine(typeAlias); } sb.AppendLine(); } if (!type.IsInterface()) { if (extends.Count > 0 && OverrideInitForBaseClasses.Contains(extends[0])) { sb.AppendLine("required public override init(){}"); } else { sb.AppendLine("required public init(){}"); } } var addVersionInfo = Config.AddImplicitVersion != null && options.IsRequest; if (addVersionInfo) { sb.AppendLine("public var {0}:Int = {1}".Fmt("Version".PropertyStyle(), Config.AddImplicitVersion)); } AddProperties(sb, type, initCollections: !type.IsInterface() && Config.InitializeCollections, includeResponseStatus: Config.AddResponseStatus && options.IsResponse && type.Properties.Safe().All(x => x.Name != typeof(ResponseStatus).Name)); sb = sb.UnIndent(); sb.AppendLine("}"); if (!type.IsInterface()) { AddTypeExtension(ref sbExt, type, initCollections: Config.InitializeCollections); } } //sb = sb.UnIndent(); return lastNS; }