private bool TryGetTextForSymbol(SyntaxToken token, SemanticModel semanticModel, Document document, CancellationToken cancellationToken, out string text) { ISymbol symbol; if (token.Parent is TypeArgumentListSyntax) { var genericName = token.GetAncestor<GenericNameSyntax>(); symbol = semanticModel.GetSymbolInfo(genericName, cancellationToken).Symbol ?? semanticModel.GetTypeInfo(genericName, cancellationToken).Type; } else if (token.Parent is NullableTypeSyntax && token.IsKind(SyntaxKind.QuestionToken)) { text = "System.Nullable`1"; return true; } else { symbol = semanticModel.GetSemanticInfo(token, document.Project.Solution.Workspace, cancellationToken) .GetAnySymbol(includeType: true); if (symbol == null) { var bindableParent = document.GetLanguageService<ISyntaxFactsService>().GetBindableParent(token); var overloads = semanticModel.GetMemberGroup(bindableParent); symbol = overloads.FirstOrDefault(); } } // Local: return the name if it's the declaration, otherwise the type if (symbol is ILocalSymbol && !symbol.DeclaringSyntaxReferences.Any(d => d.GetSyntax().DescendantTokens().Contains(token))) { symbol = ((ILocalSymbol)symbol).Type; } // Range variable: use the type if (symbol is IRangeVariableSymbol) { var info = semanticModel.GetTypeInfo(token.Parent, cancellationToken); symbol = info.Type; } // Just use syntaxfacts for operators if (symbol is IMethodSymbol && ((IMethodSymbol)symbol).MethodKind == MethodKind.BuiltinOperator) { text = null; return false; } text = symbol != null ? FormatSymbol(symbol) : null; return symbol != null; }