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("End Namespace"); } lastNS = ns; sb.AppendLine(); sb.AppendLine($"Namespace {MetadataExtensions.SafeToken(ns)}"); //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\", \"{Env.VersionString}\")>"); } PreTypeFilter?.Invoke(sb, type); if (type.IsEnum.GetValueOrDefault()) { sb.AppendLine("Public Enum {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?[i]; if (KeyWords.Contains(name)) { name = $"[{name}]"; } sb.AppendLine(value == null ? name : $"{name} = {value}"); } } sb = sb.UnIndent(); sb.AppendLine("End Enum"); } else { var partial = Config.MakePartial && !type.IsInterface() ? "Partial " : ""; var defType = type.IsInterface() ? "Interface" : "Class"; sb.AppendLine("Public {0}{1} {2}".Fmt(partial, defType, Type(type.Name, type.GenericArgs))); //: BaseClass, Interfaces if (type.Inherits != null) { sb.AppendLine($" Inherits {Type(type.Inherits, includeNested: true)}"); } var implements = new List <string>(); if (options.ImplementsFn != null) { var implStr = options.ImplementsFn(); if (!string.IsNullOrEmpty(implStr)) { implements.Add(implStr); } } type.Implements.Each(x => implements.Add(Type(x))); var makeExtensible = Config.MakeDataContractsExtensible && type.Inherits == null; if (makeExtensible) { implements.Add("IExtensibleDataObject"); } if (implements.Count > 0) { foreach (var x in implements) { sb.AppendLine($" Implements {x}"); } } 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(type.IsInterface() ? "End Interface" : "End Class"); } PostTypeFilter?.Invoke(sb, type); sb = sb.UnIndent(); return(lastNS); }
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); if (x.Response != null) { namespaces.Add(x.Response.Namespace); } }); } else { namespaces.Add(Config.GlobalNamespace); } string DefaultValue(string k) => request.QueryString[k].IsNullOrEmpty() ? "'''" : "'"; var sbInner = new StringBuilder(); 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}ExportValueTypes: {1}".Fmt(DefaultValue("ExportValueTypes"), Config.ExportValueTypes)); 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}AddNamespaces: {1}".Fmt(DefaultValue("AddNamespaces"), Config.AddNamespaces.Safe().ToArray().Join(","))); sb.AppendLine("{0}AddDefaultXmlNamespace: {1}".Fmt(DefaultValue("AddDefaultXmlNamespace"), Config.AddDefaultXmlNamespace)); sb.AppendLine(); namespaces.Where(x => !string.IsNullOrEmpty(x)) .Each(x => sb.AppendLine("Imports {0}".Fmt(x))); if (Config.AddGeneratedCodeAttributes) { sb.AppendLine("Imports 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(); sb.AppendLine("Namespace Global"); sb = sb.Indent(); 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 = new List <MetadataType>(); allTypes.AddRange(requestTypes); allTypes.AddRange(responseTypes); allTypes.AddRange(types); var orderedTypes = allTypes .OrderBy(x => x.Namespace) .ThenBy(x => x.Name) .ToList(); orderedTypes = FilterTypes(orderedTypes); foreach (var type in orderedTypes) { var fullTypeName = type.GetFullName(); if (requestTypes.Contains(type)) { if (!existingTypes.Contains(fullTypeName)) { MetadataType response = null; if (requestTypesMap.TryGetValue(type, out var 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("End Namespace"); } sb = sb.UnIndent(); sb.AppendLine("End Namespace"); sb.AppendLine(); return(StringBuilderCache.ReturnAndFree(sbInner)); }
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:Any) -> {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("}"); }
public string GetCode(MetadataTypes metadata, IRequest request, INativeTypesMetadata nativeTypes) { var typeNamespaces = new HashSet <string>(); var includeList = 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; string defaultValue(string 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.VersionString)); sb.AppendLine("Tip: {0}".Fmt(HelpMessages.NativeTypesDtoOptionsTip.Fmt("//"))); sb.AppendLine("BaseUrl: {0}".Fmt(Config.BaseUrl)); if (Config.UsePath != null) { sb.AppendLine("UsePath: {0}".Fmt(Config.UsePath)); } 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}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(); var types = metadata.Types.CreateSortedTypeList(); allTypes = metadata.GetAllTypesOrdered(); allTypes.RemoveAll(x => x.IgnoreType(Config, includeList)); 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); foreach (var import in defaultImports) { var pos = import.IndexOf(':'); sb.AppendLine(pos == -1 ? $"import {import};" : $"import {{ {import.Substring(0, pos)} }} from \"{import.Substring(pos + 1).StripQuotes()}\";"); } if (!string.IsNullOrEmpty(globalNamespace)) { var moduleDef = Config.ExportAsTypes ? "export " : "declare "; sb.AppendLine(); sb.AppendLine("{0}module {1}".Fmt(moduleDef, globalNamespace.SafeToken())); sb.AppendLine("{"); sb = sb.Indent(); } var insertCode = InsertCodeFilter?.Invoke(allTypes, Config); if (insertCode != null) { sb.AppendLine(insertCode); } //ServiceStack core interfaces foreach (var type in allTypes) { var fullTypeName = type.GetFullName(); if (requestTypes.Contains(type)) { if (!existingTypes.Contains(fullTypeName)) { MetadataType response = null; if (requestTypesMap.TryGetValue(type, out var operation)) { response = operation.Response; } lastNS = AppendType(ref sb, type, lastNS, new CreateTypeOptions { Routes = metadata.Operations.GetRoutes(type), ImplementsFn = () => { if (!Config.AddReturnMarker && operation?.ReturnsVoid != true && operation?.ReturnType == null) { return(null); } if (operation?.ReturnsVoid == true) { return(nameof(IReturnVoid)); } if (operation?.ReturnType != null) { return(Type("IReturn`1", new[] { Type(operation.ReturnType) })); } 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); } } var addCode = AddCodeFilter?.Invoke(allTypes, Config); if (addCode != null) { sb.AppendLine(addCode); } if (!string.IsNullOrEmpty(globalNamespace)) { sb = sb.UnIndent(); sb.AppendLine(); sb.AppendLine("}"); } sb.AppendLine(); //tslint return(StringBuilderCache.ReturnAndFree(sbInner)); }
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.GetTypeName(Config, allTypes), 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 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.LeftPart('`'), 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($"associatedtype {arg}"); } } } var extend = extends.Count > 0 ? " : " + (string.Join(", ", extends.ToArray())) : ""; sb.AppendLine($"public {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 {"Version".PropertyStyle()}:Int = {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); }
private string AppendType(ref StringBuilderWrapper sb, MetadataType type, string lastNS, CreateTypeOptions options) { if (type == null || (type.Namespace != null && type.Namespace.StartsWith("System"))) { return(lastNS); } if (type.Namespace != lastNS) { if (lastNS != null) { sb.AppendLine("}"); } lastNS = type.Namespace; sb.AppendLine(); sb.AppendLine("namespace {0}".Fmt(type.Namespace.SafeToken())); sb.AppendLine("{"); } sb = sb.Indent(); sb.AppendLine(); AppendComments(sb, type.Description); AppendDataContract(sb, type.DataContract); var partial = Config.MakePartial ? "partial " : ""; sb.AppendLine("public {0}class {1}".Fmt(partial, Type(type.Name, type.GenericArgs))); //: BaseClass, Interfaces var inheritsList = new List <string>(); if (type.Inherits != null) { inheritsList.Add(Type(type.Inherits, type.InheritsGenericArgs)); } if (options.ImplementsFn != null) { var implStr = options.ImplementsFn(); if (!string.IsNullOrEmpty(implStr)) { inheritsList.Add(implStr); } } 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); 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); PreTypeFilter?.Invoke(sb, type); if (type.IsEnum.GetValueOrDefault()) { var enumType = Type(type.Name, type.GenericArgs); RegisterType(type, enumType); var isIntEnum = type.IsEnumInt.GetValueOrDefault() || type.EnumNames.IsEmpty(); if (!isIntEnum) { sb.AppendLine($"enum {enumType}"); sb.AppendLine("{"); sb = sb.Indent(); foreach (var name in type.EnumNames.Safe()) { sb.AppendLine($"{name},"); } sb = sb.UnIndent(); sb.AppendLine("}"); } else { sb.AppendLine($"class {enumType}"); 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?[i]; sb.AppendLine($"static const {enumType} {name} = const {enumType}._({value});"); } } sb.AppendLine(); sb.AppendLine("final int _value;"); sb.AppendLine($"const {enumType}._(this._value);"); sb.AppendLine($"int get value => _value;"); var enumNames = (type.EnumNames ?? TypeConstants.EmptyStringList).Join(","); sb.AppendLine($"static List<{enumType}> get values => const [{enumNames}];"); sb = sb.UnIndent(); sb.AppendLine("}"); } } 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 = "dynamic"; } // This is to avoid invalid syntax such as "return new string()" responseTypeExpression = defaultValues.TryGetValue(returnType, out var newReturnInstance) ? $"createResponse() {{ return {newReturnInstance}; }}" : $"createResponse() {{ return new {returnType}(); }}"; } else if (implStr == "IReturnVoid") { responseTypeExpression = "createResponse() {}"; } } type.Implements.Each(x => interfaces.Add(Type(x))); var isClass = type.IsInterface != true; var isAbstractClass = type.IsInterface == true || type.IsAbstract == true; var baseClass = extends.Count > 0 ? extends[0] : null; var hasDtoBaseClass = baseClass != null; var hasListBase = baseClass != null && baseClass.StartsWith("List<"); if (hasListBase) { baseClass = "ListBase" + baseClass.Substring(4); hasDtoBaseClass = false; } if (!isAbstractClass) { interfaces.Add("IConvertible"); } var extend = baseClass != null ? " extends " + baseClass : ""; 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 = !isAbstractClass ? "class" : "abstract class"; var typeName = Type(type.Name, type.GenericArgs); RegisterType(type, typeName); sb.AppendLine($"{typeDeclaration} {typeName}{extend}"); sb.AppendLine("{"); sb = sb.Indent(); var addVersionInfo = Config.AddImplicitVersion != null && options.IsRequest && !isAbstractClass; if (addVersionInfo) { sb.AppendLine($"int {"Version".PropertyStyle()};"); } if (type.Name == "IReturn`1") { sb.AppendLine("T createResponse();"); sb.AppendLine("String getTypeName();"); } else if (type.Name == "IReturnVoid") { sb.AppendLine("void createResponse();"); sb.AppendLine("String getTypeName();"); } AddProperties(sb, type, includeResponseStatus: Config.AddResponseStatus && options.IsResponse && type.Properties.Safe().All(x => x.Name != typeof(ResponseStatus).Name)); if (isClass) { var typeNameWithoutGenericArgs = typeName.LeftPart('<'); var props = (type.Properties ?? TypeConstants <MetadataPropertyType> .EmptyList).ToList(); if (addVersionInfo) { props.Insert(0, new MetadataPropertyType { Name = "Version".PropertyStyle(), Type = "Int32", TypeNamespace = "System", IsValueType = true, Value = Config.AddImplicitVersion.ToString() }); } if (props.Count > 0) { sb.AppendLine(); } if (hasListBase) { var genericArg = baseClass.Substring(9, baseClass.Length - 10); sb.AppendLine($"final List<{genericArg}> l = [];"); sb.AppendLine("void set length(int newLength) { l.length = newLength; }"); sb.AppendLine("int get length => l.length;"); sb.AppendLine($"{genericArg} operator [](int index) => l[index];"); sb.AppendLine($"void operator []=(int index, {genericArg} value) {{ l[index] = value; }}"); } var sbBody = StringBuilderCacheAlt.Allocate(); if (props.Count > 0) { foreach (var prop in props) { if (sbBody.Length == 0) { sbBody.Append(typeNameWithoutGenericArgs + "({"); } else { sbBody.Append(","); } sbBody.Append($"this.{prop.Name.PropertyStyle().PropertyName()}"); if (!string.IsNullOrEmpty(prop.Value)) { sbBody.Append("=" + prop.Value); } } if (sbBody.Length > 0) { sb.AppendLine(StringBuilderCacheAlt.ReturnAndFree(sbBody) + "});"); } } else { sb.AppendLine(typeNameWithoutGenericArgs + "();"); } if (props.Count > 0) { sbBody = StringBuilderCacheAlt.Allocate(); sbBody.Append(typeNameWithoutGenericArgs + ".fromJson(Map<String, dynamic> json)"); sbBody.Append(" { fromMap(json); }"); sb.AppendLine(StringBuilderCacheAlt.ReturnAndFree(sbBody)); sb.AppendLine(); } else { sb.AppendLine(typeNameWithoutGenericArgs + ".fromJson(Map<String, dynamic> json) : " + (hasDtoBaseClass ? "super.fromJson(json);" : "super();")); } sbBody = StringBuilderCacheAlt.Allocate(); sbBody.AppendLine("fromMap(Map<String, dynamic> json) {"); if (hasDtoBaseClass) { sbBody.AppendLine(" super.fromMap(json);"); } foreach (var prop in props) { var propType = DartPropertyType(prop); var jsonName = prop.Name.PropertyStyle(); var propName = jsonName.PropertyName(); if (UseTypeConversion(prop)) { bool registerType = true; if (type.GenericArgs?.Length > 0 && prop.GenericArgs?.Length > 0) { var argIndexes = new List <int>(); foreach (var arg in prop.GenericArgs) { var argIndex = Array.IndexOf(type.GenericArgs, arg); argIndexes.Add(argIndex); } if (argIndexes.All(x => x != -1)) { propType = prop.Type.LeftPart('`') + "<${runtimeGenericTypeDefs(this,[" + argIndexes.Join(",") + "]).join(\",\")}>"; registerType = false; } } if (registerType) { RegisterPropertyType(prop, propType); } sbBody.AppendLine($" {propName} = JsonConverters.fromJson(json['{jsonName}'],'{propType}',context);"); } else { if (DartToJsonConverters.TryGetValue(propType, out var conversionFn)) { sbBody.AppendLine($" {propName} = JsonConverters.{conversionFn}(json['{jsonName}']);"); } else { sbBody.AppendLine($" {propName} = json['{jsonName}'];"); } } } sbBody.AppendLine(" return this;"); sbBody.AppendLine(" }"); sb.AppendLine(StringBuilderCacheAlt.ReturnAndFree(sbBody)); sbBody = StringBuilderCacheAlt.Allocate(); if (props.Count > 0) { foreach (var prop in props) { if (sbBody.Length == 0) { sbBody.Append("Map<String, dynamic> toJson() => "); if (hasDtoBaseClass) { sbBody.Append("super.toJson()..addAll("); } sbBody.AppendLine("{"); } else { sbBody.AppendLine(","); } var propType = DartPropertyType(prop); var jsonName = prop.Name.PropertyStyle(); var propName = jsonName.PropertyName(); if (UseTypeConversion(prop)) { sbBody.Append($" '{jsonName}': JsonConverters.toJson({propName},'{propType}',context)"); } else { sbBody.Append($" '{jsonName}': {propName}"); } } if (sbBody.Length > 0) { sb.AppendLine(StringBuilderCacheAlt.ReturnAndFree(sbBody)); sb.AppendLine(hasDtoBaseClass ? "});" : "};"); sb.AppendLine(); } } else { sb.AppendLine("Map<String, dynamic> toJson() => " + (hasDtoBaseClass ? "super.toJson();" : "{};")); } if (responseTypeExpression != null) { sb.AppendLine(responseTypeExpression); sb.AppendLine($"String getTypeName() {{ return \"{type.Name}\"; }}"); } if (isClass) { sb.AppendLine("TypeContext context = _ctx;"); } } sb = sb.UnIndent(); sb.AppendLine("}"); } PostTypeFilter?.Invoke(sb, type); return(lastNS); }
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("End Namespace"); } lastNS = ns; sb.AppendLine(); sb.AppendLine($"Namespace {MetadataExtensions.SafeToken(ns)}"); //sb.AppendLine("{"); } sb = sb.Indent(); sb.AppendLine(); AppendComments(sb, type.Description); if (options?.Routes != null) { AppendAttributes(sb, options.Routes.ConvertAll(x => x.ToMetadataAttribute())); } AppendAttributes(sb, type.Attributes); AppendDataContract(sb, type.DataContract); if (Config.AddGeneratedCodeAttributes) { sb.AppendLine($"<GeneratedCode(\"AddServiceStackReference\", \"{Env.VersionString}\")>"); } sb.Emit(type, Lang.Vb); PreTypeFilter?.Invoke(sb, type); if (type.IsEnum.GetValueOrDefault()) { sb.AppendLine("Public Enum {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?[i]; if (KeyWords.Contains(name)) { name = $"[{name}]"; } var memberValue = type.GetEnumMemberValue(i); if (memberValue != null) { AppendAttributes(sb, new List <MetadataAttribute> { new MetadataAttribute { Name = "EnumMember", Args = new List <MetadataPropertyType> { new() { Name = "Value", Value = memberValue, Type = "String", } } } });
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); }
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); PreTypeFilter?.Invoke(sb, type); if (type.IsEnum.GetValueOrDefault()) { var isIntEnum = type.IsEnumInt.GetValueOrDefault() || type.EnumNames.IsEmpty(); if ((isIntEnum || !UseUnionTypeEnums) && Config.ExportAsTypes) { var typeDeclaration = !Config.ExportAsTypes ? "enum" : "export enum"; sb.AppendLine($"{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?[i]; if (type.EnumMemberValues != null && type.EnumMemberValues[i] != name) { value = $"'{type.EnumMemberValues[i]}'"; } sb.AppendLine(value == null ? $"{name} = '{name}'," : $"{name} = {value},"); } } sb = sb.UnIndent(); sb.AppendLine("}"); } else { var sbType = StringBuilderCache.Allocate(); var typeDeclaration = !Config.ExportAsTypes ? "type" : "export type"; sbType.Append($"{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(DeclarationType(type.Inherits.Name, type.Inherits.GenericArgs, out var addDeclaration)); if (addDeclaration != null && !AddedDeclarations.Contains(addDeclaration)) { AddedDeclarations.Add(addDeclaration); sb.AppendLine(addDeclaration); sb.AppendLine(); } } string responseTypeExpression = null; var interfaces = new List <string>(); var implStr = options.ImplementsFn?.Invoke(); if (!string.IsNullOrEmpty(implStr)) { interfaces.Add(implStr); if (Config.ExportAsTypes) { if (implStr.StartsWith("IReturn<")) { var types = implStr.RightPart('<'); var returnType = types.Substring(0, types.Length - 1); // This is to avoid invalid syntax such as "return new string()" primitiveDefaultValues.TryGetValue(returnType, out var replaceReturnType); if (returnType == "any") { replaceReturnType = "{}"; } else if (returnType.EndsWith("[]")) { replaceReturnType = $"new Array<{returnType.Substring(0, returnType.Length -2)}>()"; } responseTypeExpression = replaceReturnType == null ? "public createResponse() {{ return new {0}(); }}".Fmt(returnType) : "public createResponse() {{ return {0}; }}".Fmt(replaceReturnType); } else if (implStr == "IReturnVoid") { responseTypeExpression = "public createResponse() {}"; } } } type.Implements.Each(x => interfaces.Add(Type(x))); var isClass = Config.ExportAsTypes && !type.IsInterface.GetValueOrDefault(); var modifier = isClass ? "public " : ""; 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")}"; var typeName = Type(type.Name, type.GenericArgs); sb.AppendLine($"{typeDeclaration} {typeName}{extend}"); sb.AppendLine("{"); sb = sb.Indent(); var addVersionInfo = Config.AddImplicitVersion != null && options.IsRequest; if (addVersionInfo) { sb.AppendLine(modifier + "{0}{1}: number; //{2}".Fmt( "Version".PropertyStyle(), isClass ? "" : "?", Config.AddImplicitVersion)); } if (Config.ExportAsTypes) { if (type.Name == "IReturn`1") { sb.AppendLine("createResponse(): T;"); } else if (type.Name == "IReturnVoid") { sb.AppendLine("createResponse(): void;"); } } AddProperties(sb, type, includeResponseStatus: Config.AddResponseStatus && options.IsResponse && type.Properties.Safe().All(x => x.Name != typeof(ResponseStatus).Name)); if (EmitPartialConstructors && Config.ExportAsTypes && isClass) { sb.AppendLine(); var callSuper = type.Inherits != null ? !(extend.StartsWith(" extends Array<") || extend.StartsWith(" extends Dictionary<")) ? "super(init); " : "super(); " : ""; sb.AppendLine($"public constructor(init?: Partial<{typeName}>) {{ {callSuper}(Object as any).assign(this, init); }}"); } if (Config.ExportAsTypes && responseTypeExpression != null) { sb.AppendLine(responseTypeExpression); sb.AppendLine("public getTypeName() {{ return '{0}'; }}".Fmt(type.Name)); } sb = sb.UnIndent(); sb.AppendLine("}"); } PostTypeFilter?.Invoke(sb, type); return(lastNS); }
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("End Namespace"); } 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 (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("End Enum"); } else { var partial = Config.MakePartial && !type.IsInterface() ? "Partial " : ""; var defType = type.IsInterface() ? "Interface" : "Class"; sb.AppendLine("Public {0}{1} {2}".Fmt(partial, defType, Type(type.Name, type.GenericArgs))); //: BaseClass, Interfaces if (type.Inherits != null) { sb.AppendLine(" Inherits {0}".Fmt(Type(type.Inherits, includeNested: true))); } var implements = new List <string>(); if (options.ImplementsFn != null) { var implStr = options.ImplementsFn(); if (!string.IsNullOrEmpty(implStr)) { implements.Add(implStr); } } var makeExtensible = Config.MakeDataContractsExtensible && type.Inherits == null; if (makeExtensible) { implements.Add("IExtensibleDataObject"); } if (implements.Count > 0) { foreach (var x in implements) { sb.AppendLine(" Implements {0}".Fmt(x)); } } //sb.AppendLine("{"); sb = sb.Indent(); AddConstuctor(sb, type, options); AddProperties(sb, type); 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(type.IsInterface() ? "End Interface" : "End Class"); } sb = sb.UnIndent(); return(lastNS); }
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.IsOperation; if (addVersionInfo) { sb.AppendLine("{0}: number; //{1}".Fmt("Version".PropertyStyle(), Config.AddImplicitVersion)); } AddProperties(sb, type); 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); var typeName = Type(type.Name, type.GenericArgs); if (type.IsEnum.GetValueOrDefault()) { var hasIntValue = type.EnumNames.Count == (type.EnumValues?.Count ?? 0); var enumConstructor = hasIntValue ? "(val value:Int)" : ""; sb.AppendLine($"enum class {typeName}{enumConstructor}"); 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 = hasIntValue ? type.EnumValues[i] : null; var serializeAs = JsConfig.TreatEnumAsInteger || type.Attributes.Safe().Any(x => x.Name == "Flags") ? $"@SerializedName(\"{value}\") " : ""; sb.AppendLine(value == null ? $"{name.ToPascalCase()}," : serializeAs + $"{name.ToPascalCase()}({value}),"); } //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("<") ? $"object : TypeToken<{returnType}>(){{}}.type" : $"{returnType}::class.java"; } } if (!type.Implements.IsEmpty()) { foreach (var interfaceRef in type.Implements) { interfaces.Add(Type(interfaceRef)); } } } var extend = extends.Count > 0 ? " : " + extends[0] + "()" : ""; if (interfaces.Count > 0) { extend += (extend.IsNullOrEmpty() ? " : " : ", ") + string.Join(", ", interfaces.ToArray()); } sb.AppendLine($"open {defType} {typeName}{extend}"); sb.AppendLine("{"); sb = sb.Indent(); var addVersionInfo = Config.AddImplicitVersion != null && options.IsRequest; if (addVersionInfo) { sb.AppendLine($"val {"Version".PropertyStyle()}:Int = {Config.AddImplicitVersion}"); } var initCollections = feature.ShouldInitializeCollections(type, Config.InitializeCollections); AddProperties(sb, type, initCollections: !type.IsInterface() && initCollections, includeResponseStatus: Config.AddResponseStatus && options.IsResponse && type.Properties.Safe().All(x => x.Name != typeof(ResponseStatus).Name)); if (responseTypeExpression != null) { sb.AppendLine($"companion object {{ private val responseType = {responseTypeExpression} }}"); sb.AppendLine($"override fun getResponseType(): Any? = {typeName}.responseType"); } sb = sb.UnIndent(); sb.AppendLine("}"); } return(lastNS); }
private string AppendType(ref StringBuilderWrapper sb, MetadataType type, string lastNS, List <MetadataType> allTypes, CreateTypeOptions options) { if (type.IsNested.GetValueOrDefault() && !options.IsNestedType) { return(lastNS); } if (!Config.ExcludeNamespace) { var ns = Config.GlobalNamespace ?? type.Namespace; if (ns != lastNS) { if (lastNS != null) { sb.AppendLine("}"); } lastNS = ns; sb.AppendLine(); sb.AppendLine($"namespace {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\", \"{Env.VersionString}\")]"); } var typeAccessor = !Config.MakeInternal ? "public" : "internal"; PreTypeFilter?.Invoke(sb, type); if (type.IsEnum.GetValueOrDefault()) { sb.AppendLine($"{typeAccessor} enum {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?[i]; var memberValue = type.GetEnumMemberValue(i); if (memberValue != null) { AppendAttributes(sb, new List <MetadataAttribute> { new MetadataAttribute { Name = "EnumMember", Args = new List <MetadataPropertyType> { new MetadataPropertyType { Name = "Value", Value = memberValue, Type = "String", } } } }); } sb.AppendLine(value == null ? $"{name}," : $"{name} = {value},"); } } sb = sb.UnIndent(); sb.AppendLine("}"); } else { var partial = Config.MakePartial ? "partial " : ""; var defType = type.IsInterface() ? "interface" : "class"; sb.AppendLine($"{typeAccessor} {partial}{defType} {Type(type.Name, type.GenericArgs)}"); //: BaseClass, Interfaces var inheritsList = new List <string>(); if (type.Inherits != null) { inheritsList.Add(Type(type.GetInherits(), includeNested: true)); } if (options.ImplementsFn != null) { var implStr = options.ImplementsFn(); if (!string.IsNullOrEmpty(implStr)) { inheritsList.Add(implStr); } } 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($" : {string.Join(", ", inheritsList.ToArray())}"); } sb.AppendLine("{"); sb = sb.Indent(); AddConstructor(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("}"); } PostTypeFilter?.Invoke(sb, type); if (!Config.ExcludeNamespace) { sb = sb.UnIndent(); } return(lastNS); }
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()) { var typeDeclaration = !Config.ExportAsTypes ? "enum" : "export const 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 ? "{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).InDeclarationType()); } var interfaces = new List <string>(); if (options.ImplementsFn != null) { var implStr = options.ImplementsFn(); if (!string.IsNullOrEmpty(implStr)) { interfaces.Add(implStr); } } 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 {0}".Fmt(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)); sb = sb.UnIndent(); sb.AppendLine("}"); } sb = sb.UnIndent(); return(lastNS); }
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); }
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, 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 (Config.AddGeneratedCodeAttributes) { sb.AppendLine("[<GeneratedCode(\"AddServiceStackReference\", \"{0}\")>]".Fmt(Env.VersionString)); } 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 var classCtor = type.IsInterface() ? "" : "()"; sb.AppendLine("[<AllowNullLiteral>]"); sb.AppendLine("type {0}{1} = ".Fmt(Type(type.Name, type.GenericArgs), classCtor)); 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 {implStr}"); } } if (!type.IsInterface()) { 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.IsRequest; if (addVersionInfo) { sb.AppendLine("member val Version:int = {0} with get, set".Fmt(Config.AddImplicitVersion)); } } AddProperties(sb, type, includeResponseStatus: Config.AddResponseStatus && options.IsResponse && type.Properties.Safe().All(x => x.Name != typeof(ResponseStatus).Name)); if (sb.Length == startLen) { sb.AppendLine(type.IsInterface() ? "interface end" : "class end"); } sb = sb.UnIndent(); } 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($"{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?[i]; sb.AppendLine(value == null //Enum Value's are not impacted by JS Style ? $"{name}," : $"{name} = {value},"); } } sb = sb.UnIndent(); sb.AppendLine("}"); } else { var sbType = StringBuilderCache.Allocate(); var typeDeclaration = !Config.ExportAsTypes ? "type" : "export type"; sbType.Append($"{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 (Config.ExportAsTypes) { 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() {}"; } } type.Implements.Each(x => interfaces.Add(Type(x))); } 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)); } if (Config.ExportAsTypes) { if (type.Name == "IReturn`1") { sb.AppendLine("createResponse() : T;"); } else if (type.Name == "IReturnVoid") { sb.AppendLine("createResponse() : void;"); } } 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); }
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() sbExt.AppendLine("public static func reflect() -> Type<{0}> {{".Fmt(typeName)); sbExt = sbExt.Indent(); sbExt.AppendLine( "return TypeConfig.config() ?? TypeConfig.configure(Type<{0}>(".Fmt(typeName)); sbExt = sbExt.Indent(); sbExt.AppendLine("properties: [".Fmt(typeName)); 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"; } } sbExt.AppendLine("Type<{0}>.{1}(\"{2}\", get: {{ $0.{2} }}, set: {{ $0.{2} = $1 }}),".Fmt( typeName, fnName, prop.Name.SafeToken().PropertyStyle())); } sbExt = sbExt.UnIndent(); sbExt.AppendLine("]))"); sbExt = sbExt.UnIndent(); sbExt = sbExt.UnIndent(); sbExt.AppendLine("}"); //toJson() sbExt.AppendLine("public func toJson() -> String {"); sbExt = sbExt.Indent(); sbExt.AppendLine("return {0}.reflect().toJson(self)".Fmt(typeName)); sbExt = sbExt.UnIndent(); sbExt.AppendLine("}"); //fromJson() sbExt.AppendLine("public static func fromJson(json:String) -> {0}? {{".Fmt(typeName)); sbExt = sbExt.Indent(); sbExt.AppendLine("return {0}.reflect().fromJson({0}(), json: json)".Fmt(typeName)); sbExt = sbExt.UnIndent(); sbExt.AppendLine("}"); //fromObject() sbExt.AppendLine("public static func fromObject(any:AnyObject) -> {0}? {{".Fmt(typeName)); sbExt = sbExt.Indent(); sbExt.AppendLine("return {0}.reflect().fromObject({0}(), any:any)".Fmt(typeName)); sbExt = sbExt.UnIndent(); sbExt.AppendLine("}"); //toString() sbExt.AppendLine("public func toString() -> String {"); sbExt = sbExt.Indent(); sbExt.AppendLine("return {0}.reflect().toString(self)".Fmt(typeName)); sbExt = sbExt.UnIndent(); sbExt.AppendLine("}"); //fromString() sbExt.AppendLine("public static func fromString(string:String) -> {0}? {{".Fmt(typeName)); sbExt = sbExt.Indent(); sbExt.AppendLine("return {0}.reflect().fromString({0}(), string: string)".Fmt(typeName)); sbExt = sbExt.UnIndent(); sbExt.AppendLine("}"); sbExt = sbExt.UnIndent(); sbExt.AppendLine("}"); }
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); typeName = typeName.LeftPart('<'); // Type<QueryResponse<T>> into correct mapping Type<QueryResponse> var typeNameOnly = typeName.LeftPart('<'); 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?.Length > 0 || type.Inherits?.GenericArgs?.Length > 0; 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 string GetCode(MetadataTypes metadata, IRequest request) { metadata.RemoveIgnoredTypesForNet(Config); string defaultValue(string 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.VersionString)); 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"), Config.GlobalNamespace)); 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("*/"); sb.AppendLine(); var methods = grpc.GrpcServicesType.GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(x => x.GetParameters().Length > 0) .OrderBy(x => x.GetParameters()[0].ParameterType.Name); var types = new HashSet <Type>(); var services = new List <(Type, string)>(); foreach (var method in methods) { if (!method.ReturnType.IsGenericType || method.ReturnType.DeclaringType == typeof(object)) { continue; } var resGenericDef = method.ReturnType.GetGenericTypeDefinition(); var isTask = resGenericDef == typeof(Task <>) || resGenericDef == typeof(ValueTask <>); var isStream = resGenericDef == typeof(IAsyncEnumerable <>); if (isTask || isStream) { var reqType = method.GetParameters()[0].ParameterType; var resType = method.ReturnType.GetGenericArguments()[0]; ServiceMetadata.AddReferencedTypes(types, reqType); ServiceMetadata.AddReferencedTypes(types, resType); if (isTask) { services.Add((reqType, $"rpc {method.Name}({reqType.Name}) returns ({resType.Name}) {{}}")); } else { services.Add((reqType, $"rpc {method.Name}({reqType.Name}) returns (stream {resType.Name}) {{}}")); } } } var orderedTypes = types.ToList() .OrderBy(x => x.Namespace) .ThenBy(x => x.Name) .ToList(); var addedRpcServices = false; //https://github.com/protobuf-net/protobuf-net/blob/master/src/Tools/bcl.proto var proto = GrpcUtils.TypeModel.GetSchema(null /*all types*/, ProtoSyntax.Proto3); foreach (var line in proto.ReadLines()) { if (line.StartsWith("package ")) // strip { continue; } sb.AppendLine(line); if (!addedRpcServices && string.IsNullOrEmpty(line)) { addedRpcServices = true; var globalNs = Config.GlobalNamespace ?? DefaultNamespace(orderedTypes); //package name changes Service Name from /GrpcServices to /package_name.GrpcServices //sb.AppendLine($"package {Config.Package ?? ResolvePackageName(globalNs.Replace(".","_").ToLowercaseUnderscore().Replace("__","_"))};"); sb.AppendLine($"option csharp_namespace = \"{globalNs}\";"); sb.AppendLine(); sb.AppendLine($"service {grpc.GrpcServicesType.Name} {{"); sb = sb.Indent(); foreach (var service in services) { sb.AppendLine(); if (Config.AddDescriptionAsComments) { var desc = service.Item1.FirstAttribute <DescriptionAttribute>()?.Description ?? service.Item1.FirstAttribute <System.ComponentModel.DescriptionAttribute>()?.Description; if (desc != null) { foreach (var lineDesc in desc.ReadLines()) { sb.AppendLine("// " + lineDesc); } } } sb.AppendLine(service.Item2); } sb = sb.UnIndent(); sb.AppendLine("}"); sb.AppendLine(); } } return(StringBuilderCache.ReturnAndFree(sbInner)); }
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); 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.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)); }
private string AppendType(ref StringBuilderWrapper sb, ref StringBuilderWrapper sbExt, 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("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); } 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); } 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("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()) { sb.AppendLine("required public init(){}"); } var addVersionInfo = Config.AddImplicitVersion != null && options.IsOperation; if (addVersionInfo) { sb.AppendLine("public var {0}:Int = {1}".Fmt("Version".PropertyStyle(), Config.AddImplicitVersion)); } AddProperties(sb, type, initCollections: !type.IsInterface() && Config.InitializeCollections); sb = sb.UnIndent(); sb.AppendLine("}"); if (!type.IsInterface()) { AddTypeExtension(ref sbExt, type, initCollections: Config.InitializeCollections); } } //sb = sb.UnIndent(); return(lastNS); }