public override void Initialize(AnalysisContext analysisContext) { analysisContext.EnableConcurrentExecution(); analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); analysisContext.RegisterCompilationStartAction( (context) => { INamedTypeSymbol iCollectionType = WellKnownTypes.ICollection(context.Compilation); INamedTypeSymbol genericICollectionType = WellKnownTypes.GenericICollection(context.Compilation); INamedTypeSymbol iEnumerableType = WellKnownTypes.IEnumerable(context.Compilation); INamedTypeSymbol genericIEnumerableType = WellKnownTypes.GenericIEnumerable(context.Compilation); INamedTypeSymbol iListType = WellKnownTypes.IList(context.Compilation); INamedTypeSymbol genericIListType = WellKnownTypes.GenericIList(context.Compilation); if (iCollectionType == null && genericICollectionType == null && iEnumerableType == null && genericIEnumerableType == null && iListType == null && genericIListType == null) { return; } context.RegisterSymbolAction(c => AnalyzeSymbol(c, iCollectionType, genericICollectionType, iEnumerableType, genericIEnumerableType, iListType, genericIListType), SymbolKind.NamedType); }); }
private static ImmutableHashSet <INamedTypeSymbol> GetWellKnownCollectionTypes(Compilation compilation) { var builder = ImmutableHashSet.CreateBuilder <INamedTypeSymbol>(); var iCollection = WellKnownTypes.ICollection(compilation); if (iCollection != null) { builder.Add(iCollection); } var genericICollection = WellKnownTypes.GenericICollection(compilation); if (genericICollection != null) { builder.Add(genericICollection); } var genericIReadOnlyCollection = WellKnownTypes.GenericIReadOnlyCollection(compilation); if (genericIReadOnlyCollection != null) { builder.Add(genericIReadOnlyCollection); } return(builder.ToImmutable()); }
/// <summary> /// Initializes a new instance of the <see cref="OperationActionsContext"/> class. /// </summary> /// <param name="compilation">The compilation.</param> /// <param name="enumerableType">Type of the enumerable.</param> public OperationActionsContext(Compilation compilation, INamedTypeSymbol enumerableType) { Compilation = compilation; EnumerableType = enumerableType; _immutableArrayType = new Lazy <INamedTypeSymbol>(() => WellKnownTypes.ImmutableArray(Compilation), true); _iCollectionCountProperty = new Lazy <IPropertySymbol>(ResolveICollectionCountProperty, true); _iCollectionOfType = new Lazy <INamedTypeSymbol>(() => WellKnownTypes.GenericICollection(Compilation), true); }
public override void Initialize(AnalysisContext analysisContext) { analysisContext.EnableConcurrentExecution(); analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); analysisContext.RegisterCompilationStartAction( (context) => { INamedTypeSymbol iCollectionType = WellKnownTypes.ICollection(context.Compilation); INamedTypeSymbol genericICollectionType = WellKnownTypes.GenericICollection(context.Compilation); INamedTypeSymbol arrayType = WellKnownTypes.Array(context.Compilation); INamedTypeSymbol dataMemberAttribute = WellKnownTypes.DataMemberAttribute(context.Compilation); ImmutableHashSet <INamedTypeSymbol> immutableInterfaces = WellKnownTypes.IImmutableInterfaces(context.Compilation); if (iCollectionType == null || genericICollectionType == null || arrayType == null) { return; } context.RegisterSymbolAction(c => AnalyzeSymbol(c, iCollectionType, genericICollectionType, arrayType, dataMemberAttribute, immutableInterfaces), SymbolKind.Property); }); }
public override void Initialize(AnalysisContext context) { context.EnableConcurrentExecution(); context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); context.RegisterCompilationStartAction(compilationContext => { var iDisposable = WellKnownTypes.IDisposable(compilationContext.Compilation); if (iDisposable == null) { return; } var iCollection = WellKnownTypes.ICollection(compilationContext.Compilation); var genericICollection = WellKnownTypes.GenericICollection(compilationContext.Compilation); var disposeOwnershipTransferLikelyTypes = GetDisposeOwnershipTransferLikelyTypes(compilationContext.Compilation); compilationContext.RegisterOperationBlockStartAction(operationBlockStartContext => { bool hasDisposableCreation = false; operationBlockStartContext.RegisterOperationAction(operationContext => { if (!hasDisposableCreation && operationContext.Operation.Type.IsDisposable(iDisposable)) { hasDisposableCreation = true; } }, OperationKind.ObjectCreation, OperationKind.TypeParameterObjectCreation, OperationKind.DynamicObjectCreation, OperationKind.Invocation); operationBlockStartContext.RegisterOperationBlockEndAction(operationBlockEndContext => { if (!hasDisposableCreation || !(operationBlockEndContext.OwningSymbol is IMethodSymbol containingMethod)) { return; } foreach (var operationRoot in operationBlockEndContext.OperationBlocks) { IBlockOperation topmostBlock = operationRoot.GetTopmostParentBlock(); if (topmostBlock != null) { var cfg = ControlFlowGraph.Create(topmostBlock); var nullAnalysisResult = NullAnalysis.GetOrComputeResult(cfg, containingMethod.ContainingType); var pointsToAnalysisResult = PointsToAnalysis.GetOrComputeResult(cfg, containingMethod.ContainingType, nullAnalysisResult); var disposeAnalysisResult = DisposeAnalysis.GetOrComputeResult(cfg, iDisposable, iCollection, genericICollection, disposeOwnershipTransferLikelyTypes, containingMethod.ContainingType, pointsToAnalysisResult, nullAnalysisResult); ImmutableDictionary <AbstractLocation, DisposeAbstractValue> disposeDataAtExit = disposeAnalysisResult[cfg.Exit].InputData; foreach (var kvp in disposeDataAtExit) { AbstractLocation location = kvp.Key; DisposeAbstractValue disposeValue = kvp.Value; if (disposeValue.Kind == DisposeAbstractValueKind.NotDisposed || ((disposeValue.Kind == DisposeAbstractValueKind.Disposed || disposeValue.Kind == DisposeAbstractValueKind.MaybeDisposed) && disposeValue.DisposingOperations.Count > 0 && disposeValue.DisposingOperations.All(d => d.IsInsideCatchClause()))) { Debug.Assert(location.CreationOpt != null); // CA2000: In method '{0}', call System.IDisposable.Dispose on object created by '{1}' before all references to it are out of scope. var arg1 = containingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat); var arg2 = location.CreationOpt.Syntax.ToString(); var diagnostic = location.CreationOpt.Syntax.CreateDiagnostic(Rule, arg1, arg2); operationBlockEndContext.ReportDiagnostic(diagnostic); } } break; } } }); }); }); }