Esempio n. 1
0
 private static void CalculateConnectionOfDisposableVariables(IInvocationExpression invocationExpression,
     ControlFlowElementData data, List<IRegularParameterDeclaration> thisConnections,
     Dictionary<IRegularParameterDeclaration, IVariableDeclaration> connections)
 {
     foreach (var argument in invocationExpression.InvocationExpressionReference.Invocation.Arguments)
     {
         var cSharpArgument = argument as ICSharpArgument;
         if (cSharpArgument == null)
             continue;
         var argumentExpression = cSharpArgument.Value;
         IRegularParameterDeclaration matchingVarDecl;
         if (argumentExpression is IThisExpression && data.ThisStatus != null)
         {
             if (GetMatchingParameterDeclaration(argument, out matchingVarDecl))
                 continue;
             thisConnections.Add(matchingVarDecl);
             continue;
         }
         var varDecl = TreeNodeHandlerUtil.GetVariableDeclarationForReferenceExpression(argumentExpression);
         if (data[varDecl] != null) // Если переменную не рассматриваем.
         {
             if (GetMatchingParameterDeclaration(argument, out matchingVarDecl))
                 continue;
             connections[matchingVarDecl] = varDecl;
         }
     }
 }
Esempio n. 2
0
 private static void SaveInvocationData(ControlFlowElementData data, IVariableDeclaration variable,
     byte position, string name, int offset, IPsiSourceFile sourceFile)
 {
     data[variable] = VariableDisposeStatus.DependsOnInvocation;
     var invokedExpression = new InvokedExpressionData(name, offset, position, sourceFile);
     data.InvokedExpressions.Add(variable, invokedExpression);
 }
Esempio n. 3
0
 public void ProcessTreeNode(ITreeNode treeNode, ControlFlowElementData data)
 {
     if (treeNode is IInvocationExpression)
     {
         ProcessInvocationExpression(treeNode as IInvocationExpression, data);
     }
     else if (treeNode is IUsingStatement)
     {
         TreeNodeHandlerUtil.ProcessUsingStatement(treeNode as IUsingStatement, data);
     }
 }
 public IEnumerable<HighlightingInfo> Inspect()
 {
     _elementDataStorage = new ControlFlowElementDataStorage();
     var initialData = new ControlFlowElementData(Graf.EntryElement.Id)
     {
         ThisStatus = VariableDisposeStatus.NotDisposed
     };
     _elementDataStorage[Graf.EntryElement] = initialData;
     var nodeHandlerFactory = new TreeNodeHandlerFactory(_maxLevel, _disposableInterface);
     DoStep(null, Graf.EntryElement, true, nodeHandlerFactory, _elementDataStorage);
     AddHighlightings();
     return _highlightings;
 }
Esempio n. 5
0
        private void ProcessInvocationExpression([NotNull] IInvocationExpression invocationExpression,
            ControlFlowElementData data)
        {
            var invokedExpression = invocationExpression.InvokedExpression as IReferenceExpression;
            if (invokedExpression == null)
                return;
            var isInvocationOnDisposableThis = TreeNodeHandlerUtil.IsInvocationOnDisposableThis(invokedExpression,
                _disposableInterface);
            var qualifierVariableDeclaration = TreeNodeHandlerUtil.GetQualifierVariableDeclaration(invokedExpression);
            var qualifierDisposableVariableDeclaration = data[qualifierVariableDeclaration] != null
                ? qualifierVariableDeclaration
                : null;

            if (TreeNodeHandlerUtil.CheckOnDisposeInvocation(invocationExpression, data, isInvocationOnDisposableThis,
                qualifierDisposableVariableDeclaration))
                return;

            ProcessSimpleInvocation(invocationExpression, data, qualifierDisposableVariableDeclaration,
                isInvocationOnDisposableThis);
        }
Esempio n. 6
0
        private static void CalculatePositionOfDisposableVariables(IInvocationExpression invocationExpression,
            ControlFlowElementData data, List<byte> thisPositions, IDictionary<IVariableDeclaration, byte> positions)
        {
            byte i = 0;
            foreach (var argument in invocationExpression.InvocationExpressionReference.Invocation.Arguments)
            {
                i++;
                var cSharpArgument = argument as ICSharpArgument;
                if (cSharpArgument == null)
                    continue;
                var argumentExpression = cSharpArgument.Value;

                if (argumentExpression is IThisExpression && data.ThisStatus != null)
                {
                    thisPositions.Add(i);
                    continue;
                }
                var varDecl = TreeNodeHandlerUtil.GetVariableDeclarationForReferenceExpression(argumentExpression);
                if (varDecl != null && data[varDecl] != null) // Т.е. если переменную не рассматриваем.
                    positions[varDecl] = i;
            }
        }
Esempio n. 7
0
        private void ProcessSimpleInvocation([NotNull] IInvocationExpression invocationExpression,
            ControlFlowElementData data,
            [CanBeNull] IVariableDeclaration qualifierDisposableVariableDeclaration, bool isInvocationOnDisposableThis,
            int level)
        {
            var connections = new Dictionary<IRegularParameterDeclaration, IVariableDeclaration>();
            var thisConnections = new List<IRegularParameterDeclaration>();
            CalculateConnectionOfDisposableVariables(invocationExpression, data, thisConnections, connections);

            if (!connections.Any() && !thisConnections.Any() && qualifierDisposableVariableDeclaration == null &&
                !isInvocationOnDisposableThis)
                return;

            var methodStatus = GetStatusForInvocationExpressionFromCache(invocationExpression);
            if (methodStatus == null)
                return;

            var parameterDeclarations = Enumerable.ToArray(connections.Keys);
            foreach (var parameterDeclaration in parameterDeclarations)
            {
                var argumentStatus = GetArgumentStatusForParameterDeclaration(parameterDeclaration, methodStatus);
                if (argumentStatus == null)
                    continue;
                switch (argumentStatus.Status)
                {
                    case VariableDisposeStatus.Disposed:
                        data[connections[parameterDeclaration]] = VariableDisposeStatus.Disposed;
                        break;
                    case VariableDisposeStatus.DependsOnInvocation:
                        if (AnyoneInvokedExpressionDispose(argumentStatus.InvokedExpressions, level))
                            data[connections[parameterDeclaration]] = VariableDisposeStatus.Disposed;
                        break;
                }
            }

            //this в качестве аргумента
            var thisParameterDeclarations = Enumerable.ToArray(connections.Keys);
            foreach (var parameterDeclaration in thisParameterDeclarations)
            {
                var argumentStatus = GetArgumentStatusForParameterDeclaration(parameterDeclaration, methodStatus);
                if (argumentStatus == null)
                    continue;
                switch (argumentStatus.Status)
                {
                    case VariableDisposeStatus.Disposed:
                        data.ThisStatus = VariableDisposeStatus.Disposed;
                        break;
                    case VariableDisposeStatus.DependsOnInvocation:
                        if (AnyoneInvokedExpressionDispose(argumentStatus.InvokedExpressions, level))
                            data.ThisStatus = VariableDisposeStatus.Disposed;
                        break;
                }
            }

            //обработка qualifierVariableDeclaration, в том числе this
            if (qualifierDisposableVariableDeclaration != null)
            {
                var argumentStatus = GetArgumentStatusByNumber(methodStatus, 0);
                if (argumentStatus != null)
                {
                    switch (argumentStatus.Status)
                    {
                        case VariableDisposeStatus.Disposed:
                            data[qualifierDisposableVariableDeclaration] = VariableDisposeStatus.Disposed;
                            break;
                        case VariableDisposeStatus.DependsOnInvocation:
                            if (AnyoneInvokedExpressionDispose(argumentStatus.InvokedExpressions, level))
                                data[qualifierDisposableVariableDeclaration] = VariableDisposeStatus.Disposed;
                            break;
                    }
                }
            }
            else if (isInvocationOnDisposableThis)
            {
                var argumentStatus = GetArgumentStatusByNumber(methodStatus, 0);
                if (argumentStatus != null)
                {
                    switch (argumentStatus.Status)
                    {
                        case VariableDisposeStatus.Disposed:
                            data.ThisStatus = VariableDisposeStatus.Disposed;
                            break;
                        case VariableDisposeStatus.DependsOnInvocation:
                            if (AnyoneInvokedExpressionDispose(argumentStatus.InvokedExpressions, level))
                                data.ThisStatus = VariableDisposeStatus.Disposed;
                            break;
                    }
                }
            }
        }
Esempio n. 8
0
 private void ProcessLocalVariableDeclaration([NotNull] ILocalVariableDeclaration variableDeclaration,
     ControlFlowElementData data)
 {
     if (!DisposeUtil.IsWrappedInUsing(variableDeclaration) &&
         DisposeUtil.VariableTypeImplementsDisposable(variableDeclaration, _disposableInterface))
     {
         data[variableDeclaration] = VariableDisposeStatus.NotDisposed;
     }
 }
 private ControlFlowElementDataStorage InitElementDataStorage()
 {
     var elementDataStorage = new ControlFlowElementDataStorage();
     var initialData = new ControlFlowElementData(Graf.EntryElement.Id);
     if (_disposableArguments != null)
         _disposableArguments.ForEach(kvp => initialData[kvp.Key] = VariableDisposeStatus.NotDisposed);
     if (_processThis)
         initialData.ThisStatus = VariableDisposeStatus.NotDisposed;
     elementDataStorage[Graf.EntryElement] = initialData;
     return elementDataStorage;
 }
Esempio n. 10
0
        private void ProcessSimpleInvocation([NotNull] IInvocationExpression invocationExpression,
            ControlFlowElementData data,
            [CanBeNull] IVariableDeclaration qualifierDisposableVariableDeclaration, bool isInvocationOnDisposableThis)
        {
            var positions = new Dictionary<IVariableDeclaration, byte>();
            var thisPositions = new List<byte>();
            CalculatePositionOfDisposableVariables(invocationExpression, data, thisPositions, positions);

            if (!positions.Any() && !thisPositions.Any() && qualifierDisposableVariableDeclaration == null &&
                !isInvocationOnDisposableThis)
                return;

            var referenceExpression = invocationExpression.InvokedExpression as IReferenceExpression;
            if (referenceExpression == null)
                return;
            var nameIdentifier = referenceExpression.NameIdentifier;
            if (nameIdentifier == null)
                return;
            var name = nameIdentifier.Name;
            var offset = InvokedExpressionData.GetOffsetByNode(invocationExpression);
            var sourceFile = invocationExpression.GetSourceFile();

            foreach (var position in positions)
                SaveInvocationData(data, position.Key, position.Value, name, offset, sourceFile);

            //this в качестве аргумента
            if (thisPositions.Any())
                data.ThisStatus = VariableDisposeStatus.DependsOnInvocation;
            foreach (var position in thisPositions)
            {
                var invokedExpression = new InvokedExpressionData(name, offset, position, sourceFile);
                data.ThisInvokedExpressions.Add(invokedExpression);
            }

            //обработка qualifierVariableDeclaration, в том числе this
            if (qualifierDisposableVariableDeclaration != null)
                SaveInvocationData(data, qualifierDisposableVariableDeclaration, 0, name, offset, sourceFile);
            else if (isInvocationOnDisposableThis)
            {
                data.ThisStatus = VariableDisposeStatus.DependsOnInvocation;
                var invokedExpression = new InvokedExpressionData(name, offset, 0, sourceFile);
                data.ThisInvokedExpressions.Add(invokedExpression);
            }
        }