示例#1
0
    public static void ProcessOutRefInvocation(ISymbol symbol, BlockSyntax block, SemanticModel semanticModel, CancellationToken cancellationToken, RefCounterStatus status)
    {
        using (var pooledInvocations = InvocationWalker.Borrow(block))
        {
            foreach (var invocation in pooledInvocations.Invocations)
            {
                foreach (ArgumentSyntax arg in invocation.ArgumentList.Arguments)
                {
                    if (arg.RefOrOutKeyword.IsKind(SyntaxKind.OutKeyword) || arg.RefOrOutKeyword.IsKind(SyntaxKind.RefKeyword))
                    {
                        var     sym       = ModelExtensions.GetSymbolInfo(semanticModel, arg.Expression, cancellationToken);
                        ISymbol argSymbol = sym.Symbol;
                        if (symbol.Equals(argSymbol))
                        {
                            status.RemainRef("init from out/ref call", arg.GetLocation());
                            status.IncAssignCounter("out/ref call parameter", arg.GetLocation());

                            if (LoopUtils.HasLoopBetween(invocation, block))
                            {
                                status.Skip("loop between ref/out call and var block", arg.GetLocation());
                            }
                        }
                    }
                }
            }
        }
    }
示例#2
0
 public static void ProcessReturnStatement(ISymbol local, BlockSyntax block, SemanticModel semanticModel, CancellationToken cancellationToken,
                                           RefCounterStatus status)
 {
     using (var walker = ReturnValueWalker.Borrow(block, Search.TopLevel, semanticModel, cancellationToken))
     {
         foreach (var value in walker)
         {
             var returnedSymbol = semanticModel.GetSymbolSafe(value, cancellationToken);
             if (SymbolComparer.Equals(local, returnedSymbol))
             {
                 var  method = block.FirstAncestor <MethodDeclarationSyntax>();
                 var  access = block.FirstAncestor <AccessorDeclarationSyntax>();
                 bool isGet  = false;
                 if (method != null)
                 {
                     isGet = KnownSymbol.IsGetMethodName(method.Identifier.ToString());
                 }
                 else if (access != null)
                 {
                     isGet = true;
                 }
                 if (isGet)
                 {
                     status.RemainRef("return value from get method", value.GetLocation());
                 }
                 else
                 {
                     status.ReleaseReference("return value from non get", value.GetLocation());
                 }
             }
         }
     }
 }
示例#3
0
 public static void CalcAssignmentValue(ExpressionSyntax variable, BlockSyntax block, SemanticModel semanticModel, CancellationToken cancellationToken,
                                        RefCounterStatus refCounterStatus)
 {
     if (InitializeFromCreation(variable))
     {
         refCounterStatus.IncAssignCounter("initialize from new", variable.GetLocation());
         refCounterStatus.AcquireReference("init from new", variable.GetLocation());
     }
     else if (InitializeFromTypeCastParameter(variable, semanticModel, cancellationToken, out var param))
     {
         refCounterStatus.IncAssignCounter("init cast from param", variable.GetLocation());
         refCounterStatus.RemainRef("init cast from param", variable.GetLocation());
         if (RightOfAssignmentUtils.RightSideOfAssignmentCount(param, block, semanticModel, cancellationToken) > 1)
         {
             refCounterStatus.Skip("cast from param also assigned to others", variable.GetLocation());
         }
     }
     else if (InitializeFromNonGetMethod(variable, semanticModel, cancellationToken))
     {
         refCounterStatus.IncAssignCounter("initialize from non-get method", variable.GetLocation());
         refCounterStatus.AcquireReference("init from non-get method", variable.GetLocation());
     }
     else if (InitializeFromGetMethod(variable, semanticModel, cancellationToken))
     {
         refCounterStatus.IncAssignCounter("initialize from get method", variable.GetLocation());
         refCounterStatus.RemainRef("init from get method", variable.GetLocation());
     }
     else if (InitializeFromProperty(variable, semanticModel, cancellationToken))
     {
         refCounterStatus.IncAssignCounter("initialize from field/property", variable.GetLocation());
         refCounterStatus.RemainRef("init from property", variable.GetLocation());
         // nothing
     }
     else if (InitializeFromElement(variable, semanticModel, cancellationToken))
     {
         refCounterStatus.IncAssignCounter("initialize from element access", variable.GetLocation());
         refCounterStatus.RemainRef("init from element access", variable.GetLocation());
     }
     else // assigned from other local variable, class field, or other expression
     {
         refCounterStatus.IncAssignCounter("initialize from unkown", variable.GetLocation());
         refCounterStatus.Skip("unsupported initialization", variable.GetLocation());
     }
 }