private void WriteClassDtoInterfaceTransfomMethods(SourceWriter writer, DtoInterfaceTransformLookup interfaceTransformLookup) { foreach (var(dtoInterfaceSymbol, dtoInterfaceMetadata) in interfaceTransformLookup) { writer.WriteLine(); writer.Write($"private static {dtoInterfaceMetadata.TransformMethodName}(dto: {dtoInterfaceSymbol.Name}): {dtoInterfaceMetadata.ClassSymbol.Name} "); using (writer.Block()) { var interfaceParameters = GetConstructorParameters(GetAllDistinctProperties(dtoInterfaceMetadata.ClassSymbol)) .Select(x => new { x.property, requiresDtoTransform = x.property.Type.RequiresDtoTransform(), x.parameterName }) .Apply(); if (interfaceParameters.Any(p => p.requiresDtoTransform)) { foreach (var parameter in interfaceParameters.Where(p => p.requiresDtoTransform)) { TsDtoTypeSymbolHelper.WriteSymbolDtoTransformation( propertySymbol: parameter.property, valueAccessor: $"dto.{parameter.property.Name}", variableName: parameter.parameterName, interfaceTransformLookup: interfaceTransformLookup, writer); } writer.WriteLine(); } IReadOnlyList <string> interfaceInitialization = interfaceParameters .Select(p => $"{p.property.Name}: {(p.requiresDtoTransform ? p.parameterName : $"dto.{p.property.Name}")}")
private void WriteClassDtoTransformMethod(SourceWriter writer, TsTypeSymbol symbol) { //InterfaceTransformLookup interfaceTransformLookup = this.BuildInterfaceTransformLookup(symbol); DtoInterfaceTransformLookup interfaceTransformLookup = DtoInterfaceTransformLookup.BuildLookup(symbol); writer.WriteLine(); TsTypeSymbol dtoInterface = symbol.DtoInterface; writer.Write($"public static fromDto(dto: {dtoInterface.Name}): {symbol.Name} "); using (writer.Block()) { var rawClassParameters = GetConstructorParameters(GetAllDistinctProperties(symbol)) .Select(cp => new { cp.property, cp.parameterName, requiresTransform = cp.property.Type.RequiresDtoTransform() }) .Apply(); if (rawClassParameters.Any(x => x.requiresTransform)) { foreach (var parameter in rawClassParameters.Where(x => x.requiresTransform)) { TsDtoTypeSymbolHelper.WriteSymbolDtoTransformation( propertySymbol: parameter.property, valueAccessor: $"dto.{parameter.property.Name}", variableName: parameter.parameterName, interfaceTransformLookup: interfaceTransformLookup, writer); } writer.WriteLine(); } // Write out the class constructor. var classParameters = rawClassParameters.Select(p => p.requiresTransform ? p.parameterName : "dto." + p.parameterName) .Apply(); writer.Write($"return new {symbol.Name}("); this.WriteCommaSeparatedItems(writer, classParameters); writer.WriteLine(");"); } // Write interface transform methods, if any. if (interfaceTransformLookup.Count > 0) { this.WriteClassDtoInterfaceTransfomMethods(writer, interfaceTransformLookup); } }
/// <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}."); } }
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); } } }