private static bool TryResolveDirectiveAttributeInsertionSnippet( string insertText, bool indexerCompletion, AttributeCompletionDescription attributeCompletionDescription, out string snippetText) { const string BoolTypeName = "System.Boolean"; var attributeInfos = attributeCompletionDescription.DescriptionInfos; // Boolean returning bound attribute, auto-complete to just the attribute name. if (attributeInfos.All(info => info.ReturnTypeName == BoolTypeName)) { snippetText = null; return(false); } if (indexerCompletion) { // Indexer completion snippetText = string.Concat(insertText, "$1=\"$2\"$0"); } else { snippetText = string.Concat(insertText, "=\"$1\"$0"); } return(true); }
public override bool TryCreateDescription(AttributeCompletionDescription descriptionInfos, out string markdown) { var associatedAttributeInfos = descriptionInfos.DescriptionInfos; if (associatedAttributeInfos.Count == 0) { markdown = null; return(false); } // This generates a markdown description that looks like the following: // **ReturnTypeName** SomeTypeName.**SomeProperty** // // The Summary documentation text with `CrefTypeValues` in code. // // Additional description infos result in a triple `---` to separate the markdown entries. var descriptionBuilder = new StringBuilder(); for (var i = 0; i < associatedAttributeInfos.Count; i++) { var descriptionInfo = associatedAttributeInfos[i]; if (descriptionBuilder.Length > 0) { descriptionBuilder.AppendLine(); descriptionBuilder.AppendLine("---"); } descriptionBuilder.Append("**"); var returnTypeName = GetSimpleName(descriptionInfo.ReturnTypeName); var reducedReturnTypeName = ReduceTypeName(returnTypeName); descriptionBuilder.Append(reducedReturnTypeName); descriptionBuilder.Append("** "); var tagHelperTypeName = descriptionInfo.TypeName; var reducedTagHelperTypeName = ReduceTypeName(tagHelperTypeName); descriptionBuilder.Append(reducedTagHelperTypeName); descriptionBuilder.Append(".**"); descriptionBuilder.Append(descriptionInfo.PropertyName); descriptionBuilder.AppendLine("**"); descriptionBuilder.AppendLine(); var documentation = descriptionInfo.Documentation; if (!TryExtractSummary(documentation, out var summaryContent)) { continue; } var finalSummaryContent = CleanSummaryContent(summaryContent); descriptionBuilder.AppendLine(finalSummaryContent); } markdown = descriptionBuilder.ToString(); return(true); }
public void CreateClassifiedDescription_SingleDescription_NoSeparator() { // Arrange var factory = new DefaultVisualStudioDescriptionFactory(); var description = new AttributeCompletionDescription(new[] { new AttributeDescriptionInfo("TheReturnType", "TheTypeName", "ThePropertyName", "The documentation"), }); // Act var result = factory.CreateClassifiedDescription(description); // Assert Assert.DoesNotContain(DefaultVisualStudioDescriptionFactory.SeparatorElement, result.Elements); }
public void CreateClassifiedDescription_RepresentsPropertyName() { // Arrange var factory = new DefaultVisualStudioDescriptionFactory(); var description = new AttributeCompletionDescription(new[] { new AttributeDescriptionInfo("TheReturnType", "TheTypeName", "ThePropertyName", "The documentation"), }); // Act var result = factory.CreateClassifiedDescription(description); // Assert var flattened = FlattenToStrings(result); Assert.Contains(description.DescriptionInfos[0].PropertyName, flattened); }
public static void SetDescriptionInfo(this CompletionItem completion, AttributeCompletionDescription attributeDescriptionInfo) { if (completion is null) { throw new ArgumentNullException(nameof(completion)); } if (attributeDescriptionInfo is null) { throw new ArgumentNullException(nameof(attributeDescriptionInfo)); } var data = completion.Data ?? new JObject(); data[AttributeCompletionDataKey] = JObject.FromObject(attributeDescriptionInfo); completion.Data = data; }
public void CreateClassifiedDescription_CanSimplifyKeywordReturnTypes() { // Arrange var factory = new DefaultVisualStudioDescriptionFactory(); var description = new AttributeCompletionDescription(new[] { new AttributeDescriptionInfo("System.String", "TheTypeName", "ThePropertyName", "The documentation"), }); // Act var result = factory.CreateClassifiedDescription(description); // Assert var flattened = FlattenToStrings(result); Assert.DoesNotContain(description.DescriptionInfos[0].ReturnTypeName, flattened); Assert.Contains("string", flattened); }
public override bool TryCreateDescription(AttributeDescriptionInfo attributeDescriptionInfo, out MarkupContent tagHelperDescription) { var convertedDescriptionInfos = new List <RazorAttributeDescriptionInfo>(); foreach (var descriptionInfo in attributeDescriptionInfo.AssociatedAttributeDescriptions) { var tagHelperTypeName = ResolveTagHelperTypeName(descriptionInfo); var converted = new RazorAttributeDescriptionInfo( descriptionInfo.ReturnTypeName, tagHelperTypeName, descriptionInfo.PropertyName, descriptionInfo.Documentation); convertedDescriptionInfos.Add(converted); } var convertedDescriptionInfo = new AttributeCompletionDescription(convertedDescriptionInfos); return(TryCreateDescription(convertedDescriptionInfo, out tagHelperDescription)); }
public void CreateClassifiedDescription_CanRepresentMultipleDescriptions() { // Arrange var factory = new DefaultVisualStudioDescriptionFactory(); var description = new AttributeCompletionDescription(new[] { new AttributeDescriptionInfo("System.String", "TheTypeName", "ThePropertyName", "The documentation"), new AttributeDescriptionInfo("System.Int32", "TheSecondTypeName", "TheSecondPropertyName", "The second documentation"), }); // Act var result = factory.CreateClassifiedDescription(description); // Assert var flattened = FlattenToStrings(result); Assert.Contains(description.DescriptionInfos[0].TypeName, flattened); Assert.Contains(description.DescriptionInfos[1].TypeName, flattened); Assert.Contains(description.DescriptionInfos[0].Documentation, flattened); Assert.Contains(description.DescriptionInfos[1].Documentation, flattened); }
public async Task GetDescriptionAsync_DescriptionData_AsksFactoryForDescription() { // Arrange var expectedResult = new ContainerElement(ContainerElementStyle.Wrapped); var description = new AttributeCompletionDescription(Array.Empty <AttributeDescriptionInfo>()); var descriptionFactory = Mock.Of <VisualStudioDescriptionFactory>(factory => factory.CreateClassifiedDescription(description) == expectedResult); var source = new RazorDirectiveAttributeCompletionSource( Dispatcher, Mock.Of <VisualStudioRazorParser>(), Mock.Of <RazorCompletionFactsService>(), Mock.Of <ICompletionBroker>(), descriptionFactory); var completionSessionSource = Mock.Of <IAsyncCompletionSource>(); var completionItem = new CompletionItem("@random", completionSessionSource); completionItem.Properties.AddProperty(RazorDirectiveAttributeCompletionSource.DescriptionKey, description); // Act var result = await source.GetDescriptionAsync(session : null, completionItem, CancellationToken.None); // Assert Assert.Equal(expectedResult, result); }
public abstract bool TryCreateDescription(AttributeCompletionDescription descriptionInfos, out MarkupContent markupContent);
public abstract bool TryCreateDescription(AttributeCompletionDescription descriptionInfos, out string markdown);
public override ContainerElement CreateClassifiedDescription(AttributeCompletionDescription completionDescription) { if (completionDescription is null) { throw new ArgumentNullException(nameof(completionDescription)); } var descriptionElements = new List <object>(); foreach (var descriptionInfo in completionDescription.DescriptionInfos) { if (descriptionElements.Count > 0) { descriptionElements.Add(SeparatorElement); } var returnTypeClassification = PredefinedClassificationNames.Type; if (KeywordTypeNameLookups.TryGetValue(descriptionInfo.ReturnTypeName, out var returnTypeName)) { returnTypeClassification = PredefinedClassificationNames.Keyword; } else { returnTypeName = descriptionInfo.ReturnTypeName; } var tagHelperTypeName = descriptionInfo.TypeName; var tagHelperTypeNamePrefix = string.Empty; var tagHelperTypeNameProper = tagHelperTypeName; var lastDot = tagHelperTypeName.LastIndexOf('.'); if (lastDot > 0) { var afterLastDot = lastDot + 1; // We're pulling apart the type name so the prefix looks like: // // Microsoft.AspnetCore.Components. tagHelperTypeNamePrefix = tagHelperTypeName.Substring(0, afterLastDot); // And the type name looks like BindBinds tagHelperTypeNameProper = tagHelperTypeName.Substring(afterLastDot); } descriptionElements.Add( new ContainerElement( ContainerElementStyle.Wrapped, PropertyGlyph, new ClassifiedTextElement( new ClassifiedTextRun(returnTypeClassification, returnTypeName), SpaceLiteral, new ClassifiedTextRun(PredefinedClassificationNames.Literal, tagHelperTypeNamePrefix), new ClassifiedTextRun(PredefinedClassificationNames.Type, tagHelperTypeNameProper), DotLiteral, new ClassifiedTextRun(PredefinedClassificationNames.Identifier, descriptionInfo.PropertyName)))); if (descriptionInfo.Documentation != null) { descriptionElements.Add( new ContainerElement( ContainerElementStyle.Wrapped, new ClassifiedTextElement( new ClassifiedTextRun(PredefinedClassificationNames.NaturalLanguage, descriptionInfo.Documentation)))); } } var descriptionContainer = new ContainerElement(ContainerElementStyle.Stacked, descriptionElements); return(descriptionContainer); }
public abstract ContainerElement CreateClassifiedDescription(AttributeCompletionDescription completionDescription);