Exemplo n.º 1
0
        static void Analyze([NotNull] IMethodDeclaration methodDeclaration, [NotNull] IHighlightingConsumer consumer)
        {
            if (!methodDeclaration.IsAsync || !methodDeclaration.IsVoidMethodDeclaration())
            {
                return; // not an "async void" method
            }

            var method = methodDeclaration.DeclaredElement;

            if (method == null)
            {
                return; // cannot analyze
            }

            if (method.GetImmediateSuperMembers().Any())
            {
                consumer.AddHighlighting(
                    new AvoidAsyncVoidHighlighting("'void' method overridden or implemented as 'async void'.", methodDeclaration));
                return;
            }

            // find usages
            var psiServices = method.GetPsiServices();

            Debug.Assert(SearchDomainFactory.Instance != null);

            var solutionSearchDomain = SearchDomainFactory.Instance.CreateSearchDomain(psiServices.Solution, false);
            var references           = psiServices.Finder.FindReferences(method, solutionSearchDomain, NullProgressIndicator.Create());

            if (IsPublicSurfaceArea(method))
            {
                if (references.Length > 0)
                {
                    consumer.AddHighlighting(
                        new AvoidAsyncVoidHighlighting("'async void' public surface area method with detected usages.", methodDeclaration));
                }
                else
                {
                    var implicitUseAnnotationProvider = psiServices.GetCodeAnnotationsCache().GetProvider <ImplicitUseAnnotationProvider>();

                    var useKindFlags = implicitUseAnnotationProvider.IsImplicitlyUsed(method);
                    if (useKindFlags == null)
                    {
                        // [UsedImplicitly] annotation not applied
                        consumer.AddHighlighting(
                            new AvoidAsyncVoidHighlighting("'async void' public surface area method without detected usages.", methodDeclaration));
                    }
                }
            }
            else
            {
                var count = references.Count(reference => !reference.AssertNotNull().IsEventTarget());
                if (count > 0)
                {
                    consumer.AddHighlighting(
                        new AvoidAsyncVoidHighlighting(
                            string.Format(
                                "'async void' method used {0} time{1} not as a direct event handler.",
                                count.ToString(),
                                count == 1 ? "" : "s"),
                            methodDeclaration));
                }
            }
        }