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}")}")
/// <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 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> /// Builds a <see cref="DtoInterfaceTransformLookup"/> from the class symbol. /// </summary> /// <param name="classSymbol">The class symbol.</param> /// <returns>TsDtoInterfaceTransformLookup.</returns> public static DtoInterfaceTransformLookup BuildLookup(TsTypeSymbol classSymbol) { if (classSymbol == null) { throw new ArgumentNullException(nameof(classSymbol)); } if (!classSymbol.IsClass) { throw new ArgumentException("The symbol must be a class.", nameof(classSymbol)); } if (classSymbol.IsAbstractClass) { throw new ArgumentException("The symbol must not be an abstract class.", nameof(classSymbol)); } TsDirectDependencyTypeSymbolVisitor dependencyVisitor = new TsDirectDependencyTypeSymbolVisitor(); DtoInterfaceTransformLookup lookup = new DtoInterfaceTransformLookup(); foreach (TsPropertySymbol propertySymbol in classSymbol.Properties) { TsTypeSymbol unwrappedTypeSymbol = propertySymbol.Type.UnwrapArray(); if (DtoInterfaceTransformLookup.NeedsInterfaceTransform(unwrappedTypeSymbol)) { lookup.Add(classSymbol, unwrappedTypeSymbol); } foreach (TsTypeSymbol ptdSymbol in dependencyVisitor.GetDependencies(unwrappedTypeSymbol) .Where(DtoInterfaceTransformLookup.NeedsInterfaceTransform)) { lookup.Add(classSymbol, ptdSymbol); } } return(lookup); }