private void WriteClass(SourceWriter writer, TsTypeSymbol symbol) { writer.Write("export "); if (symbol.IsAbstractClass) { writer.Write("abstract "); } writer.Write("class ").Write(symbol.Name); if (symbol.Base != null) { writer.Write(" extends ").Write(symbol.Base.Name); } if (symbol.Interfaces?.Any() ?? false) { writer .Write(" implements ") .Write(string.Join(", ", symbol.Interfaces.Select(i => i.Name))); } writer.Write(" "); using (writer.Block()) { // Write the properties. foreach (TsPropertySymbol property in symbol.Properties) { writer.Write("public "); if (property.IsReadOnly) { writer.Write("readonly "); } writer.Write(property.Name); if (property.IsOptional) { writer.Write("?"); } writer.Write(": ").Write(GetPropertyTypeIdentifier(property)); writer.WriteLine(";"); } if (symbol.Properties.Count > 0) { writer.WriteLine(); } // Write the constructor. var baseProperties = symbol.Base?.Properties ?? Enumerable.Empty <TsPropertySymbol>(); var basePropertyInfos = GetConstructorParameters(baseProperties).Apply(); var propertyInfos = GetConstructorParameters(symbol.Properties).Apply(); var parameterInfos = GetConstructorParameters(baseProperties.Concat(symbol.Properties)).Apply(); IReadOnlyList <string> parameters = parameterInfos .Select(p => $"{p.parameterName}{(p.property.IsOptional ? "?" : string.Empty)}: {GetPropertyTypeIdentifier(p.property)}") .Apply(); if (parameters.Count > 0) { writer.Write("constructor("); this.WriteCommaSeparatedItems(writer, parameters); writer.Write(") "); using (writer.Block()) { if (symbol.Base != null) { // Make call to super(...). writer.Write("super("); this.WriteCommaSeparatedItems(writer, basePropertyInfos.Select(p => p.parameterName).Apply()); writer.WriteLine(");"); if (propertyInfos.Any()) { writer.WriteLine(); } } foreach (var(property, parameterName) in propertyInfos) { writer.WriteLine($"this.{property.Name} = {parameterName};"); } } } // Write the Dto creater if necessary bool writeDtoMethod = symbol.IsClass && !symbol.IsAbstractClass && symbol.HasDtoInterface; if (writeDtoMethod) { this.WriteClassDtoTransformMethod(writer, symbol); } } }
/// <summary> /// Writes the symbol dto transformation. /// </summary> /// <param name="propertySymbol">The property symbol.</param> /// <param name="valueAccessor">The value accessor.</param> /// <param name="variableName">The name of the variable to write.</param> /// <param name="interfaceTransformLookup">The interface transform lookup.</param> /// <param name="writer">The writer.</param> /// <exception cref="InvalidOperationException">The specified type does not require DTO transformation: {type.Name}</exception> /// <exception cref="NotSupportedException">Unable to write transformation for the specified type: {type.Name}</exception> public static void WriteSymbolDtoTransformation(TsPropertySymbol propertySymbol, string valueAccessor, string variableName, DtoInterfaceTransformLookup interfaceTransformLookup, SourceWriter writer) { if (!RequiresDtoTransform(propertySymbol.Type)) { throw new InvalidOperationException($"The specified type does not require DTO transformation: {propertySymbol.Type.Name}."); } bool isArray = propertySymbol.Type.IsArray; bool isOptional = propertySymbol.IsOptional; TsTypeSymbol type = propertySymbol.Type.UnwrapArray(); writer.Write($"const {variableName} = "); if (isOptional) { writer.Write($"{valueAccessor} === {TsTypeSymbol.Undefined.Name} ? {TsTypeSymbol.Undefined.Name} : "); } if (type.IsInterface && type.HasDtoInterface) { DtoInterfaceTransformMetadata dtoInterfaceMetadata = interfaceTransformLookup[type.DtoInterface]; if (isArray) { writer.WriteLine($"{valueAccessor}.map({dtoInterfaceMetadata.TransformMethodAccessor});"); } else { writer.WriteLine($"{dtoInterfaceMetadata.TransformMethodAccessor}({valueAccessor});"); } } else if (type.IsClass && type.HasDtoInterface) { if (isArray) { writer.WriteLine($"{valueAccessor}.map({type.Name}.fromDto);"); } else { writer.WriteLine($"{type.Name}.fromDto({valueAccessor});"); } } else if (type == TsTypeSymbol.Date) { if (isArray) { writer.WriteLine($"{valueAccessor}.map(s => new Date(s));"); } else { writer.WriteLine($"new Date({valueAccessor});"); } } else { throw new NotSupportedException($"Unable to write transformation for the specified type: {type.Name}."); } }