public override async Task ProduceCompletionListAsync(CompletionListContext context) { var items = await this.GetItemsAsync(context.Document, context.Position, context.TriggerInfo, context.CancellationToken).ConfigureAwait(false); var builder = await this.GetBuilderAsync(context.Document, context.Position, context.TriggerInfo, context.CancellationToken).ConfigureAwait(false); if (items == null && builder == null) { return; } if (items != null) { foreach (var item in items) { context.AddItem(item); } } if (builder != null) { context.RegisterBuilder(builder); } var isExclusive = await this.IsExclusiveAsync(context.Document, context.Position, context.TriggerInfo, context.CancellationToken).ConfigureAwait(false); context.MakeExclusive(isExclusive); }
public override async Task ProduceCompletionListAsync(CompletionListContext context) { var document = context.Document; var position = context.Position; var cancellationToken = context.CancellationToken; var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (syntaxTree.IsInNonUserCode(position, cancellationToken)) { return; } var token = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken); token = token.GetPreviousTokenIfTouchingWord(position); if (!token.IsKind(SyntaxKind.OpenParenToken, SyntaxKind.CommaToken)) { return; } var attributeArgumentList = token.Parent as AttributeArgumentListSyntax; var attributeSyntax = token.Parent.Parent as AttributeSyntax; if (attributeSyntax == null || attributeArgumentList == null) { return; } if (IsAfterNameColonArgument(token) || IsAfterNameEqualsArgument(token)) { context.MakeExclusive(true); } // We actually want to collect two sets of named parameters to present the user. The // normal named parameters that come from the attribute constructors. These will be // presented like "foo:". And also the named parameters that come from the writable // fields/properties in the attribute. These will be presented like "bar =". var existingNamedParameters = GetExistingNamedParameters(attributeArgumentList, position); var workspace = document.Project.Solution.Workspace; var semanticModel = await document.GetSemanticModelForNodeAsync(attributeSyntax, cancellationToken).ConfigureAwait(false); var nameColonItems = await GetNameColonItemsAsync(workspace, semanticModel, position, token, attributeSyntax, existingNamedParameters, cancellationToken).ConfigureAwait(false); var nameEqualsItems = await GetNameEqualsItemsAsync(workspace, semanticModel, position, token, attributeSyntax, existingNamedParameters, cancellationToken).ConfigureAwait(false); context.AddItems(nameEqualsItems); // If we're after a name= parameter, then we only want to show name= parameters. // Otherwise, show name: parameters too. if (!IsAfterNameEqualsArgument(token)) { context.AddItems(nameColonItems); } }
public override async Task ProduceCompletionListAsync(CompletionListContext context) { var document = context.Document; var position = context.Position; var cancellationToken = context.CancellationToken; var workspace = document.Project.Solution.Workspace; var semanticModel = await document.GetSemanticModelForSpanAsync(new TextSpan(position, length : 0), cancellationToken).ConfigureAwait(false); var typeAndLocation = GetInitializedType(document, semanticModel, position, cancellationToken); if (typeAndLocation == null) { return; } var initializedType = typeAndLocation.Item1 as INamedTypeSymbol; var initializerLocation = typeAndLocation.Item2; if (initializedType == null) { return; } if (await IsExclusiveAsync(document, position, cancellationToken).ConfigureAwait(false)) { context.MakeExclusive(true); } var enclosing = semanticModel.GetEnclosingNamedTypeOrAssembly(position, cancellationToken); // Find the members that can be initialized. If we have a NamedTypeSymbol, also get the overridden members. IEnumerable <ISymbol> members = semanticModel.LookupSymbols(position, initializedType); members = members.Where(m => IsInitializable(m, initializedType) && m.CanBeReferencedByName && IsLegalFieldOrProperty(m, enclosing) && !m.IsImplicitlyDeclared); // Filter out those members that have already been typed var alreadyTypedMembers = GetInitializedMembers(semanticModel.SyntaxTree, position, cancellationToken); var uninitializedMembers = members.Where(m => !alreadyTypedMembers.Contains(m.Name)); uninitializedMembers = uninitializedMembers.Where(m => m.IsEditorBrowsable(document.ShouldHideAdvancedMembers(), semanticModel.Compilation)); var text = await semanticModel.SyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false); var filterSpan = GetTextChangeSpan(text, position); foreach (var uninitializedMember in uninitializedMembers) { context.AddItem(CreateItem( workspace, uninitializedMember.Name, filterSpan, CommonCompletionUtilities.CreateDescriptionFactory(workspace, semanticModel, initializerLocation.SourceSpan.Start, uninitializedMember), uninitializedMember.GetGlyph())); } }
public override async Task ProduceCompletionListAsync(CompletionListContext context) { var state = new ItemGetter(this, context.Document, context.Position, context.CancellationToken); var items = await state.GetItemsAsync().ConfigureAwait(false); if (items?.Any() == true) { context.MakeExclusive(true); context.AddItems(items); } }
public override async Task ProduceCompletionListAsync(CompletionListContext context) { var document = context.Document; var position = context.Position; var cancellationToken = context.CancellationToken; var workspace = document.Project.Solution.Workspace; var semanticModel = await document.GetSemanticModelForSpanAsync(new TextSpan(position, length: 0), cancellationToken).ConfigureAwait(false); var typeAndLocation = GetInitializedType(document, semanticModel, position, cancellationToken); if (typeAndLocation == null) { return; } var initializedType = typeAndLocation.Item1 as INamedTypeSymbol; var initializerLocation = typeAndLocation.Item2; if (initializedType == null) { return; } if (await IsExclusiveAsync(document, position, cancellationToken).ConfigureAwait(false)) { context.MakeExclusive(true); } var enclosing = semanticModel.GetEnclosingNamedTypeOrAssembly(position, cancellationToken); // Find the members that can be initialized. If we have a NamedTypeSymbol, also get the overridden members. IEnumerable<ISymbol> members = semanticModel.LookupSymbols(position, initializedType); members = members.Where(m => IsInitializable(m, initializedType) && m.CanBeReferencedByName && IsLegalFieldOrProperty(m, enclosing) && !m.IsImplicitlyDeclared); // Filter out those members that have already been typed var alreadyTypedMembers = GetInitializedMembers(semanticModel.SyntaxTree, position, cancellationToken); var uninitializedMembers = members.Where(m => !alreadyTypedMembers.Contains(m.Name)); uninitializedMembers = uninitializedMembers.Where(m => m.IsEditorBrowsable(document.ShouldHideAdvancedMembers(), semanticModel.Compilation)); var text = await semanticModel.SyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false); var filterSpan = GetTextChangeSpan(text, position); foreach (var uninitializedMember in uninitializedMembers) { context.AddItem(CreateItem( workspace, uninitializedMember.Name, filterSpan, CommonCompletionUtilities.CreateDescriptionFactory(workspace, semanticModel, initializerLocation.SourceSpan.Start, uninitializedMember), uninitializedMember.GetGlyph())); } }
public override async Task ProduceCompletionListAsync(CompletionListContext context) { var document = context.Document; var position = context.Position; var options = context.Options; var cancellationToken = context.CancellationToken; var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (!tree.IsEntirelyWithinCrefSyntax(position, cancellationToken)) { return; } var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken) .GetPreviousTokenIfTouchingWord(position); // To get a Speculative SemanticModel (which is much faster), we need to // walk up to the node the DocumentationTrivia is attached to. var parentNode = token.Parent.FirstAncestorOrSelf <DocumentationCommentTriviaSyntax>()?.ParentTrivia.Token.Parent; if (parentNode == null) { return; } 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.MakeExclusive(true); var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var filterSpan = GetTextChangeSpan(text, position); var items = CreateCompletionItems(document.Project.Solution.Workspace, semanticModel, symbols, token, filterSpan); context.AddItems(items); }
public override async Task ProduceCompletionListAsync(CompletionListContext context) { var document = context.Document; var position = context.Position; var cancellationToken = context.CancellationToken; var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); DeclarationModifiers modifiers; SyntaxToken token; if (!IsPartialCompletionContext(tree, position, cancellationToken, out modifiers, out token)) { return; } var items = await CreatePartialItemsAsync(document, position, modifiers, token, cancellationToken).ConfigureAwait(false); if (items?.Any() == true) { context.MakeExclusive(true); context.AddItems(items); } }
public override async Task ProduceCompletionListAsync(CompletionListContext context) { var document = context.Document; var position = context.Position; var triggerInfo = context.TriggerInfo; var options = context.Options; var cancellationToken = context.CancellationToken; // If we were triggered by typing a character, then do a semantic check to make sure // we're still applicable. If not, then return immediately. if (triggerInfo.TriggerReason == CompletionTriggerReason.TypeCharCommand) { var isSemanticTriggerCharacter = await IsSemanticTriggerCharacterAsync(document, position - 1, cancellationToken).ConfigureAwait(false); if (!isSemanticTriggerCharacter) { return; } } if (IsExclusive()) { context.MakeExclusive(true); } using (Logger.LogBlock(FunctionId.Completion_SymbolCompletionProvider_GetItemsWorker, cancellationToken)) { var regularItems = await GetItemsWorkerAsync(document, position, triggerInfo, options, preselect : false, cancellationToken : cancellationToken).ConfigureAwait(false); context.AddItems(regularItems); var preselectedItems = await GetItemsWorkerAsync(document, position, triggerInfo, options, preselect : true, cancellationToken : cancellationToken).ConfigureAwait(false); context.AddItems(preselectedItems); } }
public override async Task ProduceCompletionListAsync(CompletionListContext context) { var document = context.Document; var position = context.Position; var cancellationToken = context.CancellationToken; var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (syntaxTree.IsInNonUserCode(position, cancellationToken)) { return; } var token = syntaxTree .FindTokenOnLeftOfPosition(position, cancellationToken) .GetPreviousTokenIfTouchingWord(position); if (!token.IsKind(SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken, SyntaxKind.CommaToken)) { return; } var argumentList = token.Parent as BaseArgumentListSyntax; if (argumentList == null) { return; } var semanticModel = await document.GetSemanticModelForNodeAsync(argumentList, cancellationToken).ConfigureAwait(false); var parameterLists = GetParameterLists(semanticModel, position, argumentList.Parent, cancellationToken); if (parameterLists == null) { return; } var existingNamedParameters = GetExistingNamedParameters(argumentList, position); parameterLists = parameterLists.Where(pl => IsValid(pl, existingNamedParameters)); var unspecifiedParameters = parameterLists.SelectMany(pl => pl) .Where(p => !existingNamedParameters.Contains(p.Name)) .Distinct(this); if (!unspecifiedParameters.Any()) { return; } if (token.IsMandatoryNamedParameterPosition()) { context.MakeExclusive(true); } var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var filterSpan = CompletionUtilities.GetTextChangeSpan(text, position); var workspace = document.Project.Solution.Workspace; foreach (var parameter in unspecifiedParameters) { // Note: the filter text does not include the ':'. We want to ensure that if // the user types the name exactly (up to the colon) that it is selected as an // exact match. var escapedName = parameter.Name.ToIdentifierToken().ToString(); context.AddItem(new CompletionItem( this, escapedName + ColonString, filterSpan, CommonCompletionUtilities.CreateDescriptionFactory(workspace, semanticModel, token.SpanStart, parameter), parameter.GetGlyph(), sortText: parameter.Name, filterText: escapedName, rules: ItemRules.Instance)); } }
public override async Task ProduceCompletionListAsync(CompletionListContext context) { var document = context.Document; var position = context.Position; var triggerInfo = context.TriggerInfo; var options = context.Options; var cancellationToken = context.CancellationToken; // If we were triggered by typing a character, then do a semantic check to make sure // we're still applicable. If not, then return immediately. if (triggerInfo.TriggerReason == CompletionTriggerReason.TypeCharCommand) { var isSemanticTriggerCharacter = await IsSemanticTriggerCharacterAsync(document, position - 1, cancellationToken).ConfigureAwait(false); if (!isSemanticTriggerCharacter) { return; } } if (IsExclusive()) { context.MakeExclusive(true); } using (Logger.LogBlock(FunctionId.Completion_SymbolCompletionProvider_GetItemsWorker, cancellationToken)) { var regularItems = await GetItemsWorkerAsync(document, position, triggerInfo, options, preselect: false, cancellationToken: cancellationToken).ConfigureAwait(false); context.AddItems(regularItems); var preselectedItems = await GetItemsWorkerAsync(document, position, triggerInfo, options, preselect: true, cancellationToken: cancellationToken).ConfigureAwait(false); context.AddItems(preselectedItems); } }