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); }
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); }