public void TryConvert_DirectiveAttribute_Snippet_ReturnsTrue() { // Arrange var completionItem = new RazorCompletionItem("@testDisplay...", "testInsert", RazorCompletionItemKind.DirectiveAttribute); completionItem.SetAttributeCompletionDescription(new AttributeCompletionDescription(new CodeAnalysis.Razor.Completion.AttributeDescriptionInfo[] { new CodeAnalysis.Razor.Completion.AttributeDescriptionInfo("System.String", "System.String", "@testDisplay", "This is docs") })); var descriptionFactory = new Mock <TagHelperDescriptionFactory>(); var completionEndpoint = new RazorCompletionEndpoint(Dispatcher, EmptyDocumentResolver, CompletionFactsService, TagHelperCompletionService, descriptionFactory.Object, LoggerFactory); var capability = new CompletionCapability { CompletionItem = new CompletionItemCapability { SnippetSupport = true } }; completionEndpoint.SetCapability(capability); var expectedInsert = "testInsert$1=\"$2\"$0"; // Act var result = completionEndpoint.TryConvert(completionItem, out var converted); // Assert Assert.True(result); Assert.Equal(completionItem.DisplayText, converted.Label); Assert.Equal(expectedInsert, converted.InsertText); Assert.Equal(completionItem.InsertText, converted.FilterText); Assert.Equal(completionItem.InsertText, converted.SortText); Assert.Null(converted.Detail); Assert.Null(converted.Documentation); Assert.Null(converted.Command); Assert.True(converted.TryGetRazorCompletionKind(out var convertedKind)); Assert.Equal(RazorCompletionItemKind.DirectiveAttribute, convertedKind); }
public void TryConvert_Directive_ReturnsTrue() { // Arrange var completionItem = new RazorCompletionItem("testDisplay", "testInsert", RazorCompletionItemKind.Directive); var description = "Something"; completionItem.SetDirectiveCompletionDescription(new DirectiveCompletionDescription(description)); var descriptionFactory = new Mock <TagHelperDescriptionFactory>(); var completionEndpoint = new RazorCompletionEndpoint(Dispatcher, EmptyDocumentResolver, CompletionFactsService, TagHelperCompletionService, descriptionFactory.Object, LoggerFactory); completionEndpoint.SetCapability(DefaultCapability); // Act var result = completionEndpoint.TryConvert(completionItem, out var converted); // Assert Assert.True(result); Assert.Equal(completionItem.DisplayText, converted.Label); Assert.Equal(completionItem.InsertText, converted.InsertText); Assert.Equal(completionItem.DisplayText, converted.FilterText); Assert.Equal(completionItem.DisplayText, converted.SortText); Assert.Equal(description, converted.Detail); Assert.NotNull(converted.Documentation); Assert.True(converted.TryGetRazorCompletionKind(out var convertedKind)); Assert.Equal(RazorCompletionItemKind.Directive, convertedKind); }
public async Task Handle_Resolve_TagHelperAttribute_ReturnsCompletionItemWithDocumentation() { // Arrange var descriptionFactory = new Mock <TagHelperTooltipFactory>(MockBehavior.Strict); var markdown = new MarkupContent { Kind = MarkupKind.Markdown, Value = "Some Markdown" }; descriptionFactory.Setup(factory => factory.TryCreateTooltip(It.IsAny <AggregateBoundAttributeDescription>(), out markdown)) .Returns(true); var completionEndpoint = new RazorCompletionEndpoint(Dispatcher, EmptyDocumentResolver, CompletionFactsService, descriptionFactory.Object, LoggerFactory); var razorCompletionItem = new RazorCompletionItem("TestItem", "TestItem", RazorCompletionItemKind.TagHelperAttribute); razorCompletionItem.SetAttributeCompletionDescription(new AggregateBoundAttributeDescription(Array.Empty <BoundAttributeDescriptionInfo>())); var completionList = completionEndpoint.CreateLSPCompletionList(new[] { razorCompletionItem }); var completionItem = completionList.Items.Single(); // Act var newCompletionItem = await completionEndpoint.Handle(completionItem, default); // Assert Assert.NotNull(newCompletionItem.Documentation); }
public static void SetTagHelperAttributeDescriptionInfo(this RazorCompletionItem completionItem, AttributeDescriptionInfo attributeDescriptionInfo) { if (completionItem is null) { throw new ArgumentNullException(nameof(completionItem)); } completionItem.Items[TagHelperAttributeCompletionDescriptionKey] = attributeDescriptionInfo; }
public static AttributeDescriptionInfo?GetTagHelperAttributeDescriptionInfo(this RazorCompletionItem completionItem) { if (completionItem is null) { throw new ArgumentNullException(nameof(completionItem)); } var description = completionItem.Items[TagHelperAttributeCompletionDescriptionKey] as AttributeDescriptionInfo; return(description); }
public void TryConvert_Directive_SerializationDoesNotThrow() { // Arrange var completionItem = new RazorCompletionItem("testDisplay", "testInsert", RazorCompletionItemKind.Directive); var description = "Something"; completionItem.SetDirectiveCompletionDescription(new DirectiveCompletionDescription(description)); RazorCompletionEndpoint.TryConvert(completionItem, SupportedCompletionItemKinds, out var converted); // Act & Assert JsonConvert.SerializeObject(converted); }
public void TryGet_SetCompletionList_ReturnsTrue() { // Arrange var completionList = new RazorCompletionItem[1]; var resultId = CompletionListCache.Set(completionList); // Act var result = CompletionListCache.TryGet(resultId, out var retrievedCompletionList); // Assert Assert.True(result); Assert.Same(completionList, retrievedCompletionList); }
public void TryConvert_Directive_SerializationDoesNotThrow() { // Arrange var completionItem = new RazorCompletionItem("testDisplay", "testInsert", RazorCompletionItemKind.Directive); var description = "Something"; completionItem.SetDirectiveCompletionDescription(new DirectiveCompletionDescription(description)); var descriptionFactory = new Mock <TagHelperDescriptionFactory>(); var completionEndpoint = new RazorCompletionEndpoint(Dispatcher, EmptyDocumentResolver, CompletionFactsService, TagHelperCompletionService, descriptionFactory.Object, LoggerFactory); completionEndpoint.SetCapability(DefaultCapability); completionEndpoint.TryConvert(completionItem, out var converted); // Act & Assert JsonConvert.SerializeObject(converted); }
public async Task Handle_Resolve_MarkupTransitionCompletion_ReturnsCompletionItemWithDocumentation() { // Arrange var descriptionFactory = Mock.Of <TagHelperTooltipFactory>(MockBehavior.Strict); var completionEndpoint = new RazorCompletionEndpoint(Dispatcher, EmptyDocumentResolver, CompletionFactsService, descriptionFactory, LoggerFactory); var razorCompletionItem = new RazorCompletionItem("@...", "@", RazorCompletionItemKind.MarkupTransition); razorCompletionItem.SetMarkupTransitionCompletionDescription(new MarkupTransitionCompletionDescription("Test description")); var completionList = completionEndpoint.CreateLSPCompletionList(new[] { razorCompletionItem }); var completionItem = completionList.Items.Single(); // Act var newCompletionItem = await completionEndpoint.Handle(completionItem, default); // Assert Assert.NotNull(newCompletionItem.Documentation); }
public void TryConvert_TagHelperAttribute_ReturnsTrue() { // Arrange var completionItem = new RazorCompletionItem("format", "format", RazorCompletionItemKind.TagHelperAttribute); // Act var result = RazorCompletionEndpoint.TryConvert(completionItem, SupportedCompletionItemKinds, out var converted); // Assert Assert.True(result); Assert.Equal(completionItem.DisplayText, converted.Label); Assert.Equal(completionItem.InsertText, converted.InsertText); Assert.Equal(completionItem.InsertText, converted.FilterText); Assert.Equal(completionItem.InsertText, converted.SortText); Assert.Null(converted.Detail); Assert.Null(converted.Documentation); Assert.Null(converted.Command); }
public void TryConvert_DirectiveAttributeParameter_ReturnsTrue() { // Arrange var completionItem = new RazorCompletionItem("format", "format", RazorCompletionItemKind.DirectiveAttributeParameter); // Act var result = RazorCompletionEndpoint.TryConvert(completionItem, ClientCapabilities, out var converted); // Assert Assert.True(result); Assert.Equal(completionItem.DisplayText, converted.Label); Assert.Equal(completionItem.InsertText, converted.InsertText); Assert.Equal(completionItem.InsertText, converted.FilterText); Assert.Equal(completionItem.InsertText, converted.SortText); Assert.Null(converted.Detail); Assert.Null(converted.Documentation); Assert.Null(converted.Command); }
public void TryConvert_TagHelperAttribute_ReturnsTrue() { // Arrange var completionItem = new RazorCompletionItem("format", "format=\"$0\"", RazorCompletionItemKind.TagHelperAttribute, isSnippet: true); // Act var result = RazorCompletionEndpoint.TryConvert(completionItem, ClientCapabilities, out var converted); // Assert Assert.True(result); Assert.Equal(completionItem.DisplayText, converted.Label); Assert.Equal("format=\"$0\"", converted.InsertText); Assert.Equal(InsertTextFormat.Snippet, converted.InsertTextFormat); Assert.Equal(completionItem.DisplayText, converted.FilterText); Assert.Equal(completionItem.DisplayText, converted.SortText); Assert.Null(converted.Detail); Assert.Null(converted.Documentation); Assert.Null(converted.Command); }
public async Task Handle_Resolve_MarkupTransitionCompletion_ReturnsCompletionItemWithDocumentation() { // Arrange var endpoint = new RazorCompletionResolveEndpoint(LSPTagHelperTooltipFactory, VSLSPTagHelperTooltipFactory, CompletionListCache, LoggerFactory); endpoint.GetRegistration(DefaultClientCapability); var razorCompletionItem = new RazorCompletionItem("@...", "@", RazorCompletionItemKind.MarkupTransition); razorCompletionItem.SetMarkupTransitionCompletionDescription(new MarkupTransitionCompletionDescription("Test description")); var completionList = CreateLSPCompletionList(new[] { razorCompletionItem }); var completionItem = completionList.Items.Single(); var parameters = ConvertToBridgedItem(completionItem); // Act var newCompletionItem = await endpoint.Handle(parameters, default); // Assert Assert.NotNull(newCompletionItem.Documentation); }
public void TryGet_EvictedCompletionList_ReturnsFalse() { // Arrange var initialCompletionList = new RazorCompletionItem[1]; var initialCompletionListResultId = CompletionListCache.Set(initialCompletionList); for (var i = 0; i < CompletionListCache.MaxCacheSize; i++) { // We now fill the completion list cache up until its cache max so that the initial completion list we set gets evicted. CompletionListCache.Set(new RazorCompletionItem[1]); } // Act var result = CompletionListCache.TryGet(initialCompletionListResultId, out var retrievedCompletionList); // Assert Assert.False(result); Assert.Null(retrievedCompletionList); }
public void TryConvert_DirectiveAttribute_ReturnsTrue() { // Arrange var completionItem = new RazorCompletionItem("@testDisplay", "testInsert", RazorCompletionItemKind.DirectiveAttribute, new[] { "=", ":" }); // Act var result = RazorCompletionEndpoint.TryConvert(completionItem, SupportedCompletionItemKinds, out var converted); // Assert Assert.True(result); Assert.Equal(completionItem.DisplayText, converted.Label); Assert.Equal(completionItem.InsertText, converted.InsertText); Assert.Equal(completionItem.InsertText, converted.FilterText); Assert.Equal(completionItem.InsertText, converted.SortText); Assert.Equal(completionItem.CommitCharacters, converted.CommitCharacters); Assert.Null(converted.Detail); Assert.Null(converted.Documentation); Assert.Null(converted.Command); }
public void TryConvert_Directive_ReturnsTrue() { // Arrange var completionItem = new RazorCompletionItem("testDisplay", "testInsert", RazorCompletionItemKind.Directive); var description = "Something"; completionItem.SetDirectiveCompletionDescription(new DirectiveCompletionDescription(description)); // Act var result = RazorCompletionEndpoint.TryConvert(completionItem, SupportedCompletionItemKinds, out var converted); // Assert Assert.True(result); Assert.Equal(completionItem.DisplayText, converted.Label); Assert.Equal(completionItem.InsertText, converted.InsertText); Assert.Equal(completionItem.DisplayText, converted.FilterText); Assert.Equal(completionItem.DisplayText, converted.SortText); Assert.Null(converted.Detail); Assert.Null(converted.Documentation); }
public async Task Handle_Resolve_MarkupTransitionCompletion_ReturnsCompletionItemWithDocumentation() { // Arrange var languageServer = new Mock <ClientNotifierServiceBase>(MockBehavior.Strict); languageServer.Setup(ls => ls.ClientSettings).Returns(new InitializeParams()); var completionEndpoint = new RazorCompletionEndpoint( Dispatcher, EmptyDocumentResolver, CompletionFactsService, LSPTagHelperTooltipFactory, VSLSPTagHelperTooltipFactory, languageServer.Object, LoggerFactory); var razorCompletionItem = new RazorCompletionItem("@...", "@", RazorCompletionItemKind.MarkupTransition); razorCompletionItem.SetMarkupTransitionCompletionDescription(new MarkupTransitionCompletionDescription("Test description")); var completionList = completionEndpoint.CreateLSPCompletionList(new[] { razorCompletionItem }); var completionItem = completionList.Items.Single(); // Act var newCompletionItem = await completionEndpoint.Handle(completionItem, default); // Assert Assert.NotNull(newCompletionItem.Documentation); }
public void TryConvert_DirectiveAttributeParameter_ReturnsTrue() { // Arrange var completionItem = new RazorCompletionItem("format", "format", RazorCompletionItemKind.DirectiveAttributeParameter); completionItem.SetAttributeCompletionDescription(new AttributeCompletionDescription(Array.Empty <CodeAnalysis.Razor.Completion.AttributeDescriptionInfo>())); // Act var result = RazorCompletionEndpoint.TryConvert(completionItem, out var converted); // Assert Assert.True(result); Assert.Equal(completionItem.DisplayText, converted.Label); Assert.Equal(completionItem.InsertText, converted.InsertText); Assert.Equal(completionItem.InsertText, converted.FilterText); Assert.Equal(completionItem.InsertText, converted.SortText); Assert.Null(converted.Detail); Assert.Null(converted.Documentation); Assert.Null(converted.Command); Assert.True(converted.TryGetRazorCompletionKind(out var convertedKind)); Assert.Equal(RazorCompletionItemKind.DirectiveAttributeParameter, convertedKind); }
private IReadOnlyList <RazorCompletionItem> GetElementCompletions( SyntaxNode containingTag, string containingTagName, IEnumerable <KeyValuePair <string, string> > attributes, TagHelperDocumentContext tagHelperDocumentContext) { var ancestors = containingTag.Ancestors(); var(ancestorTagName, ancestorIsTagHelper) = _tagHelperFactsService.GetNearestAncestorTagInfo(ancestors); var elementCompletionContext = new ElementCompletionContext( tagHelperDocumentContext, existingCompletions: Enumerable.Empty <string>(), containingTagName, attributes, ancestorTagName, ancestorIsTagHelper, HtmlFactsService.IsHtmlTagName); var completionItems = new List <RazorCompletionItem>(); var completionResult = _tagHelperCompletionService.GetElementCompletions(elementCompletionContext); foreach (var completion in completionResult.Completions) { var razorCompletionItem = new RazorCompletionItem( displayText: completion.Key, insertText: completion.Key, RazorCompletionItemKind.TagHelperElement, ElementCommitCharacters); var tagHelperDescriptions = completion.Value.Select(tagHelper => new TagHelperDescriptionInfo(tagHelper.GetTypeName(), tagHelper.Documentation)); var elementDescription = new ElementDescriptionInfo(tagHelperDescriptions.ToList()); razorCompletionItem.SetTagHelperElementDescriptionInfo(elementDescription); completionItems.Add(razorCompletionItem); } return(completionItems); }
public void TryConvert_DirectiveAttributeParameter_ReturnsTrue() { // Arrange var completionItem = new RazorCompletionItem("format", "format", RazorCompletionItemKind.DirectiveAttributeParameter); completionItem.SetAttributeCompletionDescription(new AttributeCompletionDescription(Array.Empty<CodeAnalysis.Razor.Completion.AttributeDescriptionInfo>())); var descriptionFactory = new Mock<TagHelperDescriptionFactory>(); var completionEndpoint = new RazorCompletionEndpoint(Dispatcher, EmptyDocumentResolver, CompletionFactsService, TagHelperCompletionService, descriptionFactory.Object, LoggerFactory); // Act var result = completionEndpoint.TryConvert(completionItem, out var converted); // Assert Assert.True(result); Assert.Equal(completionItem.DisplayText, converted.Label); Assert.Equal(completionItem.InsertText, converted.InsertText); Assert.Equal(completionItem.InsertText, converted.FilterText); Assert.Equal(completionItem.InsertText, converted.SortText); Assert.Null(converted.Detail); Assert.Null(converted.Documentation); Assert.Null(converted.Command); Assert.True(converted.TryGetRazorCompletionKind(out var convertedKind)); Assert.Equal(RazorCompletionItemKind.DirectiveAttributeParameter, convertedKind); }
public void TryConvert_TagHelperAttribute_ReturnsTrue() { // Arrange var completionItem = new RazorCompletionItem("format", "format", RazorCompletionItemKind.TagHelperAttribute); completionItem.SetTagHelperAttributeDescriptionInfo(new AttributeDescriptionInfo(Array.Empty <TagHelperAttributeDescriptionInfo>())); // Act var result = RazorCompletionEndpoint.TryConvert(completionItem, out var converted); // Assert Assert.True(result); Assert.Equal(completionItem.DisplayText, converted.Label); Assert.Equal(completionItem.InsertText, converted.InsertText); Assert.Equal(completionItem.InsertText, converted.FilterText); Assert.Equal(completionItem.InsertText, converted.SortText); Assert.Null(converted.Detail); Assert.Null(converted.Documentation); Assert.Null(converted.Command); var descriptionInfo = completionItem.GetTagHelperAttributeDescriptionInfo(); Assert.NotNull(descriptionInfo); }
public void TryConvert_TagHelperAttribute_ForBool_ReturnsTrue() { // Arrange var completionItem = new RazorCompletionItem("format", "format", RazorCompletionItemKind.TagHelperAttribute); var attributeCompletionDescription = new AggregateBoundAttributeDescription(new[] { new BoundAttributeDescriptionInfo("System.Boolean", "Stuff", "format", "SomeDocs") }); completionItem.SetAttributeCompletionDescription(attributeCompletionDescription); // Act var result = RazorCompletionEndpoint.TryConvert(completionItem, ClientCapabilities, out var converted); // Assert Assert.True(result); Assert.Equal(completionItem.DisplayText, converted.Label); Assert.Equal("format", converted.InsertText); Assert.Equal(InsertTextFormat.Plaintext, converted.InsertTextFormat); Assert.Equal(completionItem.InsertText, converted.FilterText); Assert.Equal(completionItem.InsertText, converted.SortText); Assert.Null(converted.Detail); Assert.Null(converted.Documentation); Assert.Null(converted.Command); }
public static AggregateBoundElementDescription?GetTagHelperElementDescriptionInfo(this RazorCompletionItem completionItem) { if (completionItem is null) { throw new ArgumentNullException(nameof(completionItem)); } var description = completionItem.Items[s_tagHelperElementCompletionDescriptionKey] as AggregateBoundElementDescription; return(description); }
// Internal for testing internal static bool TryConvert(RazorCompletionItem razorCompletionItem, out CompletionItem completionItem) { switch (razorCompletionItem.Kind) { case RazorCompletionItemKind.Directive: { // There's not a lot of calculation needed for Directives, go ahead and store the documentation/detail // on the completion item. var descriptionInfo = razorCompletionItem.GetDirectiveCompletionDescription(); var directiveCompletionItem = new CompletionItem() { Label = razorCompletionItem.DisplayText, InsertText = razorCompletionItem.InsertText, FilterText = razorCompletionItem.DisplayText, SortText = razorCompletionItem.DisplayText, Detail = descriptionInfo.Description, Documentation = descriptionInfo.Description, Kind = CompletionItemKind.Struct, }; if (razorCompletionItem == DirectiveAttributeTransitionCompletionItemProvider.TransitionCompletionItem) { directiveCompletionItem.Command = RetriggerCompletionCommand; directiveCompletionItem.Kind = CompletionItemKind.TypeParameter; directiveCompletionItem.Preselect = true; } directiveCompletionItem.SetRazorCompletionKind(razorCompletionItem.Kind); completionItem = directiveCompletionItem; return(true); } case RazorCompletionItemKind.DirectiveAttribute: { var descriptionInfo = razorCompletionItem.GetAttributeCompletionDescription(); var directiveAttributeCompletionItem = new CompletionItem() { Label = razorCompletionItem.DisplayText, InsertText = razorCompletionItem.InsertText, FilterText = razorCompletionItem.InsertText, SortText = razorCompletionItem.InsertText, Kind = CompletionItemKind.TypeParameter, }; var indexerCompletion = razorCompletionItem.DisplayText.EndsWith("..."); if (TryResolveDirectiveAttributeInsertionSnippet(razorCompletionItem.InsertText, indexerCompletion, descriptionInfo, out var snippetText)) { directiveAttributeCompletionItem.InsertText = snippetText; directiveAttributeCompletionItem.InsertTextFormat = InsertTextFormat.Snippet; } directiveAttributeCompletionItem.SetDescriptionInfo(descriptionInfo); directiveAttributeCompletionItem.SetRazorCompletionKind(razorCompletionItem.Kind); completionItem = directiveAttributeCompletionItem; return(true); } case RazorCompletionItemKind.DirectiveAttributeParameter: { var descriptionInfo = razorCompletionItem.GetAttributeCompletionDescription(); var parameterCompletionItem = new CompletionItem() { Label = razorCompletionItem.DisplayText, InsertText = razorCompletionItem.InsertText, FilterText = razorCompletionItem.InsertText, SortText = razorCompletionItem.InsertText, Kind = CompletionItemKind.TypeParameter, }; parameterCompletionItem.SetDescriptionInfo(descriptionInfo); parameterCompletionItem.SetRazorCompletionKind(razorCompletionItem.Kind); completionItem = parameterCompletionItem; return(true); } case RazorCompletionItemKind.MarkupTransition: { var descriptionInfo = razorCompletionItem.GetMarkupTransitionCompletionDescription(); var markupTransitionCompletionItem = new CompletionItem() { Label = razorCompletionItem.DisplayText, InsertText = razorCompletionItem.InsertText, FilterText = razorCompletionItem.DisplayText, SortText = razorCompletionItem.DisplayText, Detail = descriptionInfo.Description, Documentation = descriptionInfo.Description, Kind = CompletionItemKind.TypeParameter, CommitCharacters = new Container <string>(razorCompletionItem.CommitCharacters) }; completionItem = markupTransitionCompletionItem; return(true); } } completionItem = null; return(false); }
private IReadOnlyList <RazorCompletionItem> GetAttributeCompletions( SyntaxNode containingAttribute, string containingTagName, string?selectedAttributeName, IEnumerable <KeyValuePair <string, string> > attributes, TagHelperDocumentContext tagHelperDocumentContext) { var ancestors = containingAttribute.Parent.Ancestors(); var nonDirectiveAttributeTagHelpers = tagHelperDocumentContext.TagHelpers.Where(tagHelper => !tagHelper.BoundAttributes.Any(attribute => attribute.IsDirectiveAttribute())); var filteredContext = TagHelperDocumentContext.Create(tagHelperDocumentContext.Prefix, nonDirectiveAttributeTagHelpers); var(ancestorTagName, ancestorIsTagHelper) = _tagHelperFactsService.GetNearestAncestorTagInfo(ancestors); var attributeCompletionContext = new AttributeCompletionContext( filteredContext, existingCompletions: Enumerable.Empty <string>(), containingTagName, selectedAttributeName, attributes, ancestorTagName, ancestorIsTagHelper, HtmlFactsService.IsHtmlTagName); var completionItems = new List <RazorCompletionItem>(); var completionResult = _tagHelperCompletionService.GetAttributeCompletions(attributeCompletionContext); foreach (var completion in completionResult.Completions) { var filterText = completion.Key; // This is a little bit of a hack because the information returned by _razorTagHelperCompletionService.GetAttributeCompletions // does not have enough information for us to determine if a completion is an indexer completion or not. Therefore we have to // jump through a few hoops below to: // 1. Determine if this specific completion is an indexer based completion // 2. Resolve an appropriate snippet if it is. This is more troublesome because we need to remove the ... suffix to accurately // build a snippet that makes sense for the user to type. var indexerCompletion = filterText.EndsWith("...", StringComparison.Ordinal); if (indexerCompletion) { filterText = filterText.Substring(0, filterText.Length - 3); } var attributeCommitCharacters = ResolveAttributeCommitCharacters(completion.Value, indexerCompletion); var razorCompletionItem = new RazorCompletionItem( displayText: completion.Key, insertText: filterText, RazorCompletionItemKind.TagHelperAttribute, attributeCommitCharacters); var attributeDescriptions = completion.Value.Select(boundAttribute => new TagHelperAttributeDescriptionInfo( boundAttribute.DisplayName, boundAttribute.GetPropertyName(), indexerCompletion ? boundAttribute.IndexerTypeName : boundAttribute.TypeName, boundAttribute.Documentation)); var attributeDescriptionInfo = new AttributeDescriptionInfo(attributeDescriptions.ToList()); razorCompletionItem.SetTagHelperAttributeDescriptionInfo(attributeDescriptionInfo); completionItems.Add(razorCompletionItem); } return(completionItems); }
private IReadOnlyList <RazorCompletionItem> GetAttributeCompletions( SyntaxNode containingAttribute, string containingTagName, string?selectedAttributeName, IEnumerable <KeyValuePair <string, string> > attributes, TagHelperDocumentContext tagHelperDocumentContext, RazorCompletionOptions options) { var ancestors = containingAttribute.Parent.Ancestors(); var nonDirectiveAttributeTagHelpers = tagHelperDocumentContext.TagHelpers.Where(tagHelper => !tagHelper.BoundAttributes.Any(attribute => attribute.IsDirectiveAttribute())); var filteredContext = TagHelperDocumentContext.Create(tagHelperDocumentContext.Prefix, nonDirectiveAttributeTagHelpers); var(ancestorTagName, ancestorIsTagHelper) = _tagHelperFactsService.GetNearestAncestorTagInfo(ancestors); var attributeCompletionContext = new AttributeCompletionContext( filteredContext, existingCompletions: Enumerable.Empty <string>(), containingTagName, selectedAttributeName, attributes, ancestorTagName, ancestorIsTagHelper, HtmlFactsService.IsHtmlTagName); var completionItems = new List <RazorCompletionItem>(); var completionResult = _tagHelperCompletionService.GetAttributeCompletions(attributeCompletionContext); foreach (var completion in completionResult.Completions) { var filterText = completion.Key; // This is a little bit of a hack because the information returned by _razorTagHelperCompletionService.GetAttributeCompletions // does not have enough information for us to determine if a completion is an indexer completion or not. Therefore we have to // jump through a few hoops below to: // 1. Determine if this specific completion is an indexer based completion // 2. Resolve an appropriate snippet if it is. This is more troublesome because we need to remove the ... suffix to accurately // build a snippet that makes sense for the user to type. var indexerCompletion = filterText.EndsWith("...", StringComparison.Ordinal); if (indexerCompletion) { filterText = filterText.Substring(0, filterText.Length - 3); } var attributeContext = ResolveAttributeContext(completion.Value, indexerCompletion, options.SnippetsSupported); var attributeCommitCharacters = ResolveAttributeCommitCharacters(attributeContext); var isSnippet = false; var insertText = filterText; if (TryResolveInsertText(insertText, attributeContext, out var snippetText)) { isSnippet = true; insertText = snippetText; } // We change the sort text depending on the tag name due to TagHelper/non-TagHelper concerns. For instance lets say you have a TagHelper that binds to `input`. // Chances are you're expecting to get every other `input` completion item in addition to the TagHelper completion items and the sort order should be the default // because HTML completion items are 100% as applicable as other items. // // Next assume that we have a TagHelper that binds `custom` (or even `Custom`); this is a special scenario where the user has effectively created a new HTML tag // meaning they're probably expecting to provide all of the attributes necessary for that tag to operate. Meaning, HTML attribute completions are less important. // To make sure we prioritize our attribute completions above all other types of completions we set the priority to high so they're showed in the completion list // above all other completion items. var sortText = HtmlFactsService.IsHtmlTagName(containingTagName) ? CompletionSortTextHelper.DefaultSortPriority : CompletionSortTextHelper.HighSortPriority; var razorCompletionItem = new RazorCompletionItem( displayText: completion.Key, insertText: insertText, sortText: sortText, kind: RazorCompletionItemKind.TagHelperAttribute, commitCharacters: attributeCommitCharacters, isSnippet: isSnippet); var attributeDescriptions = completion.Value.Select(boundAttribute => { var descriptionInfo = BoundAttributeDescriptionInfo.From(boundAttribute, indexerCompletion); return(descriptionInfo); }); var attributeDescriptionInfo = new AggregateBoundAttributeDescription(attributeDescriptions.ToList()); razorCompletionItem.SetAttributeCompletionDescription(attributeDescriptionInfo); completionItems.Add(razorCompletionItem); } return(completionItems); }
// Internal for testing internal static bool TryConvert( RazorCompletionItem razorCompletionItem, IReadOnlyList <ExtendedCompletionItemKinds> supportedItemKinds, out CompletionItem completionItem) { if (razorCompletionItem is null) { throw new ArgumentNullException(nameof(razorCompletionItem)); } var tagHelperCompletionItemKind = CompletionItemKind.TypeParameter; if (supportedItemKinds?.Contains(ExtendedCompletionItemKinds.TagHelper) == true) { tagHelperCompletionItemKind = (CompletionItemKind)ExtendedCompletionItemKinds.TagHelper; } switch (razorCompletionItem.Kind) { case RazorCompletionItemKind.Directive: { var directiveCompletionItem = new CompletionItem() { Label = razorCompletionItem.DisplayText, InsertText = razorCompletionItem.InsertText, FilterText = razorCompletionItem.DisplayText, SortText = razorCompletionItem.DisplayText, Kind = CompletionItemKind.Struct, }; if (razorCompletionItem.CommitCharacters != null && razorCompletionItem.CommitCharacters.Count > 0) { directiveCompletionItem.CommitCharacters = new Container <string>(razorCompletionItem.CommitCharacters); } if (razorCompletionItem == DirectiveAttributeTransitionCompletionItemProvider.TransitionCompletionItem) { directiveCompletionItem.Command = RetriggerCompletionCommand; directiveCompletionItem.Kind = tagHelperCompletionItemKind; } completionItem = directiveCompletionItem; return(true); } case RazorCompletionItemKind.DirectiveAttribute: { var directiveAttributeCompletionItem = new CompletionItem() { Label = razorCompletionItem.DisplayText, InsertText = razorCompletionItem.InsertText, FilterText = razorCompletionItem.InsertText, SortText = razorCompletionItem.InsertText, Kind = tagHelperCompletionItemKind, }; if (razorCompletionItem.CommitCharacters != null && razorCompletionItem.CommitCharacters.Count > 0) { directiveAttributeCompletionItem.CommitCharacters = new Container <string>(razorCompletionItem.CommitCharacters); } completionItem = directiveAttributeCompletionItem; return(true); } case RazorCompletionItemKind.DirectiveAttributeParameter: { var parameterCompletionItem = new CompletionItem() { Label = razorCompletionItem.DisplayText, InsertText = razorCompletionItem.InsertText, FilterText = razorCompletionItem.InsertText, SortText = razorCompletionItem.InsertText, Kind = tagHelperCompletionItemKind, }; completionItem = parameterCompletionItem; return(true); } case RazorCompletionItemKind.MarkupTransition: { var markupTransitionCompletionItem = new CompletionItem() { Label = razorCompletionItem.DisplayText, InsertText = razorCompletionItem.InsertText, FilterText = razorCompletionItem.DisplayText, SortText = razorCompletionItem.DisplayText, Kind = tagHelperCompletionItemKind, }; if (razorCompletionItem.CommitCharacters != null && razorCompletionItem.CommitCharacters.Count > 0) { markupTransitionCompletionItem.CommitCharacters = new Container <string>(razorCompletionItem.CommitCharacters); } completionItem = markupTransitionCompletionItem; return(true); } case RazorCompletionItemKind.TagHelperElement: { var tagHelperElementCompletionItem = new CompletionItem() { Label = razorCompletionItem.DisplayText, InsertText = razorCompletionItem.InsertText, FilterText = razorCompletionItem.InsertText, SortText = razorCompletionItem.InsertText, Kind = tagHelperCompletionItemKind, }; if (razorCompletionItem.CommitCharacters != null && razorCompletionItem.CommitCharacters.Count > 0) { tagHelperElementCompletionItem.CommitCharacters = new Container <string>(razorCompletionItem.CommitCharacters); } completionItem = tagHelperElementCompletionItem; return(true); } case RazorCompletionItemKind.TagHelperAttribute: { var tagHelperAttributeCompletionItem = new CompletionItem() { Label = razorCompletionItem.DisplayText, InsertText = razorCompletionItem.InsertText, FilterText = razorCompletionItem.InsertText, SortText = razorCompletionItem.InsertText, Kind = tagHelperCompletionItemKind, }; if (razorCompletionItem.CommitCharacters != null && razorCompletionItem.CommitCharacters.Count > 0) { tagHelperAttributeCompletionItem.CommitCharacters = new Container <string>(razorCompletionItem.CommitCharacters); } completionItem = tagHelperAttributeCompletionItem; return(true); } } completionItem = null; return(false); }
// Internal for testing internal static bool TryConvert(RazorCompletionItem razorCompletionItem, out CompletionItem completionItem) { if (razorCompletionItem is null) { throw new ArgumentNullException(nameof(razorCompletionItem)); } switch (razorCompletionItem.Kind) { case RazorCompletionItemKind.Directive: { // There's not a lot of calculation needed for Directives, go ahead and store the documentation // on the completion item. var descriptionInfo = razorCompletionItem.GetDirectiveCompletionDescription(); var directiveCompletionItem = new VSLspCompletionItem() { Label = razorCompletionItem.DisplayText, InsertText = razorCompletionItem.InsertText, FilterText = razorCompletionItem.DisplayText, SortText = razorCompletionItem.DisplayText, Documentation = descriptionInfo.Description, Kind = CompletionItemKind.Struct, }; if (razorCompletionItem.CommitCharacters != null && razorCompletionItem.CommitCharacters.Count > 0) { directiveCompletionItem.CommitCharacters = new Container <string>(razorCompletionItem.CommitCharacters); } if (razorCompletionItem == DirectiveAttributeTransitionCompletionItemProvider.TransitionCompletionItem) { directiveCompletionItem.Command = RetriggerCompletionCommand; directiveCompletionItem.Kind = CompletionItemKind.TypeParameter; directiveCompletionItem.Icon = VSLspCompletionItemIcons.TagHelper; } directiveCompletionItem.SetRazorCompletionKind(razorCompletionItem.Kind); completionItem = directiveCompletionItem; return(true); } case RazorCompletionItemKind.DirectiveAttribute: { var descriptionInfo = razorCompletionItem.GetAttributeCompletionDescription(); var directiveAttributeCompletionItem = new VSLspCompletionItem() { Label = razorCompletionItem.DisplayText, InsertText = razorCompletionItem.InsertText, FilterText = razorCompletionItem.InsertText, SortText = razorCompletionItem.InsertText, Kind = CompletionItemKind.TypeParameter, Icon = VSLspCompletionItemIcons.TagHelper, }; if (razorCompletionItem.CommitCharacters != null && razorCompletionItem.CommitCharacters.Count > 0) { directiveAttributeCompletionItem.CommitCharacters = new Container <string>(razorCompletionItem.CommitCharacters); } directiveAttributeCompletionItem.SetDescriptionInfo(descriptionInfo); directiveAttributeCompletionItem.SetRazorCompletionKind(razorCompletionItem.Kind); completionItem = directiveAttributeCompletionItem; return(true); } case RazorCompletionItemKind.DirectiveAttributeParameter: { var descriptionInfo = razorCompletionItem.GetAttributeCompletionDescription(); var parameterCompletionItem = new VSLspCompletionItem() { Label = razorCompletionItem.DisplayText, InsertText = razorCompletionItem.InsertText, FilterText = razorCompletionItem.InsertText, SortText = razorCompletionItem.InsertText, Kind = CompletionItemKind.TypeParameter, Icon = VSLspCompletionItemIcons.TagHelper, }; parameterCompletionItem.SetDescriptionInfo(descriptionInfo); parameterCompletionItem.SetRazorCompletionKind(razorCompletionItem.Kind); completionItem = parameterCompletionItem; return(true); } case RazorCompletionItemKind.MarkupTransition: { var descriptionInfo = razorCompletionItem.GetMarkupTransitionCompletionDescription(); var markupTransitionCompletionItem = new VSLspCompletionItem() { Label = razorCompletionItem.DisplayText, InsertText = razorCompletionItem.InsertText, FilterText = razorCompletionItem.DisplayText, SortText = razorCompletionItem.DisplayText, Documentation = descriptionInfo.Description, Kind = CompletionItemKind.TypeParameter, Icon = VSLspCompletionItemIcons.TagHelper, }; if (razorCompletionItem.CommitCharacters != null && razorCompletionItem.CommitCharacters.Count > 0) { markupTransitionCompletionItem.CommitCharacters = new Container <string>(razorCompletionItem.CommitCharacters); } completionItem = markupTransitionCompletionItem; return(true); } case RazorCompletionItemKind.TagHelperElement: { var tagHelperElementCompletionItem = new VSLspCompletionItem() { Label = razorCompletionItem.DisplayText, InsertText = razorCompletionItem.InsertText, FilterText = razorCompletionItem.InsertText, SortText = razorCompletionItem.InsertText, Kind = CompletionItemKind.TypeParameter, Icon = VSLspCompletionItemIcons.TagHelper, }; if (razorCompletionItem.CommitCharacters != null && razorCompletionItem.CommitCharacters.Count > 0) { tagHelperElementCompletionItem.CommitCharacters = new Container <string>(razorCompletionItem.CommitCharacters); } var descriptionInfo = razorCompletionItem.GetTagHelperElementDescriptionInfo(); tagHelperElementCompletionItem.SetDescriptionInfo(descriptionInfo); completionItem = tagHelperElementCompletionItem; return(true); } case RazorCompletionItemKind.TagHelperAttribute: { var tagHelperAttributeCompletionItem = new VSLspCompletionItem() { Label = razorCompletionItem.DisplayText, InsertText = razorCompletionItem.InsertText, FilterText = razorCompletionItem.InsertText, SortText = razorCompletionItem.InsertText, Kind = CompletionItemKind.TypeParameter, Icon = VSLspCompletionItemIcons.TagHelper, }; if (razorCompletionItem.CommitCharacters != null && razorCompletionItem.CommitCharacters.Count > 0) { tagHelperAttributeCompletionItem.CommitCharacters = new Container <string>(razorCompletionItem.CommitCharacters); } var descriptionInfo = razorCompletionItem.GetTagHelperAttributeDescriptionInfo(); tagHelperAttributeCompletionItem.SetDescriptionInfo(descriptionInfo); completionItem = tagHelperAttributeCompletionItem; return(true); } } completionItem = null; return(false); }
public static void SetTagHelperElementDescriptionInfo(this RazorCompletionItem completionItem, ElementDescriptionInfo elementDescriptionInfo) { completionItem.Items[TagHelperElementCompletionDescriptionKey] = elementDescriptionInfo; }
public static void SetTagHelperElementDescriptionInfo(this RazorCompletionItem completionItem, AggregateBoundElementDescription elementDescriptionInfo) { completionItem.Items[s_tagHelperElementCompletionDescriptionKey] = elementDescriptionInfo; }