private async Task <IList <SymbolReference> > GetNamespacesForMatchingExtensionMethodsAsync(SearchScope searchScope) { if (!_owner.CanAddImportForMethod(_diagnostic, _syntaxFacts, ref _node)) { return(null); } var expression = _node.Parent; var extensionMethods = SpecializedCollections.EmptyEnumerable <SymbolReference>(); var symbols = await GetSymbolsAsync(searchScope).ConfigureAwait(false); if (symbols != null) { extensionMethods = FilterForExtensionMethods(searchScope, expression, symbols); } var addMethods = SpecializedCollections.EmptyEnumerable <SymbolReference>(); var methodSymbols = await GetAddMethodsAsync(searchScope, expression).ConfigureAwait(false); if (methodSymbols != null) { addMethods = GetProposedNamespaces(searchScope, methodSymbols.Select(s => s.ContainingNamespace)); } return(extensionMethods.Concat(addMethods).ToList()); }
/// <summary> /// Specialized finder for the "Color Color" case. Used when we have "Color.Black" and "Color" /// bound to a Field/Property, but not a type. In this case, we want to look for namespaces /// containing 'Color' as if we import them it can resolve this issue. /// </summary> private async Task <ImmutableArray <SymbolReference> > GetReferencesForMatchingFieldsAndPropertiesAsync( SearchScope searchScope) { searchScope.CancellationToken.ThrowIfCancellationRequested(); if (_owner.CanAddImportForMethod(_diagnostic, _syntaxFacts, _node, out var nameNode) && nameNode != null) { // We have code like "Color.Black". "Color" bound to a 'Color Color' property, and // 'Black' did not bind. We want to find a type called 'Color' that will actually // allow 'Black' to bind. var syntaxFacts = this._document.GetLanguageService <ISyntaxFactsService>(); if (syntaxFacts.IsNameOfMemberAccessExpression(nameNode)) { var expression = syntaxFacts.GetExpressionOfMemberAccessExpression(nameNode.Parent, allowImplicitTarget: true) ?? syntaxFacts.GetTargetOfMemberBinding(nameNode.Parent); if (expression is TSimpleNameSyntax) { // Check if the expression before the dot binds to a property or field. var symbol = this._semanticModel.GetSymbolInfo(expression, searchScope.CancellationToken).GetAnySymbol(); if (symbol?.Kind == SymbolKind.Property || symbol?.Kind == SymbolKind.Field) { // Check if we have the 'Color Color' case. var propertyOrFieldType = symbol.GetSymbolType(); if (propertyOrFieldType is INamedTypeSymbol propertyType && Equals(propertyType.Name, symbol.Name)) { // Try to look up 'Color' as a type. var symbolResults = await searchScope.FindDeclarationsAsync( symbol.Name, (TSimpleNameSyntax)expression, SymbolFilter.Type).ConfigureAwait(false); // Return results that have accessible members. var namedTypeSymbols = OfType <INamedTypeSymbol>(symbolResults); var name = nameNode.GetFirstToken().ValueText; var namespaceResults = namedTypeSymbols.WhereAsArray(sr => HasAccessibleStaticFieldOrProperty(sr.Symbol, name)) .SelectAsArray(sr => sr.WithSymbol(sr.Symbol.ContainingNamespace)); return(this.GetNamespaceSymbolReferences(searchScope, namespaceResults)); } } } } } return(ImmutableArray <SymbolReference> .Empty); }
private async Task <IList <SymbolReference> > GetNamespacesForMatchingExtensionMethodsAsync(SearchScope searchScope) { searchScope.CancellationToken.ThrowIfCancellationRequested(); if (!_owner.CanAddImportForMethod(_diagnostic, _syntaxFacts, _node, out var nameNode)) { return(null); } if (nameNode == null) { return(null); } var symbols = await GetSymbolsAsync(searchScope, nameNode).ConfigureAwait(false); var extensionMethods = FilterForExtensionMethods(searchScope, nameNode.Parent, symbols); return(extensionMethods.ToList()); }