public static void ProcessRightOfAssignmentToField(
        ISymbol variable,
        BlockSyntax block,
        SemanticModel semanticModel,
        CancellationToken cancellationToken,
        RefCounterStatus status)
    {
        List <AssignmentExpressionSyntax> rc = new List <AssignmentExpressionSyntax>();

        block?.TryGetAssignment(variable, semanticModel, cancellationToken, rc);
        int      count = 0;
        ISymbol  field = null;
        Location loc   = Location.None;

        foreach (AssignmentExpressionSyntax assignment in rc)
        {
            var classDef    = block.FirstAncestor <ClassDeclarationSyntax>();
            var classSymbol = CSharpExtensions.GetDeclaredSymbol(semanticModel, classDef, cancellationToken);

            if (IsRightOfAssignmentToField(semanticModel, cancellationToken, assignment.Left, out field))
            {
                count++;
                loc = assignment.GetLocation();
                if (!field.ContainingType.Equals(classSymbol))
                {
                    status.Skip("assigned to field/property of other class", loc);
                }

                if (LoopUtils.HasLoopBetween(assignment, block))
                {
                    status.Skip("loop between assignment to field/property and var block", loc);
                }
            }
        }

        if (count == 1)
        {
            status.ReleaseReference("assign to class field/property", loc);

            var methodBlock = block?.FirstAncestorOrSelf <BlockSyntax>();
            if (methodBlock == null)
            {
                return;
            }

            if (RightSideOfAssignmentCount(field, methodBlock, semanticModel, cancellationToken) > 0)
            {
                status.Skip("var assigned to field/property, which is assigned to others", loc);
            }


            ChangeReferenceMethodUtils.ProcessIncDelRefInvocation(field, methodBlock, semanticModel, cancellationToken, status);
            ReturnUtils.ProcessReturnStatement(field, methodBlock, semanticModel, cancellationToken, status);
        }
        else if (count > 1)
        {
            status.Skip("multiple assign to field/property", loc);
        }
    }
Пример #2
0
        private static void ProcessLocalOrParamenterVar(SyntaxNodeAnalysisContext context, ISymbol local,
                                                        BlockSyntax block, RefCounterStatus status)
        {
            RightOfAssignmentUtils.ProcessRightSideOfAssignment(local, block, context.SemanticModel,
                                                                context.CancellationToken, status);

            SystemCollectionUtils.ProcessAddedToCollection(local, block, context.SemanticModel, context.CancellationToken,
                                                           status);
            LeftOfAssignmentUtils.ProcessLeftSideOfAssignment(local, block, context.SemanticModel,
                                                              context.CancellationToken, status);

            ChangeReferenceMethodUtils.ProcessIncDelRefInvocation(local, block, context.SemanticModel, context.CancellationToken,
                                                                  status);

            AssignmentUtils.ProcessOutRefInvocation(local, block, context.SemanticModel, context.CancellationToken, status);

            ReturnUtils.ProcessReturnStatement(local, block, context.SemanticModel, context.CancellationToken, status);

            ReportError(context, local, status);
        }