private async Task <Document> GenerateMappingMethodBody(Document document, BaseMethodDeclarationSyntax methodSyntax, bool useMembersMappers, CancellationToken cancellationToken) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var methodSymbol = semanticModel.GetDeclaredSymbol(methodSyntax, cancellationToken); var generator = SyntaxGenerator.GetGenerator(document); var mappingContext = new MappingContext(methodSyntax, semanticModel); var accessibilityHelper = new AccessibilityHelper(methodSymbol.ContainingType); if (useMembersMappers) { foreach (var userDefinedConversion in CustomConversionHelper.FindCustomConversionMethods(methodSymbol)) { if (userDefinedConversion == methodSymbol || accessibilityHelper.IsSymbolAccessible(userDefinedConversion, methodSymbol.ContainingType) == false) { continue; } mappingContext.CustomConversions.Add(new CustomConversion() { FromType = new AnnotatedType(userDefinedConversion.Parameters.First().Type), ToType = new AnnotatedType(userDefinedConversion.ReturnType), Conversion = SyntaxFactory.IdentifierName(userDefinedConversion.Name) }); } } var blockSyntax = await MappingImplementorEngine.GenerateMappingBlockAsync(methodSymbol, generator, semanticModel, mappingContext).ConfigureAwait(false); return(await document.ReplaceNodes(methodSyntax, methodSyntax.WithOnlyBody(blockSyntax), cancellationToken).ConfigureAwait(false)); }
public Task <GenerationResult> GenerateAsync(CSharpSyntaxNode processedNode, AttributeData markerAttribute, TransformationContext context, CancellationToken cancellationToken) { var syntaxGenerator = SyntaxGenerator.GetGenerator(context.Document); var mappingDeclaration = (InterfaceDeclarationSyntax)processedNode; var interfaceSymbol = context.SemanticModel.GetDeclaredSymbol(mappingDeclaration); var mappingContext = new MappingContext(interfaceSymbol); var accessibilityHelper = new AccessibilityHelper(interfaceSymbol); foreach (var x in FindCustomMapperTypes(markerAttribute).SelectMany(CustomConversionHelper.FindCustomConversionMethods)) { if (x.IsStatic && accessibilityHelper.IsSymbolAccessible(x, interfaceSymbol)) { mappingContext.CustomConversions[(x.Parameters[0].Type, x.ReturnType)] = (ExpressionSyntax)syntaxGenerator.MemberAccessExpression((ExpressionSyntax)syntaxGenerator.IdentifierName(x.ContainingType.ToDisplayString()), x.Name);
private async Task <Document> GenerateMappingMethodBody(Document document, BaseMethodDeclarationSyntax methodSyntax, bool useMembersMappers, CancellationToken cancellationToken) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken); var methodSymbol = semanticModel.GetDeclaredSymbol(methodSyntax); var generator = SyntaxGenerator.GetGenerator(document); var mappingContext = new MappingContext(methodSyntax, semanticModel); var accessibilityHelper = new AccessibilityHelper(methodSymbol.ContainingType); if (useMembersMappers) { foreach (var userDefinedConversion in CustomConversionHelper.FindCustomConversionMethods(methodSymbol)) { if (userDefinedConversion == methodSymbol || accessibilityHelper.IsSymbolAccessible(userDefinedConversion, methodSymbol.ContainingType) == false) { continue; } mappingContext.CustomConversions[(userDefinedConversion.Parameters.First().Type, userDefinedConversion.ReturnType)] = (ExpressionSyntax)generator.IdentifierName(userDefinedConversion.Name);
public async Task <GenerationResult> GenerateAsync(CSharpSyntaxNode processedNode, AttributeData markerAttribute, TransformationContext context, CancellationToken cancellationToken) { var syntaxGenerator = SyntaxGenerator.GetGenerator(context.Document); var mappingDeclaration = (InterfaceDeclarationSyntax)processedNode; var interfaceSymbol = context.SemanticModel.GetDeclaredSymbol(mappingDeclaration); var mappingContext = new MappingContext(interfaceSymbol); var accessibilityHelper = new AccessibilityHelper(interfaceSymbol); foreach (var x in FindCustomMapperTypes(markerAttribute).SelectMany(CustomConversionHelper.FindCustomConversionMethods)) { if (x.IsStatic && accessibilityHelper.IsSymbolAccessible(x, interfaceSymbol)) { mappingContext.CustomConversions.Add(new CustomConversion() { FromType = new AnnotatedType(x.Parameters[0].Type), ToType = new AnnotatedType(x.ReturnType), Conversion = (ExpressionSyntax)syntaxGenerator.MemberAccessExpression((ExpressionSyntax)syntaxGenerator.IdentifierName(x.ContainingType.ToDisplayString()), x.Name) }); } } var memberDeclarationSyntaxes = mappingDeclaration.Members.Select(async x => { if (x is MethodDeclarationSyntax methodDeclaration) { var methodSymbol = context.SemanticModel.GetDeclaredSymbol(methodDeclaration); var statements = ImplementorEngine.CanProvideMappingImplementationFor(methodSymbol) ? await ImplementorEngine.GenerateMappingStatements(methodSymbol, syntaxGenerator, context.SemanticModel, mappingContext).ConfigureAwait(false) : new List <StatementSyntax>() { GenerateThrowNotSupportedException(context, syntaxGenerator, methodSymbol.Name) }; var methodDeclarationSyntax = ((MethodDeclarationSyntax)syntaxGenerator.MethodDeclaration( methodDeclaration.Identifier.Text, parameters: methodDeclaration.ParameterList.Parameters, accessibility: Accessibility.Public, modifiers: DeclarationModifiers.Virtual, typeParameters: methodDeclaration.TypeParameterList?.Parameters.Select(xx => xx.Identifier.Text), returnType: methodDeclaration.ReturnType )).WithBody(SyntaxFactory.Block(statements)); return(methodDeclarationSyntax); } return(x); }); var mappingClass = (ClassDeclarationSyntax)syntaxGenerator.ClassDeclaration( mappingDeclaration.Identifier.Text.Substring(1), accessibility: Accessibility.Public, modifiers: DeclarationModifiers.Partial, interfaceTypes: new List <SyntaxNode>() { syntaxGenerator.TypeExpression(interfaceSymbol) }, members: await Task.WhenAll(memberDeclarationSyntaxes)); var newRoot = WrapInTheSameNamespace(mappingClass, processedNode); var usings = new List <UsingDirectiveSyntax>() { SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System")), SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System.Linq")), SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(interfaceSymbol.ContainingNamespace.ToDisplayString())) }; var immutableList = context.SemanticModel.Compilation.GetTypeByMetadataName("System.Collections.Immutable.IImmutableList`1"); if (immutableList != null) { usings.Add(SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System.Collections.Immutable"))); } return(new GenerationResult() { Members = SyntaxFactory.SingletonList(newRoot), Usings = new SyntaxList <UsingDirectiveSyntax>(usings) }); }