Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't use symbolid in symbol completion #15688

Merged
merged 9 commits into from
Jan 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ private async Task<ImmutableArray<CompletionItem>> GetNameEqualsItemsAsync(
var text = await semanticModel.SyntaxTree.GetTextAsync(context.CancellationToken).ConfigureAwait(false);
var q = from p in attributeNamedParameters
where !existingNamedParameters.Contains(p.Name)
select SymbolCompletionItem.Create(
select SymbolCompletionItem.CreateWithSymbolId(
displayText: p.Name.ToIdentifierToken().ToString() + SpaceEqualsString,
insertionText: null,
symbol: p,
Expand All @@ -165,7 +165,7 @@ private async Task<IEnumerable<CompletionItem>> GetNameColonItemsAsync(
return from pl in parameterLists
from p in pl
where !existingNamedParameters.Contains(p.Name)
select SymbolCompletionItem.Create(
select SymbolCompletionItem.CreateWithSymbolId(
displayText: p.Name.ToIdentifierToken().ToString() + ColonString,
insertionText: null,
symbol: p,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@

namespace Microsoft.CodeAnalysis.CSharp.Completion.Providers
{
internal sealed class CrefCompletionProvider : CommonCompletionProvider
internal sealed class CrefCompletionProvider : AbstractCrefCompletionProvider
{

public static readonly SymbolDisplayFormat QualifiedCrefFormat =
new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Omitted,
Expand Down Expand Up @@ -60,10 +61,33 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
var options = context.Options;
var cancellationToken = context.CancellationToken;

var (token, semanticModel, symbols) = await GetSymbolsAsync(document, position, options, cancellationToken).ConfigureAwait(false);

if (symbols.Length == 0)
{
return;
}

context.IsExclusive = true;

var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
var span = GetCompletionItemSpan(text, position);
var hideAdvancedMembers = options.GetOption(CompletionOptions.HideAdvancedMembers, semanticModel.Language);
var serializedOptions = ImmutableDictionary<string, string>.Empty.Add(HideAdvancedMembers, hideAdvancedMembers.ToString());

var items = CreateCompletionItems(document.Project.Solution.Workspace,
semanticModel, symbols, token, span, position, serializedOptions);

context.AddItems(items);
}

protected override async Task<(SyntaxToken, SemanticModel, ImmutableArray<ISymbol>)> GetSymbolsAsync(
Document document, int position, OptionSet options, CancellationToken cancellationToken)
{
var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
if (!tree.IsEntirelyWithinCrefSyntax(position, cancellationToken))
{
return;
return (default(SyntaxToken), null, ImmutableArray<ISymbol>.Empty);
}

var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken, includeDocumentationComments: true)
Expand All @@ -75,28 +99,18 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
_testSpeculativeNodeCallbackOpt?.Invoke(parentNode);
if (parentNode == null)
{
return;
return (default(SyntaxToken), null, ImmutableArray<ISymbol>.Empty);
}

var semanticModel = await document.GetSemanticModelForNodeAsync(
parentNode, cancellationToken).ConfigureAwait(false);

var symbols = GetSymbols(token, semanticModel, cancellationToken);

symbols = symbols.FilterToVisibleAndBrowsableSymbols(options.GetOption(CompletionOptions.HideAdvancedMembers, semanticModel.Language), semanticModel.Compilation);

if (!symbols.Any())
{
return;
}

context.IsExclusive = true;

var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
var span = GetCompletionItemSpan(text, position);
var symbols = GetSymbols(token, semanticModel, cancellationToken)
.FilterToVisibleAndBrowsableSymbols(
options.GetOption(CompletionOptions.HideAdvancedMembers, semanticModel.Language),
semanticModel.Compilation);

var items = CreateCompletionItems(document.Project.Solution.Workspace, semanticModel, symbols, token, span);
context.AddItems(items);
return (token, semanticModel, symbols);
}

private static bool IsCrefStartContext(SyntaxToken token)
Expand Down Expand Up @@ -230,15 +244,15 @@ private static TextSpan GetCompletionItemSpan(SourceText text, int position)
}

private IEnumerable<CompletionItem> CreateCompletionItems(
Workspace workspace, SemanticModel semanticModel, IEnumerable<ISymbol> symbols, SyntaxToken token, TextSpan itemSpan)
Workspace workspace, SemanticModel semanticModel, IEnumerable<ISymbol> symbols, SyntaxToken token, TextSpan itemSpan, int position, ImmutableDictionary<string, string> options)
{
var builder = SharedPools.Default<StringBuilder>().Allocate();
try
{
foreach (var symbol in symbols)
{
builder.Clear();
yield return CreateItem(workspace, semanticModel, symbol, token, builder);
yield return CreateItem(workspace, semanticModel, symbol, token, position, builder, options);
}
}
finally
Expand All @@ -248,10 +262,8 @@ private IEnumerable<CompletionItem> CreateCompletionItems(
}

private CompletionItem CreateItem(
Workspace workspace, SemanticModel semanticModel, ISymbol symbol, SyntaxToken token, StringBuilder builder)
Workspace workspace, SemanticModel semanticModel, ISymbol symbol, SyntaxToken token, int position, StringBuilder builder, ImmutableDictionary<string, string> options)
{
int position = token.SpanStart;

if (symbol is INamespaceOrTypeSymbol && token.IsKind(SyntaxKind.DotToken))
{
// Handle qualified namespace and type names.
Expand All @@ -262,7 +274,7 @@ private CompletionItem CreateItem(
{
// Handle unqualified namespace and type names, or member names.

builder.Append(symbol.ToMinimalDisplayString(semanticModel, position, CrefFormat));
builder.Append(symbol.ToMinimalDisplayString(semanticModel, token.SpanStart, CrefFormat));

var parameters = symbol.GetParameters();
if (!parameters.IsDefaultOrEmpty)
Expand Down Expand Up @@ -303,18 +315,16 @@ private CompletionItem CreateItem(
.Replace('>', '}')
.ToString();

return SymbolCompletionItem.Create(
return SymbolCompletionItem.CreateWithNameAndKind(
displayText: insertionText,
insertionText: insertionText,
symbol: symbol,
symbols: ImmutableArray.Create(symbol),
contextPosition: position,
sortText: symbolText,
properties: options,
rules: GetRules(insertionText));
}

protected override Task<CompletionDescription> GetDescriptionWorkerAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
=> SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);

private static readonly CharacterSetModificationRule s_WithoutOpenBrace = CharacterSetModificationRule.Create(CharacterSetModificationKind.Remove, '{');
private static readonly CharacterSetModificationRule s_WithoutOpenParen = CharacterSetModificationRule.Create(CharacterSetModificationKind.Remove, '(');

Expand Down Expand Up @@ -342,7 +352,6 @@ private CompletionItemRules GetRules(string displayText)
}
}


private static readonly string InsertionTextProperty = "insertionText";

protected override Task<TextChange?> GetTextChangeAsync(CompletionItem selectedItem, char? ch, CancellationToken cancellationToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
var workspace = document.Project.Solution.Workspace;
var text = await semanticModel.SyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false);

var item = SymbolCompletionItem.Create(
var item = SymbolCompletionItem.CreateWithSymbolId(
displayText: displayText,
insertionText: null,
symbol: alias ?? type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
semanticModel, namePosition, s_signatureDisplayFormat);
var insertionText = displayText;

var item = SymbolCompletionItem.Create(
var item = SymbolCompletionItem.CreateWithSymbolId(
displayText,
insertionText: insertionText,
symbol: member,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
// exact match.
var escapedName = parameter.Name.ToIdentifierToken().ToString();

context.AddItem(SymbolCompletionItem.Create(
context.AddItem(SymbolCompletionItem.CreateWithSymbolId(
displayText: escapedName + ColonString,
insertionText: null,
symbol: parameter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Completion;
Expand Down
4 changes: 3 additions & 1 deletion src/Features/CSharp/Portable/project.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"dependencies": { },
"dependencies": {
"System.ValueTuple": "4.3.0"
},
"frameworks": {
"netstandard1.3": {
"imports": [ "portable-net45+win8", "dotnet" ]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using Microsoft.CodeAnalysis.Options;
using System.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.CodeAnalysis.Completion.Providers
{
abstract class AbstractCrefCompletionProvider : CommonCompletionProvider
{
protected const string HideAdvancedMembers = nameof(HideAdvancedMembers);

protected override async Task<CompletionDescription> GetDescriptionWorkerAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
{
var position = SymbolCompletionItem.GetContextPosition(item);

// What EditorBrowsable settings were we previously passed in (if it mattered)?
bool hideAdvancedMembers = false;
if (item.Properties.TryGetValue(HideAdvancedMembers, out var hideAdvancedMembersString))
{
bool.TryParse(hideAdvancedMembersString, out hideAdvancedMembers);
}

var options = document.Project.Solution.Workspace.Options
.WithChangedOption(new OptionKey(CompletionOptions.HideAdvancedMembers, document.Project.Language), hideAdvancedMembers);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we changing options? why are we not just using the option as defined by the user?

Doing this actually overrides the user's choice here.


var (token, semanticModel, symbols) = await GetSymbolsAsync(document, position, options, cancellationToken).ConfigureAwait(false);
var name = SymbolCompletionItem.GetSymbolName(item);
var kind = SymbolCompletionItem.GetKind(item);
var bestSymbols = symbols.WhereAsArray(s => s.Kind == kind && s.Name == name);
return await SymbolCompletionItem.GetDescriptionAsync(item, bestSymbols, document, semanticModel, cancellationToken).ConfigureAwait(false);
}

protected abstract Task<(SyntaxToken, SemanticModel, ImmutableArray<ISymbol>)> GetSymbolsAsync(
Document document, int position, OptionSet options, CancellationToken cancellationToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ protected override CompletionItem CreateItem(
SyntaxContext context, bool preselect,
SupportedPlatformData supportedPlatformData)
{
return SymbolCompletionItem.Create(
return SymbolCompletionItem.CreateWithSymbolId(
displayText: displayText,
insertionText: insertionText,
filterText: GetFilterText(symbols[0], displayText, context),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)

foreach (var uninitializedMember in uninitializedMembers)
{
context.AddItem(SymbolCompletionItem.Create(
context.AddItem(SymbolCompletionItem.CreateWithSymbolId(
displayText: uninitializedMember.Name,
insertionText: null,
symbol: uninitializedMember,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ private CompletionItem CreateCompletionItem(
{
var displayAndInsertionText = GetDisplayAndInsertionText(symbol, context);

return SymbolCompletionItem.Create(
return SymbolCompletionItem.CreateWithSymbolId(
displayText: displayAndInsertionText.Item1,
insertionText: displayAndInsertionText.Item2,
symbol: symbol,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copyright.


using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Recommendations;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Extensions.ContextQuery;
using Microsoft.CodeAnalysis.Shared.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.CodeAnalysis.Completion.Providers
{
Expand All @@ -35,10 +38,10 @@ protected override async Task<ImmutableArray<ISymbol>> GetPreselectedSymbolsWork
}

var symbols = await recommender.GetRecommendedSymbolsAtPositionAsync(
context.Workspace,
context.SemanticModel,
position,
options,
context.Workspace,
context.SemanticModel,
context.Position,
options,
cancellationToken).ConfigureAwait(false);

// Don't preselect intrinsic type symbols so we can preselect their keywords instead.
Expand All @@ -64,7 +67,7 @@ protected override CompletionItem CreateItem(string displayText, string insertio
rules = rules.WithSelectionBehavior(PreselectedItemSelectionBehavior);
}

return SymbolCompletionItem.Create(
return SymbolCompletionItem.CreateWithNameAndKind(
displayText: displayText,
insertionText: insertionText,
filterText: GetFilterText(symbols[0], displayText, context),
Expand Down Expand Up @@ -100,5 +103,26 @@ private static int ComputeSymbolMatchPriority(ISymbol symbol)

return SymbolMatchPriority.PreferType;
}

protected override async Task<CompletionDescription> GetDescriptionWorkerAsync(
Document document, CompletionItem item, CancellationToken cancellationToken)
{
var position = SymbolCompletionItem.GetContextPosition(item);
var name = SymbolCompletionItem.GetSymbolName(item);
var kind = SymbolCompletionItem.GetKind(item);
var relatedDocumentIds = document.Project.Solution.GetRelatedDocumentIds(document.Id).Concat(document.Id);
var options = document.Project.Solution.Workspace.Options;
var totalSymbols = await base.GetPerContextSymbols(document, position, options, relatedDocumentIds, preselect: false, cancellationToken: cancellationToken).ConfigureAwait(false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why base.?

foreach (var info in totalSymbols)
{
var bestSymbols = info.Item3.Where(s => kind != null && s.Kind == kind && s.Name == name).ToImmutableArray();
if (bestSymbols.Any())
{
return await SymbolCompletionItem.GetDescriptionAsync(item, bestSymbols, document, info.Item2.SemanticModel, cancellationToken).ConfigureAwait(false);
}
}

return CompletionDescription.Empty;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ protected virtual CompletionItem CreateItem(
SyntaxContext context, bool preselect,
SupportedPlatformData supportedPlatformData)
{
return SymbolCompletionItem.Create(
return SymbolCompletionItem.CreateWithSymbolId(
displayText: displayText,
insertionText: insertionText,
filterText: GetFilterText(symbols[0], displayText, context),
Expand All @@ -129,9 +129,6 @@ protected virtual CompletionItem CreateItem(
rules: GetCompletionItemRules(symbols, context));
}

protected override Task<CompletionDescription> GetDescriptionWorkerAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
=> SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);

protected virtual string GetFilterText(ISymbol symbol, string displayText, SyntaxContext context)
{
return (displayText == symbol.Name) ||
Expand All @@ -148,6 +145,9 @@ protected virtual Task<ImmutableArray<ISymbol>> GetPreselectedSymbolsWorker(Synt
return SpecializedTasks.EmptyImmutableArray<ISymbol>();
}

protected override Task<CompletionDescription> GetDescriptionWorkerAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
=> SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);

public override async Task ProvideCompletionsAsync(CompletionContext context)
{
var document = context.Document;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public static CompletionItem Create(
.Add("Modifiers", modifiers.ToString())
.Add("TokenSpanEnd", token.Span.End.ToString());

return SymbolCompletionItem.Create(
return SymbolCompletionItem.CreateWithSymbolId(
displayText: displayText,
symbol: symbol,
glyph: glyph,
Expand Down
Loading