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;
}