private static ExpressionSyntax?ShouldCheck(SyntaxNodeAnalysisContext context)
        {
            return(context.Node switch
            {
                InvocationExpressionSyntax {
                    Expression : MemberAccessExpressionSyntax {
                        Expression : { } expression, Name : { Identifier : { ValueText : "Schedule" } }
                    }
                }
                when context.SemanticModel.TryGetNamedType(expression, context.CancellationToken, out var type) &&
                type.IsAssignableTo(KnownSymbol.RxIScheduler, context.SemanticModel.Compilation)
                => null,
                InvocationExpressionSyntax invocation
                => invocation,
                ObjectCreationExpressionSyntax objectCreation
                => objectCreation,
                MemberAccessExpressionSyntax
                {
                    Expression : { } expression
                }

                when context.SemanticModel.TryGetSymbol(expression, context.CancellationToken, out IPropertySymbol?property) &&
                Disposable.IsPotentiallyAssignableFrom(property.Type, context.Compilation)
                => expression,
                ConditionalAccessExpressionSyntax
                {
                    Expression : { } expression
                }

                when context.SemanticModel.TryGetSymbol(expression, context.CancellationToken, out IPropertySymbol?property) &&
                Disposable.IsPotentiallyAssignableFrom(property.Type, context.Compilation)
                => expression,
                _ => null,
            });
        private static void HandleProperty(SyntaxNodeAnalysisContext context)
        {
            if (context.IsExcludedFromAnalysis())
            {
                return;
            }

            var property = (IPropertySymbol)context.ContainingSymbol;

            if (property.IsStatic ||
                property.IsIndexer)
            {
                return;
            }

            var propertyDeclaration = (PropertyDeclarationSyntax)context.Node;

            if (propertyDeclaration.ExpressionBody != null)
            {
                return;
            }

            if (propertyDeclaration.TryGetSetter(out var setter) &&
                setter.Body != null)
            {
                // Handle the backing field
                return;
            }

            if (FieldOrProperty.TryCreate(property, out var fieldOrProperty) &&
                Disposable.IsPotentiallyAssignableFrom(property.Type, context.Compilation))
            {
                HandleFieldOrProperty(context, fieldOrProperty);
            }
        }
        private static void Handle(SyntaxNodeAnalysisContext context)
        {
            if (!context.IsExcludedFromAnalysis() &&
                context.Node is ArgumentSyntax argument &&
                argument.Parent is ArgumentListSyntax argumentList &&
                argumentList.Parent is InvocationExpressionSyntax invocation &&
                argument.RefOrOutKeyword.IsEither(SyntaxKind.RefKeyword, SyntaxKind.OutKeyword) &&
                context.SemanticModel.TryGetSymbol(invocation, context.CancellationToken, out var method) &&
                method.TrySingleDeclaration(context.CancellationToken, out BaseMethodDeclarationSyntax declaration) &&
                method.TryFindParameter(argument, out var parameter) &&
                Disposable.IsPotentiallyAssignableFrom(parameter.Type, context.Compilation))
            {
                if (Disposable.IsCreation(argument, context.SemanticModel, context.CancellationToken).IsEither(Result.Yes, Result.AssumeYes) &&
                    !Disposable.IsAddedToFieldOrProperty(parameter, declaration, context.SemanticModel, context.CancellationToken) &&
                    context.SemanticModel.TryGetSymbol(argument.Expression, context.CancellationToken, out ISymbol symbol))
                {
                    if (LocalOrParameter.TryCreate(symbol, out var localOrParameter) &&
                        Disposable.ShouldDispose(localOrParameter, argument.Expression, context.SemanticModel, context.CancellationToken))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(IDISP001DisposeCreated.Descriptor, argument.GetLocation()));
                    }

                    if (Disposable.IsAssignedWithCreated(symbol, invocation, context.SemanticModel, context.CancellationToken).IsEither(Result.Yes, Result.AssumeYes) &&
                        !Disposable.IsDisposedBefore(symbol, invocation, context.SemanticModel, context.CancellationToken))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(IDISP003DisposeBeforeReassigning.Descriptor, argument.GetLocation()));
                    }
                }
            }
        }
 private static void HandleField(SyntaxNodeAnalysisContext context)
 {
     if (!context.IsExcludedFromAnalysis() &&
         context.ContainingSymbol is IFieldSymbol {
         IsStatic : false, IsConst : false
     } field&&
         context.Node is FieldDeclarationSyntax declaration &&
         Disposable.IsPotentiallyAssignableFrom(field.Type, context.Compilation))
     {
         HandleFieldOrProperty(context, new FieldOrPropertyAndDeclaration(field, declaration));
     }
 }
 private static void HandleField(SyntaxNodeAnalysisContext context)
 {
     if (!context.IsExcludedFromAnalysis() &&
         context.ContainingSymbol is IFieldSymbol field &&
         !field.IsStatic &&
         !field.IsConst &&
         FieldOrProperty.TryCreate(field, out var fieldOrProperty) &&
         Disposable.IsPotentiallyAssignableFrom(field.Type, context.Compilation))
     {
         HandleFieldOrProperty(context, fieldOrProperty);
     }
 }
Beispiel #6
0
        private static void Handle(SyntaxNodeAnalysisContext context)
        {
            if (context.IsExcludedFromAnalysis())
            {
                return;
            }

            if (context.Node is InvocationExpressionSyntax invocation &&
                Disposable.IsCreation(invocation, context.SemanticModel, context.CancellationToken).IsEither(Result.Yes, Result.AssumeYes) &&
                Disposable.IsIgnored(invocation, context.SemanticModel, context.CancellationToken))
            {
                context.ReportDiagnostic(Diagnostic.Create(Descriptor, context.Node.GetLocation()));
            }

            if (context.Node is MemberAccessExpressionSyntax memberAccess &&
                context.SemanticModel.TryGetSymbol(memberAccess.Expression, context.CancellationToken, out IPropertySymbol property) &&
                Disposable.IsPotentiallyAssignableFrom(property.Type, context.Compilation) &&
                Disposable.IsCreation(memberAccess.Expression, context.SemanticModel, context.CancellationToken).IsEither(Result.Yes, Result.AssumeYes) &&
                Disposable.IsIgnored(memberAccess.Expression, context.SemanticModel, context.CancellationToken))
            {
                context.ReportDiagnostic(Diagnostic.Create(Descriptor, context.Node.GetLocation()));
            }
        }