File: IntroduceVariable\AbstractIntroduceVariableService.AbstractIntroduceVariableCodeAction.cs
Web Access
Project: src\src\Features\Core\Portable\Microsoft.CodeAnalysis.Features.csproj (Microsoft.CodeAnalysis.Features)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeCleanup;
using Microsoft.CodeAnalysis.LanguageService;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Simplification;
 
namespace Microsoft.CodeAnalysis.IntroduceVariable;
 
internal abstract partial class AbstractIntroduceVariableService<TService, TExpressionSyntax, TTypeSyntax, TTypeDeclarationSyntax, TQueryExpressionSyntax, TNameSyntax>
{
    private abstract class AbstractIntroduceVariableCodeAction : CodeAction
    {
        private readonly bool _allOccurrences;
        private readonly bool _isConstant;
        private readonly bool _isLocal;
        private readonly bool _isQueryLocal;
        private readonly TExpressionSyntax _expression;
        private readonly SemanticDocument _semanticDocument;
        private readonly TService _service;
 
        public readonly CodeCleanupOptions Options;
 
        internal AbstractIntroduceVariableCodeAction(
            TService service,
            SemanticDocument document,
            CodeCleanupOptions options,
            TExpressionSyntax expression,
            bool allOccurrences,
            bool isConstant,
            bool isLocal,
            bool isQueryLocal)
        {
            _service = service;
            _semanticDocument = document;
            Options = options;
            _expression = expression;
            _allOccurrences = allOccurrences;
            _isConstant = isConstant;
            _isLocal = isLocal;
            _isQueryLocal = isQueryLocal;
            Title = CreateDisplayText(expression);
        }
 
        public override string Title { get; }
 
        protected override async Task<Document> GetChangedDocumentAsync(CancellationToken cancellationToken)
        {
            var changedDocument = await GetChangedDocumentCoreAsync(cancellationToken).ConfigureAwait(false);
            var simplifierOptions = await changedDocument.GetSimplifierOptionsAsync(cancellationToken).ConfigureAwait(false);
            return await Simplifier.ReduceAsync(changedDocument, simplifierOptions, cancellationToken).ConfigureAwait(false);
        }
 
        private async Task<Document> GetChangedDocumentCoreAsync(CancellationToken cancellationToken)
        {
            if (_isQueryLocal)
            {
                return await _service.IntroduceQueryLocalAsync(_semanticDocument, _expression, _allOccurrences, cancellationToken).ConfigureAwait(false);
            }
            else if (_isLocal)
            {
                return await _service.IntroduceLocalAsync(_semanticDocument, _expression, _allOccurrences, _isConstant, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                return await _service.IntroduceFieldAsync(_semanticDocument, _expression, _allOccurrences, _isConstant, cancellationToken).ConfigureAwait(false);
            }
        }
 
        private string CreateDisplayText(TExpressionSyntax expression)
        {
            var singleLineExpression = _semanticDocument.Document.GetLanguageService<ISyntaxFactsService>().ConvertToSingleLine(expression);
            var nodeString = singleLineExpression.ToString();
 
            return CreateDisplayText(nodeString);
        }
 
        // Indexed by: allOccurrences, isConstant, isLocal
        private static readonly string[,,] formatStrings = new string[2, 2, 2]
            {
              {
                { FeaturesResources.Introduce_field_for_0, FeaturesResources.Introduce_local_for_0 },
                { FeaturesResources.Introduce_constant_for_0, FeaturesResources.Introduce_local_constant_for_0 }
              },
              {
                { FeaturesResources.Introduce_field_for_all_occurrences_of_0,  FeaturesResources.Introduce_local_for_all_occurrences_of_0 },
                { FeaturesResources.Introduce_constant_for_all_occurrences_of_0, FeaturesResources.Introduce_local_constant_for_all_occurrences_of_0 }
              }
            };
 
        private string CreateDisplayText(string nodeString)
        {
            var formatString = _isQueryLocal
                ? _allOccurrences
                    ? FeaturesResources.Introduce_query_variable_for_all_occurrences_of_0
                    : FeaturesResources.Introduce_query_variable_for_0
                : formatStrings[_allOccurrences ? 1 : 0, _isConstant ? 1 : 0, _isLocal ? 1 : 0];
            return string.Format(formatString, nodeString);
        }
 
        protected ITypeSymbol GetExpressionType(
            CancellationToken cancellationToken)
        {
            var semanticModel = _semanticDocument.SemanticModel;
            var typeInfo = semanticModel.GetTypeInfo(_expression, cancellationToken);
 
            return typeInfo.Type ?? typeInfo.ConvertedType ?? semanticModel.Compilation.GetSpecialType(SpecialType.System_Object);
        }
    }
}