public static bool CanRefactor(RefactoringContext context, PropertyDeclarationSyntax propertyDeclaration)
        {
            AccessorListSyntax accessorList = propertyDeclaration.AccessorList;

            if (accessorList != null)
            {
                SyntaxList <AccessorDeclarationSyntax> accessors = accessorList.Accessors;

                if (accessors.Count == 1)
                {
                    AccessorDeclarationSyntax accessor = accessors.First();

                    if (accessor.IsKind(SyntaxKind.GetAccessorDeclaration))
                    {
                        if (accessor.BodyOrExpressionBody() != null)
                        {
                            return(true);
                        }
                        else if (context.SupportsCSharp6 &&
                                 accessor.IsAutoGetter() &&
                                 propertyDeclaration.Initializer?.Value != null)
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Ejemplo n.º 2
0
        private static void AnalyzeAccessorList(SyntaxNodeAnalysisContext context)
        {
            var accessorList = (AccessorListSyntax)context.Node;

            SyntaxList <AccessorDeclarationSyntax> accessors = accessorList.Accessors;

            if (accessors.Count <= 1)
            {
                return;
            }

            Debug.Assert(accessors.Count == 2, accessors.Count.ToString());

            AccessorDeclarationSyntax accessor1 = accessors[0];

            if (accessor1.BodyOrExpressionBody() == null)
            {
                return;
            }

            AccessorDeclarationSyntax accessor2 = accessors[1];

            if (accessor2.BodyOrExpressionBody() == null)
            {
                return;
            }

            SyntaxTriviaList trailingTrivia = accessor1.GetTrailingTrivia();

            if (!SyntaxTriviaAnalysis.IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(trailingTrivia))
            {
                return;
            }

            SyntaxTriviaList leadingTrivia = accessor2.GetLeadingTrivia();

            bool isEmptyLine = SyntaxTriviaAnalysis.StartsWithOptionalWhitespaceThenEndOfLineTrivia(leadingTrivia);

            if (accessorList.SyntaxTree.IsSingleLineSpan(accessor1.Span, context.CancellationToken) &&
                accessorList.SyntaxTree.IsSingleLineSpan(accessor2.Span, context.CancellationToken))
            {
                if (isEmptyLine)
                {
                    ReportDiagnostic(context, DiagnosticDescriptors.RemoveEmptyLineBetweenSingleLineAccessors, leadingTrivia[0]);
                }
                else
                {
                    ReportDiagnostic(context, DiagnosticDescriptors.AddEmptyLineBetweenSingleLineAccessors, trailingTrivia.Last());
                }
            }
            else if (!isEmptyLine)
            {
                ReportDiagnostic(context, DiagnosticDescriptors.AddEmptyLineBetweenAccessors, trailingTrivia.Last());
            }
        }
Ejemplo n.º 3
0
        public static bool CanRefactor(RefactoringContext context, PropertyDeclarationSyntax propertyDeclaration)
        {
            AccessorDeclarationSyntax accessor = propertyDeclaration.AccessorList?.Accessors.SingleOrDefault(shouldThrow: false);

            if (accessor?.Kind() != SyntaxKind.GetAccessorDeclaration)
            {
                return(false);
            }

            if (accessor.BodyOrExpressionBody() != null)
            {
                return(true);
            }

            return(context.SupportsCSharp6 &&
                   accessor.IsAutoImplemented() &&
                   propertyDeclaration.Initializer?.Value != null);
        }
Ejemplo n.º 4
0
        private static void AnalyzeTypeDeclaration(SyntaxNodeAnalysisContext context)
        {
            var typeDeclaration = (TypeDeclarationSyntax)context.Node;

            if (typeDeclaration.Modifiers.Contains(SyntaxKind.PartialKeyword))
            {
                return;
            }

            bool skipField = !DiagnosticRules.MakeFieldReadOnly.IsEffective(context);

            bool skipProperty = !DiagnosticRules.UseReadOnlyAutoProperty.IsEffective(context) ||
                                ((CSharpCompilation)context.Compilation).LanguageVersion < LanguageVersion.CSharp6;

            MakeMemberReadOnlyWalker walker = MakeMemberReadOnlyWalker.GetInstance();

            walker.SemanticModel     = context.SemanticModel;
            walker.CancellationToken = context.CancellationToken;

            Dictionary <string, (SyntaxNode node, ISymbol symbol)> symbols = walker.Symbols;

            foreach (MemberDeclarationSyntax memberDeclaration in typeDeclaration.Members)
            {
                switch (memberDeclaration.Kind())
                {
                case SyntaxKind.PropertyDeclaration:
                {
                    if (skipProperty)
                    {
                        break;
                    }

                    var propertyDeclaration = (PropertyDeclarationSyntax)memberDeclaration;

                    AccessorDeclarationSyntax setter = propertyDeclaration.Setter();

                    if (setter?.IsKind(SyntaxKind.InitAccessorDeclaration) == false &&
                        setter.BodyOrExpressionBody() == null &&
                        !setter.AttributeLists.Any() &&
                        !setter.SpanContainsDirectives())
                    {
                        IPropertySymbol propertySymbol = context.SemanticModel.GetDeclaredSymbol(propertyDeclaration, context.CancellationToken);

                        IMethodSymbol setMethod = propertySymbol.SetMethod;

                        if (setMethod?.DeclaredAccessibility == Accessibility.Private &&
                            setMethod.GetAttributes().IsEmpty &&
                            !propertySymbol.IsIndexer &&
                            !propertySymbol.IsReadOnly &&
                            ValidateType(propertySymbol.Type) &&
                            propertySymbol.ExplicitInterfaceImplementations.IsDefaultOrEmpty &&
                            AnalyzePropertyAttributes(propertySymbol))
                        {
                            symbols[propertySymbol.Name] = (propertyDeclaration, propertySymbol);
                        }
                    }

                    break;
                }

                case SyntaxKind.FieldDeclaration:
                {
                    if (skipField)
                    {
                        break;
                    }

                    var fieldDeclaration = (FieldDeclarationSyntax)memberDeclaration;

                    foreach (VariableDeclaratorSyntax declarator in fieldDeclaration.Declaration.Variables)
                    {
                        if (context.SemanticModel.GetDeclaredSymbol(declarator, context.CancellationToken) is IFieldSymbol fieldSymbol &&
                            !fieldSymbol.IsConst &&
                            fieldSymbol.DeclaredAccessibility == Accessibility.Private &&
                            !fieldSymbol.IsReadOnly &&
                            !fieldSymbol.IsVolatile &&
                            ValidateType(fieldSymbol.Type))
                        {
                            symbols[fieldSymbol.Name] = (declarator, fieldSymbol);
                        }
                    }

                    break;
                }
                }
            }

            if (symbols.Count > 0)
            {
                foreach (MemberDeclarationSyntax memberDeclaration in typeDeclaration.Members)
                {
                    walker.Visit(memberDeclaration);

                    if (symbols.Count == 0)
                    {
                        break;
                    }
                }

                if (symbols.Count > 0)
                {
                    foreach (KeyValuePair <string, (SyntaxNode node, ISymbol symbol)> kvp in symbols)
                    {
                        if (kvp.Value.node is PropertyDeclarationSyntax propertyDeclaration)
                        {
                            AccessorDeclarationSyntax setter = propertyDeclaration.Setter();

                            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.UseReadOnlyAutoProperty, setter);
                        }
                    }

                    foreach (IGrouping <VariableDeclarationSyntax, SyntaxNode> grouping in symbols
                             .Select(f => f.Value.node)
                             .Where(f => f.IsKind(SyntaxKind.VariableDeclarator))
                             .GroupBy(f => (VariableDeclarationSyntax)f.Parent))
                    {
                        int count = grouping.Key.Variables.Count;

                        if (count == 1 ||
                            count == grouping.Count())
                        {
                            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.MakeFieldReadOnly, grouping.Key.Parent);
                        }
                    }
                }
            }

            MakeMemberReadOnlyWalker.Free(walker);
Ejemplo n.º 5
0
        private static void AnalyzeAccessorList(SyntaxNodeAnalysisContext context)
        {
            var accessorList = (AccessorListSyntax)context.Node;

            SyntaxList <AccessorDeclarationSyntax> accessors = accessorList.Accessors;

            if (accessors.Count <= 1)
            {
                return;
            }

            Debug.Assert(accessors.Count == 2, accessors.Count.ToString());

            AccessorDeclarationSyntax accessor1 = accessors[0];

            if (accessor1.BodyOrExpressionBody() == null)
            {
                return;
            }

            AccessorDeclarationSyntax accessor2 = accessors[1];

            if (accessor2.BodyOrExpressionBody() == null)
            {
                return;
            }

            SyntaxTriviaList trailingTrivia = accessor1.GetTrailingTrivia();

            if (!SyntaxTriviaAnalysis.IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(trailingTrivia))
            {
                return;
            }

            SyntaxTriviaList leadingTrivia = accessor2.GetLeadingTrivia();

            bool isEmptyLine = SyntaxTriviaAnalysis.StartsWithOptionalWhitespaceThenEndOfLineTrivia(leadingTrivia);

            if (accessorList.SyntaxTree.IsSingleLineSpan(accessor1.Span, context.CancellationToken) &&
                accessorList.SyntaxTree.IsSingleLineSpan(accessor2.Span, context.CancellationToken))
            {
                if (DiagnosticRules.BlankLineBetweenSingleLineAccessors.IsEffective(context))
                {
                    BlankLineStyle style = context.GetBlankLineBetweenSingleLineAccessors();

                    if (isEmptyLine)
                    {
                        if (style == BlankLineStyle.Remove)
                        {
                            DiagnosticHelpers.ReportDiagnostic(
                                context,
                                DiagnosticRules.BlankLineBetweenSingleLineAccessors,
                                Location.Create(context.Node.SyntaxTree, leadingTrivia[0].Span.WithLength(0)),
                                properties: DiagnosticProperties.AnalyzerOption_Invert,
                                "Remove");
                        }
                    }
                    else if (style == BlankLineStyle.Add)
                    {
                        DiagnosticHelpers.ReportDiagnostic(
                            context,
                            DiagnosticRules.BlankLineBetweenSingleLineAccessors,
                            Location.Create(context.Node.SyntaxTree, trailingTrivia.Last().Span.WithLength(0)),
                            "Add");
                    }
                }
            }
            else if (!isEmptyLine)
            {
                DiagnosticHelpers.ReportDiagnosticIfEffective(
                    context,
                    DiagnosticRules.AddBlankLineBetweenAccessors,
                    Location.Create(context.Node.SyntaxTree, trailingTrivia.Last().Span.WithLength(0)));
            }
        }