public static IEnumerable <ExpressionSyntax> MapUsingSimpleAssignment(SyntaxGenerator generator, SemanticModel semanticModel, IEnumerable <IPropertySymbol> targets, IMappingSourceFinder sourceFinder, MappingPath mappingPath = null, SyntaxNode globalTargetAccessor = null) { if (mappingPath == null) { mappingPath = new MappingPath(); } var mappingEngine = new MappingEngine(semanticModel, generator); return(targets.Select(property => new { source = sourceFinder.FindMappingSource(property.Name, property.Type), target = new MappingElement() { Expression = (ExpressionSyntax)CreateAccessPropertyExpression(globalTargetAccessor, property, generator), ExpressionType = property.Type } }) .Where(x => x.source != null) .Select(pair => { var sourceExpression = mappingEngine.MapExpression(pair.source, pair.target.ExpressionType, mappingPath.Clone()).Expression; return (ExpressionSyntax)generator.AssignmentStatement(pair.target.Expression, sourceExpression); }).ToList()); }
private static async Task <Document> CreateMappingLambda(Document document, InvocationExpressionSyntax invocation, CancellationToken cancellationToken) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken); var syntaxGenerator = SyntaxGenerator.GetGenerator(document); var methodInvocationSymbol = semanticModel.GetSymbolInfo(invocation.Expression); var mappingOverload = methodInvocationSymbol.CandidateSymbols.OfType <IMethodSymbol>().FirstOrDefault(IsMappingMethod); if (mappingOverload == null) { return(document); } var sourceElementType = ((INamedTypeSymbol)mappingOverload.Parameters[0].Type).TypeArguments[0]; var targetElementType = GetExpressionType(semanticModel, invocation); if (targetElementType == null) { return(document); } var contextAssembly = semanticModel.FindContextAssembly(invocation); var mappingEngine = new MappingEngine(semanticModel, syntaxGenerator, contextAssembly); var mappingLambda = mappingEngine.CreateMappingLambda("x", sourceElementType, targetElementType, new MappingPath()); return(await document.ReplaceNodes(invocation, invocation.WithArgumentList(SyntaxFactory.ArgumentList().AddArguments(SyntaxFactory.Argument((ExpressionSyntax)mappingLambda))), cancellationToken)); }
private async Task <Document> GenerateExplicitConversion(Document document, YieldStatementSyntax yieldStatement, CancellationToken cancellationToken) { var mappingEngine = await MappingEngine.Create(document, cancellationToken); var returnExpressionTypeInfo = mappingEngine.GetExpressionTypeInfo(yieldStatement.Expression); var mappingExpression = mappingEngine.MapExpression(yieldStatement.Expression, returnExpressionTypeInfo.Type, returnExpressionTypeInfo.ConvertedType); return(await ReplaceNode(document, yieldStatement, yieldStatement.WithExpression(mappingExpression), cancellationToken)); }
private static async Task <MappingEngine> CreateMappingEngine(Document document, SyntaxNode node, CancellationToken cancellationToken) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken); var contextAssembly = semanticModel.FindContextAssembly(node); var mappingEngine = await MappingEngine.Create(document, cancellationToken, contextAssembly); return(mappingEngine); }
private async Task <Document> GenerateExplicitConversion(Document document, AssignmentExpressionSyntax assignmentExpression, CancellationToken cancellationToken) { var mappingEngine = await MappingEngine.Create(document, cancellationToken); var sourceType = mappingEngine.GetExpressionTypeInfo(assignmentExpression.Right).Type; var destimationType = mappingEngine.GetExpressionTypeInfo(assignmentExpression.Left).Type; var mappingExpression = mappingEngine.MapExpression(assignmentExpression.Right, sourceType, destimationType); return(await ReplaceNode(document, assignmentExpression, assignmentExpression.WithRight(mappingExpression), cancellationToken)); }
private static IEnumerable<SyntaxNode> GenerateMappingCode(IMethodSymbol methodSymbol, SyntaxGenerator generator, SemanticModel semanticModel) { var mappingEngine = new MappingEngine(semanticModel, generator); if (SymbolHelper.IsPureMappingFunction(methodSymbol)) { var source = methodSymbol.Parameters[0]; var targetType = methodSymbol.ReturnType; var newExpression = mappingEngine.MapExpression((ExpressionSyntax)generator.IdentifierName(source.Name), source.Type, targetType); return new[] { generator.ReturnStatement(newExpression) }; } //TODO: Pure mapping with multiple parameters if (SymbolHelper.IsUpdateParameterFunction(methodSymbol)) { var source = methodSymbol.Parameters[0]; var target = methodSymbol.Parameters[1]; var targets = ObjectHelper.GetFieldsThaCanBeSetPublicly(target.Type); var sourceFinder = new ObjectMembersMappingSourceFinder(source.Type, generator.IdentifierName(source.Name), generator); return MappingHelper.MapUsingSimpleAssignment(generator, semanticModel, targets, sourceFinder, globalTargetAccessor: generator.IdentifierName(target.Name)); } if (SymbolHelper.IsUpdateThisObjectFunction(methodSymbol)) { var source = methodSymbol.Parameters[0]; var sourceFinder = new ObjectMembersMappingSourceFinder(source.Type, generator.IdentifierName(source.Name), generator); var targets = ObjectHelper.GetFieldsThaCanBeSetPrivately(methodSymbol.ContainingType); return MappingHelper.MapUsingSimpleAssignment(generator, semanticModel, targets, sourceFinder); } if (SymbolHelper.IsMultiParameterUpdateThisObjectFunction(methodSymbol)) { var sourceFinder = new LocalScopeMappingSourceFinder(semanticModel, methodSymbol.Parameters); var targets = ObjectHelper.GetFieldsThaCanBeSetPrivately(methodSymbol.ContainingType); return MappingHelper.MapUsingSimpleAssignment(generator, semanticModel, targets, sourceFinder); } if (SymbolHelper.IsMappingConstructor(methodSymbol)) { var source = methodSymbol.Parameters[0]; var sourceFinder = new ObjectMembersMappingSourceFinder(source.Type, generator.IdentifierName(source.Name), generator); var targets = ObjectHelper.GetFieldsThaCanBeSetFromConstructor(methodSymbol.ContainingType); return MappingHelper.MapUsingSimpleAssignment(generator, semanticModel, targets, sourceFinder); } if (SymbolHelper.IsMultiParameterMappingConstructor(methodSymbol)) { var sourceFinder = new LocalScopeMappingSourceFinder(semanticModel, methodSymbol.Parameters); var targets = ObjectHelper.GetFieldsThaCanBeSetFromConstructor(methodSymbol.ContainingType); return MappingHelper.MapUsingSimpleAssignment(generator, semanticModel, targets, sourceFinder); } return Enumerable.Empty<SyntaxNode>(); }
private static async Task <Document> ReplaceEmptyInitializationBlock(Document document, InitializerExpressionSyntax objectInitializer, SemanticModel semanticModel, IMappingSourceFinder mappingSourceFinder, CancellationToken cancellationToken) { var oldObjCreation = objectInitializer.FindContainer <ObjectCreationExpressionSyntax>(); var createdObjectType = ModelExtensions.GetTypeInfo(semanticModel, oldObjCreation).Type; var mappingEngine = await MappingEngine.Create(document, cancellationToken, semanticModel.FindContextAssembly(objectInitializer)); var newObjectCreation = mappingEngine.AddInitializerWithMapping(oldObjCreation, mappingSourceFinder, createdObjectType); return(await document.ReplaceNodes(oldObjCreation, newObjectCreation, cancellationToken)); }
public ArgumentListSyntax ToArgumentListSyntax(MappingEngine mappingEngine, bool generateNamedParameters = true) { return(Matches.Aggregate(SyntaxFactory.ArgumentList(), (list, match) => { if (match.Source?.Expression == null && match.Parameter.IsOptional) { generateNamedParameters = true; return list; } var parameterType = match.Parameter.Type; var expression = mappingEngine.MapExpression(match.Source, parameterType)?.Expression ?? mappingEngine.CreateDefaultExpression(parameterType); var argument = generateNamedParameters ? SyntaxFactory.Argument(SyntaxFactory.NameColon(match.Parameter.Name), SyntaxFactory.Token(SyntaxKind.None), expression) : SyntaxFactory.Argument(expression); return list.AddArguments(argument); })); }
private async Task <Document> UseLocalVariablesAsParameters(Document document, IInvocation invocation, bool generateNamedParameters, CancellationToken cancellationToken) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken); var syntaxGenerator = SyntaxGenerator.GetGenerator(document); var mappingSourceFinder = new LocalScopeMappingSourceFinder(semanticModel, invocation.SourceNode); var overloadParameterSets = invocation.GetOverloadParameterSets(semanticModel); if (overloadParameterSets != null) { var mappingEngine = new MappingEngine(semanticModel, syntaxGenerator); var parametersMatch = MethodHelper.FindBestParametersMatch(mappingSourceFinder, overloadParameterSets); if (parametersMatch != null) { var argumentList = parametersMatch.ToArgumentListSyntax(mappingEngine, generateNamedParameters); return(await document.ReplaceNodes(invocation.SourceNode, invocation.WithArgumentList(argumentList), cancellationToken)); } } return(document); }
private async Task <Document> GenerateSplatting(Document document, IInvocation invocation, bool generateNamedParameters, CancellationToken cancellationToken) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken); var overloadParameterSets = invocation.GetOverloadParameterSets(semanticModel); if (overloadParameterSets != null) { var syntaxGenerator = SyntaxGenerator.GetGenerator(document); var mappingEngine = new MappingEngine(semanticModel, syntaxGenerator); var invalidArgumentList = invocation.Arguments; var parametersMatch = FindParametersMatch(invalidArgumentList, overloadParameterSets, semanticModel, syntaxGenerator); if (parametersMatch != null) { var argumentList = parametersMatch.ToArgumentListSyntax(mappingEngine, generateNamedParameters); return(await document.ReplaceNodes(invocation.SourceNode, invocation.WithArgumentList(argumentList), cancellationToken)); } } return(document); }
private string GetArgumentListWithLocalVariables(Document document, IInvocation invocation, bool generateNamedParameters, SemanticModel semanticModel) { var mappingSourceFinder = new LocalScopeMappingSourceFinder(semanticModel, invocation.SourceNode); var syntaxGenerator = SyntaxGenerator.GetGenerator(document); var overloadParameterSets = invocation.GetOverloadParameterSets(semanticModel); if (overloadParameterSets != null) { var contextAssembly = semanticModel.FindContextAssembly(invocation.SourceNode); var mappingEngine = new MappingEngine(semanticModel, syntaxGenerator, contextAssembly); var parametersMatch = MethodHelper.FindBestParametersMatch(mappingSourceFinder, overloadParameterSets); if (parametersMatch != null) { var argumentList = parametersMatch.ToArgumentListSyntax(mappingEngine, generateNamedParameters); var chunks = argumentList.Arguments.Select(a => a.ToString()); return(string.Join(", ", chunks)); } } return(null); }
public static async Task <Document> FixInvocationWithParameters(Document document, IInvocation invocation, bool generateNamedParameters, SemanticModel semanticModel, IMappingSourceFinder mappingSourceFinder, CancellationToken cancellationToken) { var syntaxGenerator = SyntaxGenerator.GetGenerator(document); var overloadParameterSets = invocation.GetOverloadParameterSets(semanticModel); if (overloadParameterSets != null) { var contextAssembly = semanticModel.FindContextAssembly(invocation.SourceNode); var mappingEngine = new MappingEngine(semanticModel, syntaxGenerator, contextAssembly); var parametersMatch = MethodHelper.FindBestParametersMatch(mappingSourceFinder, overloadParameterSets); if (parametersMatch != null) { var argumentList = parametersMatch.ToArgumentListSyntax(mappingEngine, generateNamedParameters); return(await document.ReplaceNodes(invocation.SourceNode, invocation.WithArgumentList(argumentList), cancellationToken)); } } return(document); }
private static IEnumerable <SyntaxNode> GenerateMappingCode(IMethodSymbol methodSymbol, SyntaxGenerator generator, SemanticModel semanticModel) { if (SymbolHelper.IsIdentityMappingFunction(methodSymbol)) { var cloneMappingEngine = new CloneMappingEngine(semanticModel, generator, methodSymbol.ContainingAssembly); var source = methodSymbol.Parameters[0]; var targetType = methodSymbol.ReturnType; var newExpression = cloneMappingEngine.MapExpression((ExpressionSyntax)generator.IdentifierName(source.Name), source.Type, targetType); return(new[] { generator.ReturnStatement(newExpression).WithAdditionalAnnotations(Formatter.Annotation) }); } var mappingEngine = new MappingEngine(semanticModel, generator, methodSymbol.ContainingAssembly); if (SymbolHelper.IsPureMappingFunction(methodSymbol)) { var source = methodSymbol.Parameters[0]; var targetType = methodSymbol.ReturnType; var newExpression = mappingEngine.MapExpression((ExpressionSyntax)generator.IdentifierName(source.Name), source.Type, targetType); return(new[] { generator.ReturnStatement(newExpression).WithAdditionalAnnotations(Formatter.Annotation) }); } if (SymbolHelper.IsMultiParameterPureFunction(methodSymbol)) { var targetType = methodSymbol.ReturnType; var sourceFinder = new LocalScopeMappingSourceFinder(semanticModel, methodSymbol); var newExpression = mappingEngine.AddInitializerWithMapping((ObjectCreationExpressionSyntax)generator.ObjectCreationExpression(targetType), sourceFinder, targetType); return(new[] { generator.ReturnStatement(newExpression).WithAdditionalAnnotations(Formatter.Annotation) }); } if (SymbolHelper.IsUpdateParameterFunction(methodSymbol)) { var source = methodSymbol.Parameters[0]; var target = methodSymbol.Parameters[1]; var targets = ObjectHelper.GetFieldsThaCanBeSetPublicly(target.Type, methodSymbol.ContainingAssembly); var sourceFinder = new ObjectMembersMappingSourceFinder(source.Type, generator.IdentifierName(source.Name), generator); return(mappingEngine.MapUsingSimpleAssignment(generator, targets, sourceFinder, globalTargetAccessor: generator.IdentifierName(target.Name))); } if (SymbolHelper.IsUpdateThisObjectFunction(methodSymbol)) { var source = methodSymbol.Parameters[0]; var sourceFinder = new ObjectMembersMappingSourceFinder(source.Type, generator.IdentifierName(source.Name), generator); var targets = ObjectHelper.GetFieldsThaCanBeSetPrivately(methodSymbol.ContainingType); return(mappingEngine.MapUsingSimpleAssignment(generator, targets, sourceFinder)); } if (SymbolHelper.IsMultiParameterUpdateThisObjectFunction(methodSymbol)) { var sourceFinder = new LocalScopeMappingSourceFinder(semanticModel, methodSymbol.Parameters); var targets = ObjectHelper.GetFieldsThaCanBeSetPrivately(methodSymbol.ContainingType); return(mappingEngine.MapUsingSimpleAssignment(generator, targets, sourceFinder)); } if (SymbolHelper.IsMappingConstructor(methodSymbol)) { var source = methodSymbol.Parameters[0]; var sourceFinder = new ObjectMembersMappingSourceFinder(source.Type, generator.IdentifierName(source.Name), generator); var targets = ObjectHelper.GetFieldsThaCanBeSetFromConstructor(methodSymbol.ContainingType); return(mappingEngine.MapUsingSimpleAssignment(generator, targets, sourceFinder)); } if (SymbolHelper.IsMultiParameterMappingConstructor(methodSymbol)) { var sourceFinder = new LocalScopeMappingSourceFinder(semanticModel, methodSymbol.Parameters); var targets = ObjectHelper.GetFieldsThaCanBeSetFromConstructor(methodSymbol.ContainingType); return(mappingEngine.MapUsingSimpleAssignment(generator, targets, sourceFinder)); } return(Enumerable.Empty <SyntaxNode>()); }