protected override async Task <ImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> > DetermineCascadedSymbolsAsync(
            IPropertySymbol symbol,
            Solution solution,
            IImmutableSet <Project>?projects,
            FindReferencesSearchOptions options,
            FindReferencesCascadeDirection cascadeDirection,
            CancellationToken cancellationToken)
        {
            var baseSymbols = await base.DetermineCascadedSymbolsAsync(
                symbol, solution, projects, options, cascadeDirection, cancellationToken).ConfigureAwait(false);

            var backingFields = symbol.ContainingType.GetMembers()
                                .OfType <IFieldSymbol>()
                                .Where(f => symbol.Equals(f.AssociatedSymbol))
                                .Select(f => ((ISymbol)f, cascadeDirection))
                                .ToImmutableArray();

            var result = baseSymbols.Concat(backingFields);

            if (symbol.GetMethod != null)
            {
                result = result.Add((symbol.GetMethod, cascadeDirection));
            }

            if (symbol.SetMethod != null)
            {
                result = result.Add((symbol.SetMethod, cascadeDirection));
            }

            return(result);
        }
        protected override async Task <ImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> > DetermineCascadedSymbolsAsync(
            IMethodSymbol symbol,
            Solution solution,
            IImmutableSet <Project> projects,
            FindReferencesSearchOptions options,
            FindReferencesCascadeDirection cascadeDirection,
            CancellationToken cancellationToken)
        {
            using var _ = ArrayBuilder <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> .GetInstance(out var result);

            var beginInvoke = symbol.ContainingType.GetMembers(WellKnownMemberNames.DelegateBeginInvokeName).FirstOrDefault();

            if (beginInvoke != null)
            {
                result.Add((beginInvoke, cascadeDirection));
            }

            // All method group references
            foreach (var project in solution.Projects)
            {
                foreach (var document in project.Documents)
                {
                    var changeSignatureService = document.GetLanguageService <AbstractChangeSignatureService>();
                    var cascaded = await changeSignatureService.DetermineCascadedSymbolsFromDelegateInvokeAsync(
                        symbol, document, cancellationToken).ConfigureAwait(false);

                    result.AddRange(cascaded.SelectAsArray(s => (s, cascadeDirection)));
                }
            }

            return(result.ToImmutable());
        }
Esempio n. 3
0
 protected virtual Task <ImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> > DetermineCascadedSymbolsAsync(
     TSymbol symbol, Solution solution, IImmutableSet <Project>?projects,
     FindReferencesSearchOptions options, FindReferencesCascadeDirection cascadeDirection,
     CancellationToken cancellationToken)
 {
     return(SpecializedTasks.EmptyImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)>());
 }
        protected override async Task <ImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> > DetermineCascadedSymbolsAsync(
            IMethodSymbol symbol,
            Solution solution,
            IImmutableSet <Project>?projects,
            FindReferencesSearchOptions options,
            FindReferencesCascadeDirection cascadeDirection,
            CancellationToken cancellationToken)
        {
            // If it's a delegate method, then cascade to the type as well.  These guys are
            // practically equivalent for users.
            if (symbol.ContainingType.TypeKind == TypeKind.Delegate)
            {
                return(ImmutableArray.Create(((ISymbol)symbol.ContainingType, cascadeDirection)));
            }
            else
            {
                var otherPartsOfPartial = GetOtherPartsOfPartial(symbol);
                var baseCascadedSymbols = await base.DetermineCascadedSymbolsAsync(
                    symbol, solution, projects, options, cascadeDirection, cancellationToken).ConfigureAwait(false);

                if (otherPartsOfPartial == null && baseCascadedSymbols == null)
                {
                    return(ImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> .Empty);
                }

                return(otherPartsOfPartial.SelectAsArray(m => (m, cascadeDirection)).Concat(baseCascadedSymbols));
            }
        }
Esempio n. 5
0
        protected override Task <ImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> > DetermineCascadedSymbolsAsync(
            ITypeParameterSymbol symbol,
            Solution solution,
            IImmutableSet <Project>?projects,
            FindReferencesSearchOptions options,
            FindReferencesCascadeDirection cascadeDirection,
            CancellationToken cancellationToken)
        {
            var method  = (IMethodSymbol)symbol.ContainingSymbol;
            var ordinal = method.TypeParameters.IndexOf(symbol);

            if (ordinal >= 0)
            {
                if (method.PartialDefinitionPart != null && ordinal < method.PartialDefinitionPart.TypeParameters.Length)
                {
                    return(Task.FromResult(ImmutableArray.Create(
                                               ((ISymbol)method.PartialDefinitionPart.TypeParameters[ordinal], cascadeDirection))));
                }

                if (method.PartialImplementationPart != null && ordinal < method.PartialImplementationPart.TypeParameters.Length)
                {
                    return(Task.FromResult(ImmutableArray.Create(
                                               ((ISymbol)method.PartialImplementationPart.TypeParameters[ordinal], cascadeDirection))));
                }
            }

            return(SpecializedTasks.EmptyImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)>());
        }
        protected override async Task <ImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> > DetermineCascadedSymbolsAsync(
            IParameterSymbol parameter,
            Solution solution,
            IImmutableSet <Project>?projects,
            FindReferencesSearchOptions options,
            FindReferencesCascadeDirection cascadeDirection,
            CancellationToken cancellationToken)
        {
            if (parameter.IsThis)
            {
                return(ImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> .Empty);
            }

            using var _1 = ArrayBuilder <ISymbol> .GetInstance(out var symbols);

            await CascadeBetweenAnonymousFunctionParametersAsync(solution, parameter, symbols, cancellationToken).ConfigureAwait(false);

            CascadeBetweenPropertyAndAccessorParameters(parameter, symbols);
            CascadeBetweenDelegateMethodParameters(parameter, symbols);
            CascadeBetweenPartialMethodParameters(parameter, symbols);

            using var _2 = ArrayBuilder <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> .GetInstance(symbols.Count, out var result);

            foreach (var symbol in symbols)
            {
                result.Add((symbol, cascadeDirection));
            }

            return(result.ToImmutable());
        }
Esempio n. 7
0
            > DetermineCascadedSymbolsAsync(
            IEventSymbol symbol,
            Solution solution,
            IImmutableSet <Project>?projects,
            FindReferencesSearchOptions options,
            FindReferencesCascadeDirection cascadeDirection,
            CancellationToken cancellationToken
            )
        {
            var baseSymbols = await base.DetermineCascadedSymbolsAsync(
                symbol,
                solution,
                projects,
                options,
                cascadeDirection,
                cancellationToken
                )
                              .ConfigureAwait(false);

            var backingFields = symbol.ContainingType
                                .GetMembers()
                                .OfType <IFieldSymbol>()
                                .Where(f => symbol.Equals(f.AssociatedSymbol))
                                .ToImmutableArray();

            var associatedNamedTypes = symbol.ContainingType
                                       .GetTypeMembers()
                                       .WhereAsArray(n => symbol.Equals(n.AssociatedSymbol));

            return(baseSymbols
                   .Concat(backingFields.SelectAsArray(f => ((ISymbol)f, cascadeDirection)))
                   .Concat(associatedNamedTypes.SelectAsArray(n => ((ISymbol)n, cascadeDirection))));
        }
Esempio n. 8
0
            > DetermineCascadedSymbolsAsync(
            IMethodSymbol symbol,
            Solution solution,
            IImmutableSet <Project>?projects,
            FindReferencesSearchOptions options,
            FindReferencesCascadeDirection cascadeDirection,
            CancellationToken cancellationToken
            )
        {
            var result = await base.DetermineCascadedSymbolsAsync(
                symbol,
                solution,
                projects,
                options,
                cascadeDirection,
                cancellationToken
                )
                         .ConfigureAwait(false);

            // If we've been asked to search for specific accessors, then do not cascade.
            // We don't want to produce results for the associated property.
            if (
                !options.AssociatePropertyReferencesWithSpecificAccessor &&
                symbol.AssociatedSymbol != null
                )
            {
                result = result.Add((symbol.AssociatedSymbol, cascadeDirection));
            }

            return(result);
        }
        private async Task DetermineAllSymbolsCoreAsync(
            ISymbol symbol, FindReferencesCascadeDirection cascadeDirection,
            ConcurrentSet <SymbolGroup> result, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var searchSymbol = MapToAppropriateSymbol(symbol);

            // 2) Try to map this back to source symbol if this was a metadata symbol.
            var sourceSymbol = await SymbolFinder.FindSourceDefinitionAsync(searchSymbol, _solution, cancellationToken).ConfigureAwait(false);

            if (sourceSymbol != null)
            {
                searchSymbol = sourceSymbol;
            }

            Contract.ThrowIfNull(searchSymbol);

            var group = await DetermineSymbolGroupAsync(searchSymbol, cancellationToken).ConfigureAwait(false);

            if (result.Add(group))
            {
                await _progress.OnDefinitionFoundAsync(group, cancellationToken).ConfigureAwait(false);

                // get project to search
                var projects = GetProjectScope();

                cancellationToken.ThrowIfCancellationRequested();

                using var _ = ArrayBuilder <Task> .GetInstance(out var finderTasks);

                foreach (var f in _finders)
                {
                    finderTasks.Add(Task.Factory.StartNew(async() =>
                    {
                        using var _ = ArrayBuilder <Task> .GetInstance(out var symbolTasks);

                        var symbols = await f.DetermineCascadedSymbolsAsync(
                            searchSymbol, _solution, projects, _options, cascadeDirection, cancellationToken).ConfigureAwait(false);
                        AddSymbolTasks(result, symbols, symbolTasks, cancellationToken);

                        // Defer to the language to see if it wants to cascade here in some special way.
                        var symbolProject = _solution.GetProject(searchSymbol.ContainingAssembly);
                        if (symbolProject?.LanguageServices.GetService <ILanguageServiceReferenceFinder>() is { } service)
                        {
                            symbols = await service.DetermineCascadedSymbolsAsync(
                                searchSymbol, symbolProject, cascadeDirection, cancellationToken).ConfigureAwait(false);
                            AddSymbolTasks(result, symbols, symbolTasks, cancellationToken);
                        }

                        cancellationToken.ThrowIfCancellationRequested();

                        await Task.WhenAll(symbolTasks).ConfigureAwait(false);
                    }, cancellationToken, TaskCreationOptions.None, _scheduler).Unwrap());
                }

                await Task.WhenAll(finderTasks).ConfigureAwait(false);
            }
        }
        private async Task <ConcurrentSet <SymbolGroup> > DetermineAllSymbolsAsync(
            ISymbol symbol, FindReferencesCascadeDirection cascadeDirection, CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.FindReference_DetermineAllSymbolsAsync, cancellationToken))
            {
                var result = new ConcurrentSet <SymbolGroup>();
                await DetermineAllSymbolsCoreAsync(symbol, cascadeDirection, result, cancellationToken).ConfigureAwait(false);

                return(result);
            }
        }
 protected override Task <ImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> > DetermineCascadedSymbolsAsync(
     IFieldSymbol symbol,
     Solution solution,
     IImmutableSet <Project>?projects,
     FindReferencesSearchOptions options,
     FindReferencesCascadeDirection cascadeDirection,
     CancellationToken cancellationToken)
 {
     return(symbol.AssociatedSymbol != null
         ? Task.FromResult(ImmutableArray.Create((symbol.AssociatedSymbol, cascadeDirection)))
         : SpecializedTasks.EmptyImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)>());
 }
Esempio n. 12
0
        protected override async Task <ImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> > DetermineCascadedSymbolsAsync(
            TSymbol symbol,
            Solution solution,
            IImmutableSet <Project>?projects,
            FindReferencesSearchOptions options,
            FindReferencesCascadeDirection cascadeDirection,
            CancellationToken cancellationToken)
        {
            // Static methods can't cascade.
            if (symbol.IsStatic)
            {
                return(ImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> .Empty);
            }

            if (symbol.IsImplementableMember())
            {
                // We have an interface method.  Walk down the inheritance hierarchy and find all implementations of
                // that method and cascade to them.
                var result = cascadeDirection.HasFlag(FindReferencesCascadeDirection.Down)
                    ? await SymbolFinder.FindMemberImplementationsArrayAsync(symbol, solution, projects, cancellationToken).ConfigureAwait(false)
                    : ImmutableArray <ISymbol> .Empty;

                return(result.SelectAsArray(s => (s, FindReferencesCascadeDirection.Down)));
            }
            else
            {
                // We have a normal method.  Find any interface methods up the inheritance hierarchy that it implicitly
                // or explicitly implements and cascade to those.
                var interfaceMembersImplemented = cascadeDirection.HasFlag(FindReferencesCascadeDirection.Up)
                    ? await SymbolFinder.FindImplementedInterfaceMembersArrayAsync(symbol, solution, projects, cancellationToken).ConfigureAwait(false)
                    : ImmutableArray <ISymbol> .Empty;

                // Finally, methods can cascade through virtual/override inheritance.  NOTE(cyrusn):
                // We only need to go up or down one level.  Then, when we're finding references on
                // those members, we'll end up traversing the entire hierarchy.
                var overrides = cascadeDirection.HasFlag(FindReferencesCascadeDirection.Down)
                    ? await SymbolFinder.FindOverridesArrayAsync(symbol, solution, projects, cancellationToken).ConfigureAwait(false)
                    : ImmutableArray <ISymbol> .Empty;

                var overriddenMember = cascadeDirection.HasFlag(FindReferencesCascadeDirection.Up)
                    ? symbol.GetOverriddenMember()
                    : null;

                var interfaceMembersImplementedWithDirection = interfaceMembersImplemented.SelectAsArray(s => (s, FindReferencesCascadeDirection.Up));
                var overridesWithDirection        = overrides.SelectAsArray(s => (s, FindReferencesCascadeDirection.Down));
                var overriddenMemberWithDirection = (overriddenMember !, FindReferencesCascadeDirection.Up);

                return(overriddenMember == null
                    ? interfaceMembersImplementedWithDirection.Concat(overridesWithDirection)
                    : interfaceMembersImplementedWithDirection.Concat(overridesWithDirection).Concat(overriddenMemberWithDirection));
            }
        }
        public async Task <ImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> > DetermineCascadedSymbolsAsync(
            ISymbol symbol, Solution solution, IImmutableSet <Project>?projects,
            FindReferencesSearchOptions options, FindReferencesCascadeDirection cascadeDirection,
            CancellationToken cancellationToken)
        {
            if (!options.Cascade)
            {
                return(ImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> .Empty);
            }

            var linkedSymbols = await SymbolFinder.FindLinkedSymbolsAsync(symbol, solution, cancellationToken).ConfigureAwait(false);

            return(linkedSymbols.SelectAsArray(s => (s, cascadeDirection)));
        }
Esempio n. 14
0
        public override Task <ImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> > DetermineCascadedSymbolsAsync(
            ISymbol symbol, Solution solution, IImmutableSet <Project>?projects,
            FindReferencesSearchOptions options, FindReferencesCascadeDirection cascadeDirection,
            CancellationToken cancellationToken)
        {
            if (options.Cascade &&
                symbol is TSymbol typedSymbol &&
                CanFind(typedSymbol))
            {
                return(DetermineCascadedSymbolsAsync(
                           typedSymbol, solution, projects, options, cascadeDirection, cancellationToken));
            }

            return(SpecializedTasks.EmptyImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)>());
        }
Esempio n. 15
0
        protected override Task <ImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> > DetermineCascadedSymbolsAsync(
            IMethodSymbol symbol,
            Solution solution,
            IImmutableSet <Project>?projects,
            FindReferencesSearchOptions options,
            FindReferencesCascadeDirection cascadeDirection,
            CancellationToken cancellationToken)
        {
            if (!cascadeDirection.HasFlag(FindReferencesCascadeDirection.Up))
            {
                return(SpecializedTasks.EmptyImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)>());
            }

            // An explicit interface method will cascade to all the methods that it implements in the up direction.
            return(Task.FromResult(
                       symbol.ExplicitInterfaceImplementations.SelectAsArray(m => ((ISymbol)m, FindReferencesCascadeDirection.Up))));
        }
        protected override Task <ImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> > DetermineCascadedSymbolsAsync(
            INamedTypeSymbol symbol,
            Solution solution,
            IImmutableSet <Project>?projects,
            FindReferencesSearchOptions options,
            FindReferencesCascadeDirection cascadeDirection,
            CancellationToken cancellationToken)
        {
            using var _ = ArrayBuilder <ISymbol> .GetInstance(out var result);

            if (symbol.AssociatedSymbol != null)
            {
                Add(result, ImmutableArray.Create(symbol.AssociatedSymbol));
            }

            // cascade to constructors
            Add(result, symbol.Constructors);

            // cascade to destructor
            Add(result, symbol.GetMembers(WellKnownMemberNames.DestructorName));

            return(Task.FromResult(result.SelectAsArray(s => (s, cascadeDirection))));
        }
Esempio n. 17
0
 public static bool HasFlag(
     this FindReferencesCascadeDirection value,
     FindReferencesCascadeDirection flag
     ) => (value & flag) == flag;
Esempio n. 18
0
 public abstract Task <ImmutableArray <(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> > DetermineCascadedSymbolsAsync(
     ISymbol symbol, Solution solution, IImmutableSet <Project>?projects,
     FindReferencesSearchOptions options, FindReferencesCascadeDirection cascadeDirection,
     CancellationToken cancellationToken);