示例#1
0
        private static CompletionDescription DecodeDescription(string encoded)
        {
            var parts = encoded.Split(s_descriptionSeparators).Select(t => t.Unescape('\\')).ToArray();

            var builder = ImmutableArray <TaggedText> .Empty.ToBuilder();

            for (int i = 0; i < parts.Length; i += 2)
            {
                builder.Add(new TaggedText(parts[i], parts[i + 1]));
            }

            return(CompletionDescription.Create(builder.ToImmutable()));
        }
示例#2
0
        public static async Task <CompletionDescription> CreateDescriptionAsync(
            Workspace workspace, SemanticModel semanticModel, int position, IReadOnlyList <ISymbol> symbols, SupportedPlatformData supportedPlatforms, CancellationToken cancellationToken)
        {
            var symbolDisplayService = workspace.Services.GetLanguageServices(semanticModel.Language).GetService <ISymbolDisplayService>();
            var formatter            = workspace.Services.GetLanguageServices(semanticModel.Language).GetService <IDocumentationCommentFormattingService>();

            // TODO(cyrusn): Figure out a way to cancel this.
            var symbol   = symbols[0];
            var sections = await symbolDisplayService.ToDescriptionGroupsAsync(workspace, semanticModel, position, ImmutableArray.Create(symbol), cancellationToken).ConfigureAwait(false);

            if (!sections.ContainsKey(SymbolDescriptionGroups.MainDescription))
            {
                return(CompletionDescription.Empty);
            }

            var textContentBuilder = new List <SymbolDisplayPart>();

            textContentBuilder.AddRange(sections[SymbolDescriptionGroups.MainDescription]);

            switch (symbol.Kind)
            {
            case SymbolKind.Method:
            case SymbolKind.NamedType:
                if (symbols.Count > 1)
                {
                    var overloadCount = symbols.Count - 1;
                    var isGeneric     = symbol.GetArity() > 0;

                    textContentBuilder.AddSpace();
                    textContentBuilder.AddPunctuation("(");
                    textContentBuilder.AddPunctuation("+");
                    textContentBuilder.AddText(NonBreakingSpaceString + overloadCount.ToString());

                    AddOverloadPart(textContentBuilder, overloadCount, isGeneric);

                    textContentBuilder.AddPunctuation(")");
                }

                break;
            }

            AddDocumentationPart(textContentBuilder, symbol, semanticModel, position, formatter, cancellationToken);

            if (sections.ContainsKey(SymbolDescriptionGroups.AwaitableUsageText))
            {
                textContentBuilder.AddRange(sections[SymbolDescriptionGroups.AwaitableUsageText]);
            }

            if (sections.ContainsKey(SymbolDescriptionGroups.AnonymousTypes))
            {
                var parts = sections[SymbolDescriptionGroups.AnonymousTypes];
                if (!parts.IsDefaultOrEmpty)
                {
                    textContentBuilder.AddLineBreak();
                    textContentBuilder.AddLineBreak();
                    textContentBuilder.AddRange(parts);
                }
            }

            if (supportedPlatforms != null)
            {
                textContentBuilder.AddLineBreak();
                textContentBuilder.AddRange(supportedPlatforms.ToDisplayParts());
            }

            return(CompletionDescription.Create(textContentBuilder.Select(p => new TaggedText(SymbolDisplayPartKindTags.GetTag(p.Kind), p.ToString())).ToImmutableArray()));
        }
示例#3
0
        public static async Task <CompletionDescription> CreateDescriptionAsync(
            HostSolutionServices workspaceServices, SemanticModel semanticModel, int position, ISymbol symbol, int overloadCount, SymbolDescriptionOptions options, SupportedPlatformData?supportedPlatforms, CancellationToken cancellationToken)
        {
            var symbolDisplayService = workspaceServices.GetRequiredLanguageService <ISymbolDisplayService>(semanticModel.Language);
            var formatter            = workspaceServices.GetRequiredLanguageService <IDocumentationCommentFormattingService>(semanticModel.Language);

            // TODO(cyrusn): Figure out a way to cancel this.
            var sections = await symbolDisplayService.ToDescriptionGroupsAsync(semanticModel, position, ImmutableArray.Create(symbol), options, cancellationToken).ConfigureAwait(false);

            if (!sections.ContainsKey(SymbolDescriptionGroups.MainDescription))
            {
                return(CompletionDescription.Empty);
            }

            var textContentBuilder = new List <TaggedText>();

            textContentBuilder.AddRange(sections[SymbolDescriptionGroups.MainDescription]);

            switch (symbol.Kind)
            {
            case SymbolKind.Method:
            case SymbolKind.Property:
            case SymbolKind.NamedType:
                if (overloadCount > 0)
                {
                    var isGeneric = symbol.GetArity() > 0;

                    textContentBuilder.AddSpace();
                    textContentBuilder.AddPunctuation("(");
                    textContentBuilder.AddPunctuation("+");
                    textContentBuilder.AddText(NonBreakingSpaceString + overloadCount.ToString());

                    AddOverloadPart(textContentBuilder, overloadCount, isGeneric);

                    textContentBuilder.AddPunctuation(")");
                }

                break;
            }

            AddDocumentationPart(textContentBuilder, symbol, semanticModel, position, formatter, cancellationToken);

            if (sections.TryGetValue(SymbolDescriptionGroups.AwaitableUsageText, out var parts))
            {
                textContentBuilder.AddRange(parts);
            }

            if (sections.TryGetValue(SymbolDescriptionGroups.StructuralTypes, out parts))
            {
                if (!parts.IsDefaultOrEmpty)
                {
                    textContentBuilder.AddLineBreak();
                    textContentBuilder.AddLineBreak();
                    textContentBuilder.AddRange(parts);
                }
            }

            if (supportedPlatforms != null)
            {
                textContentBuilder.AddLineBreak();
                textContentBuilder.AddRange(supportedPlatforms.ToDisplayParts().ToTaggedText());
            }

            return(CompletionDescription.Create(textContentBuilder.AsImmutable()));
        }
示例#4
0
		KeyValuePair<int, int>? GetMatchIndexes(RoslynCompletion completion, CompletionDescription description) {
			if (completion == null || description == null)
				return null;
			if (stringBuilder == null)
				stringBuilder = new StringBuilder();
			else
				stringBuilder.Clear();
			var displayText = completion.DisplayText;
			int matchIndex = -1;
			int index = -1;
			foreach (var part in description.TaggedParts) {
				index++;
				if (part.Tag == TextTags.LineBreak)
					break;
				if (matchIndex < 0) {
					if (!displayText.StartsWith(part.Text))
						continue;
					matchIndex = index;
				}
				else {
					if (!StartsWith(displayText, stringBuilder.Length, part.Text)) {
						// Partial match, could happen if the type is System.Collections.Generic.List<int> but
						// the documentation is using System.Collections.Generic.List<T>.
						return new KeyValuePair<int, int>(matchIndex, index - 1);
					}
				}
				stringBuilder.Append(part.Text);
				if (stringBuilder.Length == displayText.Length) {
					if (stringBuilder.ToString() == completion.DisplayText)
						return new KeyValuePair<int, int>(matchIndex, index);
					break;
				}
				else if (stringBuilder.Length > displayText.Length)
					break;
			}
			return null;
		}