示例#1
0
        private void OnMethodDeclaration(SyntaxNodeAnalysisContext context)
        {
            var method = (IMethodSymbol)context.ContainingSymbol;

            if (!method.IsMappingMethod())
            {
                return;
            }

            var methodDeclarationSyntax      = (MethodDeclarationSyntax)context.Node;
            var mappingMethodAttributeSyntax = MappingMethodDetection
                                               .GetMappingMethodAttributeSyntax(methodDeclarationSyntax, context.SemanticModel);

            var location = mappingMethodAttributeSyntax?.GetLocation() ?? methodDeclarationSyntax.Identifier.GetLocation();

            var mappingTargetType = method.GetMappingTargetType(context.Compilation);

            if (mappingTargetType == null)
            {
                context.ReportDiagnostic(Diagnostic.Create(Diagnostics.MissingMappingTargetType, location));
                return;
            }

            var mappingTargetProperties = mappingTargetType.GetMappingTargetProperties();
            var mappedProperties        = new HashSet <IPropertySymbol>();

            foreach (var assignment in context.Node.DescendantNodes().OfType <AssignmentExpressionSyntax>())
            {
                var assignmentTarget = context.SemanticModel.GetSymbolInfo(assignment.Left);
                if (assignmentTarget.Symbol is IPropertySymbol targetProperty)
                {
                    mappedProperties.Add(targetProperty);
                }
            }

            var excludedPropertyNames = method.GetAttributes()
                                        .Where(a => a.AttributeClass.Name == "UnmappedPropertyAttribute")
                                        .Select(a => (string)a.ConstructorArguments[0].Value)
                                        .ToList();

            excludedPropertyNames.AddRange(method.GetAttributes()
                                           .Where(a => a.AttributeClass.Name == "UnmappedPropertiesAttribute")
                                           .SelectMany(a => a.ConstructorArguments[0].Values.Select(v => (string)v.Value)));

            var unmappedPropertyNames = mappingTargetProperties
                                        .Except(mappedProperties, new RootPropertyEqualityComparer())
                                        .Select(p => p.Name)
                                        .Except(excludedPropertyNames)
                                        .OrderBy(n => n);

            foreach (var unmappedPropertyName in unmappedPropertyNames)
            {
                var diagnostic = Diagnostic.Create(Diagnostics.UnmappedProperty, location, unmappedPropertyName);
                context.ReportDiagnostic(diagnostic);
            }
        }
        public void GetMappingMethodAttributeSyntax_NoAttribute_ReturnsNull()
        {
            var(method, semanticModel) = GetMapMethodDeclaration(@"
        public class TestClass
        {
          public object Map() => new object();
        }
      ");

            var attributeSyntax = MappingMethodDetection.GetMappingMethodAttributeSyntax(method, semanticModel);

            Assert.That(attributeSyntax, Is.Null);
        }
        public void GetMappingMethodAttributeSyntax_FullyQualifiedAttributeUsage_ReturnsSyntaxNode()
        {
            var(method, semanticModel) = GetMapMethodDeclaration(@"
        public class TestClass
        {
          [global::ManualMappingGuard.MappingMethodAttribute()]
          public object Map() => new object();
        }
      ");

            var attributeSyntax = MappingMethodDetection.GetMappingMethodAttributeSyntax(method, semanticModel);

            Assert.That(attributeSyntax !.GetLocation().SourceSpan, Is.EqualTo(new TextSpan(56, 51)));
        }
        public void GetMappingMethodAttributeSyntax_RegularAttributeUsage_ReturnsSyntaxNode()
        {
            var(method, semanticModel) = GetMapMethodDeclaration(@"
        using ManualMappingGuard;

        public class TestClass
        {
          [MappingMethod]
          public object Map() => new object();
        }
      ");

            var attributeSyntax = MappingMethodDetection.GetMappingMethodAttributeSyntax(method, semanticModel);

            Assert.That(attributeSyntax !.GetLocation().SourceSpan, Is.EqualTo(new TextSpan(93, 13)));
        }