File: ExtractMethod\MethodExtractor.VariableInfo.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.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Roslyn.Utilities;
 
namespace Microsoft.CodeAnalysis.ExtractMethod;
 
internal abstract partial class AbstractExtractMethodService<
    TStatementSyntax,
    TExecutableStatementSyntax,
    TExpressionSyntax>
{
    internal abstract partial class MethodExtractor
    {
        protected sealed class VariableInfo(
            VariableSymbol variableSymbol,
            VariableStyle variableStyle,
            bool useAsReturnValue) : IComparable<VariableInfo>
        {
            private readonly VariableSymbol _variableSymbol = variableSymbol;
            private readonly VariableStyle _variableStyle = variableStyle;
            private readonly bool _useAsReturnValue = useAsReturnValue;
 
            public bool UseAsReturnValue
            {
                get
                {
                    Contract.ThrowIfFalse(!_useAsReturnValue || _variableStyle.ReturnStyle.ReturnBehavior != ReturnBehavior.None);
                    return _useAsReturnValue;
                }
            }
 
            public bool CanBeUsedAsReturnValue
            {
                get
                {
                    return _variableStyle.ReturnStyle.ReturnBehavior != ReturnBehavior.None;
                }
            }
 
            public bool UseAsParameter
            {
                get
                {
                    return (!_useAsReturnValue && _variableStyle.ParameterStyle.ParameterBehavior != ParameterBehavior.None) ||
                           (_useAsReturnValue && _variableStyle.ReturnStyle.ParameterBehavior != ParameterBehavior.None);
                }
            }
 
            public ParameterBehavior ParameterModifier
            {
                get
                {
                    return _useAsReturnValue ? _variableStyle.ReturnStyle.ParameterBehavior : _variableStyle.ParameterStyle.ParameterBehavior;
                }
            }
 
            public DeclarationBehavior GetDeclarationBehavior()
                => _useAsReturnValue
                    ? _variableStyle.ReturnStyle.DeclarationBehavior
                    : _variableStyle.ParameterStyle.DeclarationBehavior;
 
            public ReturnBehavior ReturnBehavior
            {
                get
                {
                    if (_useAsReturnValue)
                    {
                        return _variableStyle.ReturnStyle.ReturnBehavior;
                    }
 
                    return ReturnBehavior.None;
                }
            }
 
            public static VariableInfo CreateReturnValue(VariableInfo variable)
            {
                Contract.ThrowIfNull(variable);
                Contract.ThrowIfFalse(variable.CanBeUsedAsReturnValue);
                Contract.ThrowIfFalse(variable.ParameterModifier is ParameterBehavior.Out or ParameterBehavior.Ref);
 
                return new VariableInfo(variable._variableSymbol, variable._variableStyle, useAsReturnValue: true);
            }
 
            public void AddIdentifierTokenAnnotationPair(
                MultiDictionary<SyntaxToken, SyntaxAnnotation> annotations, CancellationToken cancellationToken)
            {
                _variableSymbol.AddIdentifierTokenAnnotationPair(annotations, cancellationToken);
            }
 
            public string Name => _variableSymbol.Name;
 
            /// <summary>
            /// Returns true, if the variable could be either passed as a parameter
            /// to the new local function or the local function can capture the variable.
            /// </summary>
            public bool CanBeCapturedByLocalFunction
                => _variableSymbol.CanBeCapturedByLocalFunction;
 
            public bool OriginalTypeHadAnonymousTypeOrDelegate => _variableSymbol.SymbolType.ContainsAnonymousType();
 
            public ITypeSymbol SymbolType => _variableSymbol.SymbolType;
 
            public SyntaxToken GetIdentifierTokenAtDeclaration(SemanticDocument document)
                => document.GetTokenWithAnnotation(_variableSymbol.IdentifierTokenAnnotation);
 
            public SyntaxToken GetIdentifierTokenAtDeclaration(SyntaxNode node)
                => node.GetAnnotatedTokens(_variableSymbol.IdentifierTokenAnnotation).SingleOrDefault();
 
            public SyntaxToken GetOriginalIdentifierToken(CancellationToken cancellationToken) => _variableSymbol.GetOriginalIdentifierToken(cancellationToken);
 
            public int CompareTo(VariableInfo other)
                => this._variableSymbol.CompareTo(other._variableSymbol);
        }
    }
}