private static int IncRefInvocationCount(ISymbol symbol, BlockSyntax block, SemanticModel semanticModel, CancellationToken cancellationToken, RefCounterStatus status) { int count = 0; Location loc = Location.None;; using (var pooledInvocations = InvocationWalker.Borrow(block)) { foreach (var invocation in pooledInvocations.Invocations) { var isFromSymbol = IsInvokeFrom(symbol, semanticModel, cancellationToken, invocation); var method = semanticModel.GetSymbolSafe(invocation, cancellationToken) as IMethodSymbol; if (isFromSymbol && method.ReceiverType != null) { if (method.ReceiverType.Is(KnownSymbol.RefCounter) && method?.Name == KnownSymbol.IncRef) { count++; loc = invocation.GetLocation(); if (LoopUtils.HasLoopBetween(invocation, block)) { status.Skip("loop between IncRef call and var block", loc); } } } } } if (count > 1) { status.Skip("more than one IncRef", loc); } else if (count == 1) { status.IncRef("call IncRef", loc); } return(count); }
public static void ProcessAddedToCollection( ISymbol symbol, BlockSyntax block, SemanticModel semanticModel, CancellationToken cancellationToken, RefCounterStatus status) { int count = 0; Location loc = Location.None; using (var pooledInvocations = InvocationWalker.Borrow(block)) { foreach (var invocation in pooledInvocations.Invocations) { bool isAddToCollection = false; var method = semanticModel.GetSymbolSafe(invocation, cancellationToken) as IMethodSymbol; if (method?.ReceiverType != null) { if (!isAddToCollection) { isAddToCollection = (method.ReceiverType.Is(KnownSymbol.IDictionary) || method.ReceiverType.Is(KnownSymbol.ICollection)) && method?.Name == "Add"; } if (!isAddToCollection) { isAddToCollection = method.ReceiverType.Is(KnownSymbol.QueueOfT) && method?.Name == "Enqueue"; } if (!isAddToCollection) { isAddToCollection = method.ReceiverType.Is(KnownSymbol.Queue) && method?.Name == "Enqueue"; } if (!isAddToCollection) { isAddToCollection = method.ReceiverType.Is(KnownSymbol.ListOfT) && method?.Name == "Insert"; } if (!isAddToCollection) { isAddToCollection = method.ReceiverType.Is(KnownSymbol.IRefCounterContainerOfT) && method?.Name == "Add"; } if (!isAddToCollection) { isAddToCollection = method.ReceiverType.Is(KnownSymbol.CollectionOfT) && method?.Name == "Add"; } if (!isAddToCollection) { isAddToCollection = method.ReceiverType.Is(KnownSymbol.LinkedListOfT) && (method?.Name == "AddLast" || method?.Name == "AddFirst"); } } if (isAddToCollection) { bool isInArg = false; foreach (ArgumentSyntax arg in invocation.ArgumentList.Arguments) { var sym = ModelExtensions.GetSymbolInfo(semanticModel, arg.Expression, cancellationToken); ISymbol argSymbol = sym.Symbol; if (symbol.Equals(argSymbol)) { isInArg = true; } } if (isInArg) { count++; loc = invocation.GetLocation(); if (LoopUtils.HasLoopBetween(invocation, block)) { status.Skip("loop between add to collection and var block", invocation.GetLocation()); } } } } } if (count == 1) { status.ReleaseReference("added to collection", loc); } }