Example #1
0
        protected override void Run(ICSharpTreeNode element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
        {
            var controlFlowGraph = (ICSharpControlFlowGraph)ControlFlowBuilder.GetGraph(element);

            if (controlFlowGraph != null)
            {
                AnalyzeAssertions(data, consumer, element, controlFlowGraph);
            }
        }
        public ICSharpControlFlowGraph GetControlFlowGraph()
        {
            if (!_controlFlowGraphCached)
            {
                if (this.SelectedElement is ICSharpTreeNode)
                {
                    ITreeNode containingGraphOwner = ControlFlowBuilder.GetContainingGraphOwner(this.SelectedElement);
                    if (containingGraphOwner != null)
                    {
                        new CachingNonQualifiedReferencesResolver().Process(containingGraphOwner);
                        _cachedControlFlowGraph = ControlFlowBuilder.GetGraph(containingGraphOwner) as ICSharpControlFlowGraph;
                    }
                }

                _controlFlowGraphCached = true;
            }

            return(_cachedControlFlowGraph);
        }
Example #3
0
        static Location?TryGetLocation([NotNull] ICSharpTreeNode element, [NotNull] ElementProblemAnalyzerData data)
        {
            switch (element.GetContainingFunctionLikeDeclarationOrClosure())
            {
            case IAccessorDeclaration accessorDeclaration:
                switch (accessorDeclaration.Kind)
                {
                case AccessorKind.GETTER:
                    switch (accessorDeclaration.Parent)
                    {
                    case IPropertyDeclaration _:
                        return(Location.PropertyGetter);

                    case IIndexerDeclaration _:
                        return(Location.IndexerGetter);
                    }
                    break;

                case AccessorKind.ADDER:
                case AccessorKind.REMOVER:
                    return(Location.EventAccessor);
                }
                break;

            case IPropertyDeclaration _:
                return(Location.PropertyGetter);

            case IIndexerDeclaration _:
                return(Location.IndexerGetter);

            case IMethodDeclaration methodDeclaration when methodDeclaration.DeclaredElement != null:
                var psiModule = element.GetPsiModule();

                var objectClass = TypeElementUtil.GetTypeElementByClrName(PredefinedType.OBJECT_FQN, psiModule).AssertNotNull();
                if (methodDeclaration.DeclaredElement.OverridesOrImplements(GetMethod(objectClass, nameof(object.Equals))))
                {
                    return(Location.EqualsMethod);
                }
                if (methodDeclaration.DeclaredElement.OverridesOrImplements(GetMethod(objectClass, nameof(GetHashCode))))
                {
                    return(Location.GetHashCodeMethod);
                }
                if (methodDeclaration.DeclaredElement.OverridesOrImplements(GetMethod(objectClass, nameof(ToString))))
                {
                    return(Location.ToStringMethod);
                }

                if (methodDeclaration.DeclaredElement.OverridesOrImplements(
                        GetMethod(
                            TypeElementUtil.GetTypeElementByClrName(PredefinedType.GENERIC_IEQUATABLE_FQN, psiModule).AssertNotNull(),
                            nameof(IEquatable <int> .Equals))))
                {
                    return(Location.EqualsMethod);
                }

                var equalityComparerGenericInterface = TypeElementUtil.GetTypeElementByClrName(ClrTypeNames.IEqualityComparerGeneric, psiModule)
                                                       .AssertNotNull();
                if (methodDeclaration.DeclaredElement.OverridesOrImplements(
                        GetMethod(equalityComparerGenericInterface, nameof(IEqualityComparer <int> .Equals))))
                {
                    return(Location.EqualsMethodWithParameters);
                }
                if (methodDeclaration.DeclaredElement.OverridesOrImplements(
                        GetMethod(equalityComparerGenericInterface, nameof(IEqualityComparer <int> .GetHashCode))))
                {
                    return(Location.GetHashCodeMethodWithParameter);
                }

                var equalityComparerInterface =
                    TypeElementUtil.GetTypeElementByClrName(ClrTypeNames.IEqualityComparer, psiModule).AssertNotNull();
                if (methodDeclaration.DeclaredElement.OverridesOrImplements(
                        GetMethod(equalityComparerInterface, nameof(IEqualityComparer.Equals))))
                {
                    return(Location.EqualsMethodWithParameters);
                }
                if (methodDeclaration.DeclaredElement.OverridesOrImplements(
                        GetMethod(equalityComparerInterface, nameof(IEqualityComparer.GetHashCode))))
                {
                    return(Location.GetHashCodeMethodWithParameter);
                }

                if (methodDeclaration.DeclaredElement.OverridesOrImplements(
                        GetMethod(
                            TypeElementUtil.GetTypeElementByClrName(PredefinedType.IDISPOSABLE_FQN, psiModule).AssertNotNull(),
                            nameof(IDisposable.Dispose))))
                {
                    return(Location.DisposeMethod);
                }

                if (methodDeclaration.DeclaredElement.ShortName == disposeMethodName && methodDeclaration.DeclaredElement.Parameters.Count == 1)
                {
                    var parameter = methodDeclaration.DeclaredElement.Parameters[0];
                    if (parameter != null && parameter.Type.IsBool())
                    {
                        var controlFlowGraph = (ICSharpControlFlowGraph)ControlFlowBuilder.GetGraph(methodDeclaration);

                        var controlFlowEdge = controlFlowGraph?.ReachableExits.FirstOrDefault(
                            e => e?.Type == ControlFlowEdgeType.THROW && e.Source.SourceElement == element);

                        if (controlFlowEdge != null)
                        {
                            var inspector          = CSharpControlFlowGraphInspector.Inspect(controlFlowGraph, data.GetValueAnalysisMode());
                            var controlFlowContext = inspector.GetContext(controlFlowEdge);
                            var variableInfo       = inspector.FindVariableInfo(parameter);
                            if (variableInfo != null)
                            {
                                var variableValue = controlFlowContext?.GetVariableDefiniteState(variableInfo);
                                if (variableValue == null || variableValue == CSharpControlFlowVariableValue.FALSE)
                                {
                                    return(Location.DisposeMethodWithParameterFalseCodePath);
                                }
                            }
                        }
                    }
                }
                break;

            case IConstructorDeclaration constructorDeclaration when constructorDeclaration.IsStatic:
                return(Location.StaticConstructor);

            case IDestructorDeclaration _:
                return(Location.Finalizer);

            case ISignOperatorDeclaration signOperator:
                var tokenType = signOperator.OperatorSign?.GetTokenType();
                if (tokenType == CSharpTokenType.EQEQ || tokenType == CSharpTokenType.NE)
                {
                    return(Location.EqualityOperator);
                }
                break;

            case IConversionOperatorDeclaration conversionOperatorDeclaration
                when conversionOperatorDeclaration.Modifier?.GetTokenType() == CSharpTokenType.IMPLICIT_KEYWORD:
                return(Location.ImplicitCastOperator);
            }

            return(null);
        }