public async Task <ImmutableArray <InlineHint> > GetInlineHintsAsync(
            Document document, TextSpan textSpan, CancellationToken cancellationToken)
        {
            var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);

            var displayAllOverride = options.GetOption(InlineHintsOptions.DisplayAllOverride);
            var enabledForTypes    = options.GetOption(InlineHintsOptions.EnabledForTypes);

            if (!enabledForTypes && !displayAllOverride)
            {
                return(ImmutableArray <InlineHint> .Empty);
            }

            var forImplicitVariableTypes = enabledForTypes && options.GetOption(InlineHintsOptions.ForImplicitVariableTypes);
            var forLambdaParameterTypes  = enabledForTypes && options.GetOption(InlineHintsOptions.ForLambdaParameterTypes);

            if (!forImplicitVariableTypes && !forLambdaParameterTypes && !displayAllOverride)
            {
                return(ImmutableArray <InlineHint> .Empty);
            }

            var anonymousTypeService = document.GetRequiredLanguageService <IAnonymousTypeDisplayService>();
            var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            using var _1 = ArrayBuilder <InlineHint> .GetInstance(out var result);

            foreach (var node in root.DescendantNodes(n => n.Span.IntersectsWith(textSpan)))
            {
                var hintOpt = TryGetTypeHint(
                    semanticModel, node,
                    displayAllOverride,
                    forImplicitVariableTypes,
                    forLambdaParameterTypes,
                    cancellationToken);
                if (hintOpt == null)
                {
                    continue;
                }

                var(type, span) = hintOpt.Value;

                using var _2 = ArrayBuilder <SymbolDisplayPart> .GetInstance(out var finalParts);

                var parts = type.ToDisplayParts(s_minimalTypeStyle);

                AddParts(anonymousTypeService, finalParts, parts, semanticModel, span.Start);
                result.Add(new InlineHint(
                               span, finalParts.ToTaggedText(),
                               InlineHintHelpers.GetDescriptionFunction(span.Start, type.GetSymbolKey())));
            }

            return(result.ToImmutable());
        }
Beispiel #2
0
        public async Task <ImmutableArray <InlineHint> > GetInlineHintsAsync(
            Document document, TextSpan textSpan, InlineTypeHintsOptions options, SymbolDescriptionOptions displayOptions, CancellationToken cancellationToken)
        {
            // TODO: https://github.com/dotnet/roslyn/issues/57283
            var globalOptions      = document.Project.Solution.Workspace.Services.GetRequiredService <ILegacyGlobalOptionsWorkspaceService>();
            var displayAllOverride = globalOptions.InlineHintsOptionsDisplayAllOverride;

            var enabledForTypes = options.EnabledForTypes;

            if (!enabledForTypes && !displayAllOverride)
            {
                return(ImmutableArray <InlineHint> .Empty);
            }

            var forImplicitVariableTypes  = enabledForTypes && options.ForImplicitVariableTypes;
            var forLambdaParameterTypes   = enabledForTypes && options.ForLambdaParameterTypes;
            var forImplicitObjectCreation = enabledForTypes && options.ForImplicitObjectCreation;

            if (!forImplicitVariableTypes && !forLambdaParameterTypes && !forImplicitObjectCreation && !displayAllOverride)
            {
                return(ImmutableArray <InlineHint> .Empty);
            }

            var anonymousTypeService = document.GetRequiredLanguageService <IStructuralTypeDisplayService>();
            var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            using var _1 = ArrayBuilder <InlineHint> .GetInstance(out var result);

            foreach (var node in root.DescendantNodes(n => n.Span.IntersectsWith(textSpan)))
            {
                var hintOpt = TryGetTypeHint(
                    semanticModel, node,
                    displayAllOverride,
                    forImplicitVariableTypes,
                    forLambdaParameterTypes,
                    forImplicitObjectCreation,
                    cancellationToken);
                if (hintOpt == null)
                {
                    continue;
                }

                var(type, span, textChange, prefix, suffix) = hintOpt.Value;

                using var _2 = ArrayBuilder <SymbolDisplayPart> .GetInstance(out var finalParts);

                finalParts.AddRange(prefix);

                var parts = type.ToDisplayParts(s_minimalTypeStyle);
                AddParts(anonymousTypeService, finalParts, parts, semanticModel, span.Start);

                // If we have nothing to show, then don't bother adding this hint.
                if (finalParts.All(p => string.IsNullOrWhiteSpace(p.ToString())))
                {
                    continue;
                }

                finalParts.AddRange(suffix);
                var taggedText = finalParts.ToTaggedText();

                result.Add(new InlineHint(
                               span, taggedText, textChange,
                               InlineHintHelpers.GetDescriptionFunction(span.Start, type.GetSymbolKey(cancellationToken: cancellationToken), displayOptions)));
            }

            return(result.ToImmutable());
        }
        public async Task <ImmutableArray <InlineHint> > GetInlineHintsAsync(
            Document document, TextSpan textSpan, CancellationToken cancellationToken)
        {
            var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);

            var displayAllOverride = options.GetOption(InlineHintsOptions.DisplayAllOverride);
            var enabledForTypes    = options.GetOption(InlineHintsOptions.EnabledForTypes);

            if (!enabledForTypes && !displayAllOverride)
            {
                return(ImmutableArray <InlineHint> .Empty);
            }

            var forImplicitVariableTypes = enabledForTypes && options.GetOption(InlineHintsOptions.ForImplicitVariableTypes);
            var forLambdaParameterTypes  = enabledForTypes && options.GetOption(InlineHintsOptions.ForLambdaParameterTypes);

            if (!forImplicitVariableTypes && !forLambdaParameterTypes && !displayAllOverride)
            {
                return(ImmutableArray <InlineHint> .Empty);
            }

            var anonymousTypeService = document.GetRequiredLanguageService <IAnonymousTypeDisplayService>();
            var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            using var _1 = ArrayBuilder <InlineHint> .GetInstance(out var result);

            foreach (var node in root.DescendantNodes(n => n.Span.IntersectsWith(textSpan)))
            {
                var hintOpt = TryGetTypeHint(
                    semanticModel, node,
                    displayAllOverride,
                    forImplicitVariableTypes,
                    forLambdaParameterTypes,
                    cancellationToken);
                if (hintOpt == null)
                {
                    continue;
                }

                var(type, span) = hintOpt.Value;

                using var _2 = ArrayBuilder <SymbolDisplayPart> .GetInstance(out var finalParts);

                var parts = type.ToDisplayParts(s_minimalTypeStyle);

                AddParts(anonymousTypeService, finalParts, parts, semanticModel, span.Start);

                // If we have nothing to show, then don't bother adding this hint.
                if (finalParts.Sum(p => p.ToString().Length) == 0)
                {
                    continue;
                }

                if (span.Length == 0)
                {
                    // if this is a hint that is placed in-situ (i.e. it's not overwriting text like 'var'), then place
                    // a space after it to make things feel less cramped.
                    finalParts.Add(new SymbolDisplayPart(SymbolDisplayPartKind.Space, null, " "));
                }

                result.Add(new InlineHint(
                               span, finalParts.ToTaggedText(),
                               InlineHintHelpers.GetDescriptionFunction(span.Start, type.GetSymbolKey())));
            }

            return(result.ToImmutable());
        }