private static void ValidateMap(List <AttributeSyntax> mapCandidates, Maps.Builder maps, Compilation compilation)
        {
            var mapAttributeSymbol = compilation.GetTypeByMetadataName(typeof(MapAttribute).FullName);

            foreach (var candidateAttributeNode in mapCandidates)
            {
                var attributeSymbol = compilation.GetSemanticModel(candidateAttributeNode.SyntaxTree)
                                      .GetSymbolInfo(candidateAttributeNode).Symbol !.ContainingSymbol;

                if (attributeSymbol.Equals(mapAttributeSymbol, SymbolEqualityComparer.Default))
                {
                    var attributeData = compilation.Assembly.GetAttributes().Single(
                        _ => _.ApplicationSyntaxReference !.GetSyntax() == candidateAttributeNode);
                    var sourceType      = (INamedTypeSymbol)attributeData.ConstructorArguments[0].Value !;
                    var destinationType = (INamedTypeSymbol)attributeData.ConstructorArguments[1].Value !;
                    MappingInformation.ValidatePairs(candidateAttributeNode, sourceType, destinationType, maps);
                }
            }
        }
Exemplo n.º 2
0
        private static void ValidatePairs(SyntaxNode currentNode, INamedTypeSymbol source, INamedTypeSymbol destination,
                                          Maps.Builder maps)
        {
            var key = (source, destination);

            if (maps.ContainsKey(key))
            {
                var diagnostics = maps[key].diagnostics.ToList();
                diagnostics.Add(DuplicatedAttributeDiagnostic.Create(currentNode, maps[key].node));
                maps[key] = (diagnostics.ToImmutableArray(), maps[key].node, maps[key].maps);
            }
            else
            {
                var diagnostics = ImmutableArray.CreateBuilder <Diagnostic>();

                if (!destination.Constructors.Any(_ => _.DeclaredAccessibility == Accessibility.Public && _.Parameters.Length == 0))
                {
                    diagnostics.Add(NoArgumentConstructorDiagnostic.Create(currentNode));
                }

                var propertyMaps = ImmutableArray.CreateBuilder <string>();

                var destinationProperties = destination.GetMembers().OfType <IPropertySymbol>()
                                            .Where(_ => _.SetMethod is not null &&
                                                   (_.SetMethod.DeclaredAccessibility == Accessibility.Public ||
                                                    (destination.ContainingAssembly.ExposesInternalsTo(source.ContainingAssembly) && _.SetMethod.DeclaredAccessibility == Accessibility.Friend)))
                                            .ToList();

                foreach (var sourceProperty in source.GetMembers().OfType <IPropertySymbol>()
                         .Where(_ => _.GetMethod is not null &&
                                (_.GetMethod.DeclaredAccessibility == Accessibility.Public ||
                                 (source.ContainingAssembly.ExposesInternalsTo(destination.ContainingAssembly) && _.GetMethod.DeclaredAccessibility == Accessibility.Friend))))
                {
                    var destinationProperty = destinationProperties.FirstOrDefault(
                        _ => _.Name == sourceProperty.Name &&
                        _.Type.Equals(sourceProperty.Type, SymbolEqualityComparer.Default) &&
                        (sourceProperty.NullableAnnotation != NullableAnnotation.Annotated ||
                         sourceProperty.NullableAnnotation == NullableAnnotation.Annotated && _.NullableAnnotation == NullableAnnotation.Annotated));

                    if (destinationProperty is not null)
                    {
                        propertyMaps.Add($"{destinationProperty.Name} = self.{sourceProperty.Name},");
                        destinationProperties.Remove(destinationProperty);
                    }
                    else
                    {
                        diagnostics.Add(NoMatchDiagnostic.Create(sourceProperty, "source", source));
                    }
                }

                foreach (var remainingDestinationProperty in destinationProperties)
                {
                    diagnostics.Add(NoMatchDiagnostic.Create(remainingDestinationProperty, "destination", destination));
                }

                if (propertyMaps.Count == 0)
                {
                    diagnostics.Add(NoPropertyMapsFoundDiagnostic.Create(currentNode));
                }

                maps.Add((source, destination), (diagnostics.ToImmutable(), currentNode, propertyMaps.ToImmutable()));
            }
        }
        private static void ValidateMapTo(List <TypeDeclarationSyntax> mapToCandidates, Maps.Builder maps, Compilation compilation)
        {
            var mapToAttributeSymbol = compilation.GetTypeByMetadataName(typeof(MapToAttribute).FullName);

            foreach (var candidateTypeNode in mapToCandidates)
            {
                var model      = compilation.GetSemanticModel(candidateTypeNode.SyntaxTree);
                var sourceType = model.GetDeclaredSymbol(candidateTypeNode) as INamedTypeSymbol;

                if (sourceType is not null)
                {
                    foreach (var mappingAttribute in sourceType.GetAttributes().Where(
                                 _ => _.AttributeClass !.Equals(mapToAttributeSymbol, SymbolEqualityComparer.Default)))
                    {
                        var destinationType = (INamedTypeSymbol)mappingAttribute.ConstructorArguments[0].Value !;
                        MappingInformation.ValidatePairs(mappingAttribute.ApplicationSyntaxReference !.GetSyntax(),
                                                         sourceType, destinationType, maps);
                    }
                }
            }
        }