File: ExtractMethod\MethodExtractor.AnalyzerResult.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;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.PooledObjects;
 
namespace Microsoft.CodeAnalysis.ExtractMethod;
 
internal abstract partial class AbstractExtractMethodService<
    TStatementSyntax,
    TExecutableStatementSyntax,
    TExpressionSyntax>
{
    internal abstract partial class MethodExtractor
    {
        protected sealed class AnalyzerResult(
            ImmutableArray<ITypeParameterSymbol> typeParametersInDeclaration,
            ImmutableArray<ITypeParameterSymbol> typeParametersInConstraintList,
            ImmutableArray<VariableInfo> variables,
            ITypeSymbol returnType,
            bool returnsByRef,
            bool instanceMemberIsUsed,
            bool shouldBeReadOnly,
            ExtractMethodFlowControlInformation flowControlInformation,
            OperationStatus status)
        {
            public ImmutableArray<ITypeParameterSymbol> MethodTypeParametersInDeclaration { get; } = typeParametersInDeclaration;
            public ImmutableArray<ITypeParameterSymbol> MethodTypeParametersInConstraintList { get; } = typeParametersInConstraintList;
            public ImmutableArray<VariableInfo> VariablesToUseAsReturnValue { get; } = variables.WhereAsArray(v => v.UseAsReturnValue);
 
            /// <summary>
            /// used to determine whether static can be used
            /// </summary>
            public bool UseInstanceMember { get; } = instanceMemberIsUsed;
 
            /// <summary>
            /// Indicates whether the extracted method should have a 'readonly' modifier.
            /// </summary>
            public bool ShouldBeReadOnly { get; } = shouldBeReadOnly;
 
            /// <summary>
            /// Information about the flow control constructs found in the selection.  For for many purposes, including
            /// determining whether a final "return" statement needs to be inserted.
            /// </summary>
            public ExtractMethodFlowControlInformation FlowControlInformation { get; } = flowControlInformation;
 
            /// <summary>
            /// Initial computed return type for the extract method.  This does not include any wrapping in a type like
            /// <see cref="Task{TResult}"/> for async methods.
            /// </summary>
            public ITypeSymbol CoreReturnType { get; } = returnType;
            public bool ReturnsByRef { get; } = returnsByRef;
 
            /// <summary>
            /// analyzer result operation status
            /// </summary>
            public OperationStatus Status { get; } = status;
 
            public ImmutableArray<VariableInfo> Variables { get; } = variables;
 
            public ImmutableArray<VariableInfo> GetVariablesToSplitOrMoveIntoMethodDefinition()
            {
                return Variables.WhereAsArray(
                    v => v.GetDeclarationBehavior() is DeclarationBehavior.SplitIn or DeclarationBehavior.MoveIn);
            }
 
            public IEnumerable<VariableInfo> MethodParameters
                => Variables.Where(v => v.UseAsParameter);
 
            public IEnumerable<VariableInfo> GetVariablesToMoveIntoMethodDefinition()
                => Variables.Where(v => v.GetDeclarationBehavior() == DeclarationBehavior.MoveIn);
 
            public IEnumerable<VariableInfo> GetVariablesToMoveOutToCallSiteOrDelete()
                => Variables.Where(v => v.GetDeclarationBehavior() is DeclarationBehavior.MoveOut);
 
            public IEnumerable<VariableInfo> GetVariablesToSplitOrMoveOutToCallSite()
                => Variables.Where(v => v.GetDeclarationBehavior() is DeclarationBehavior.SplitOut or DeclarationBehavior.MoveOut);
 
            public VariableInfo GetOutermostVariableToMoveIntoMethodDefinition()
            {
                using var _ = ArrayBuilder<VariableInfo>.GetInstance(out var variables);
                variables.AddRange(this.GetVariablesToMoveIntoMethodDefinition());
                if (variables.Count <= 0)
                    return null;
 
                return variables.Min();
            }
        }
    }
}