public static async Task ComputeRefactoringAsync(RefactoringContext context, EnumDeclarationSyntax enumDeclaration)
        {
            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

            INamedTypeSymbol enumSymbol = semanticModel.GetDeclaredSymbol(enumDeclaration, context.CancellationToken);

            if (!enumSymbol.IsEnumWithFlags(semanticModel))
            {
                return;
            }

            SeparatedSyntaxList <EnumMemberDeclarationSyntax> members = enumDeclaration.Members;

            if (!members.Any(f => f.EqualsValue == null))
            {
                return;
            }

            SpecialType specialType = enumSymbol.EnumUnderlyingType.SpecialType;

            List <object> values = GetExplicitValues(enumDeclaration, semanticModel, context.CancellationToken);

            Optional <object> optional = FlagsUtility.GetUniquePowerOfTwo(specialType, values);

            if (!optional.HasValue)
            {
                return;
            }

            context.RegisterRefactoring(
                "Generate enum values",
                cancellationToken => RefactorAsync(context.Document, enumDeclaration, enumSymbol, startFromHighestExistingValue: false, cancellationToken: cancellationToken),
                RefactoringIdentifiers.GenerateEnumValues);

            if (!members.Any(f => f.EqualsValue != null))
            {
                return;
            }

            Optional <object> optional2 = FlagsUtility.GetUniquePowerOfTwo(specialType, values, startFromHighestExistingValue: true);

            if (!optional2.HasValue)
            {
                return;
            }

            if (optional.Value.Equals(optional2.Value))
            {
                return;
            }

            context.RegisterRefactoring(
                $"Generate enum values (starting from {optional2.Value})",
                cancellationToken => RefactorAsync(context.Document, enumDeclaration, enumSymbol, startFromHighestExistingValue: true, cancellationToken: cancellationToken),
                RefactoringIdentifiers.GenerateEnumValues);
        }
        private static object GetFlagsValue(EnumMemberDeclarationSyntax enumMember, INamedTypeSymbol enumSymbol, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            var enumDeclaration = (EnumDeclarationSyntax)enumMember.Parent;

            object[]    values      = GetExplicitValues(enumDeclaration, semanticModel, cancellationToken).ToArray();
            SpecialType specialType = enumSymbol.EnumUnderlyingType.SpecialType;

            Optional <object> optional = FlagsUtility.GetUniquePowerOfTwo(
                specialType,
                values,
                startFromHighestExistingValue: false);

            Debug.Assert(optional.HasValue, "");

            if (optional.HasValue)
            {
                object value = optional.Value;

                SeparatedSyntaxList <EnumMemberDeclarationSyntax> members = enumDeclaration.Members;
                int index = members.IndexOf(enumMember);
                int count = members.Take(index).Count(f => HasImplicitValue(f, semanticModel, cancellationToken));

                switch (specialType)
                {
                case SpecialType.System_SByte:
                    return(GetUniquePowerOfTwo((sbyte)value, count, values.Cast <sbyte>().ToArray()));

                case SpecialType.System_Byte:
                    return(GetUniquePowerOfTwo((byte)value, count, values.Cast <byte>().ToArray()));

                case SpecialType.System_Int16:
                    return(GetUniquePowerOfTwo((short)value, count, values.Cast <short>().ToArray()));

                case SpecialType.System_UInt16:
                    return(GetUniquePowerOfTwo((ushort)value, count, values.Cast <ushort>().ToArray()));

                case SpecialType.System_Int32:
                    return(GetUniquePowerOfTwo((int)value, count, values.Cast <int>().ToArray()));

                case SpecialType.System_UInt32:
                    return(GetUniquePowerOfTwo((uint)value, count, values.Cast <uint>().ToArray()));

                case SpecialType.System_Int64:
                    return(GetUniquePowerOfTwo((long)value, count, values.Cast <long>().ToArray()));

                case SpecialType.System_UInt64:
                    return(GetUniquePowerOfTwo((ulong)value, count, values.Cast <ulong>().ToArray()));
                }
            }

            return(null);
        }
Ejemplo n.º 3
0
        private static async Task <Document> RefactorAsync(
            Document document,
            EnumDeclarationSyntax enumDeclaration,
            INamedTypeSymbol enumSymbol,
            bool startFromHighestExistingValue,
            CancellationToken cancellationToken)
        {
            SeparatedSyntaxList <EnumMemberDeclarationSyntax> members = enumDeclaration.Members;

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            SpecialType specialType = enumSymbol.EnumUnderlyingType.SpecialType;

            List <object> values = GetExplicitValues(enumDeclaration, semanticModel, cancellationToken);

            for (int i = 0; i < members.Count; i++)
            {
                if (members[i].EqualsValue == null)
                {
                    Optional <object> optional = FlagsUtility.GetUniquePowerOfTwo(specialType, values, startFromHighestExistingValue);

                    if (optional.HasValue)
                    {
                        values.Add(optional.Value);

                        EqualsValueClauseSyntax equalsValue = EqualsValueClause(CSharpFactory.LiteralExpression(optional.Value));

                        EnumMemberDeclarationSyntax newMember = members[i]
                                                                .WithEqualsValue(equalsValue)
                                                                .WithFormatterAnnotation();

                        members = members.ReplaceAt(i, newMember);
                    }
                    else
                    {
                        break;
                    }
                }
            }

            EnumDeclarationSyntax newNode = enumDeclaration.WithMembers(members);

            return(await document.ReplaceNodeAsync(enumDeclaration, newNode, cancellationToken).ConfigureAwait(false));
        }
        public static async Task ComputeRefactoringAsync(RefactoringContext context, EnumDeclarationSyntax enumDeclaration)
        {
            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

            INamedTypeSymbol enumSymbol = semanticModel.GetDeclaredSymbol(enumDeclaration, context.CancellationToken);

            if (enumSymbol.IsEnumWithFlags())
            {
                List <object> values = GetConstantValues(enumSymbol);

                SpecialType specialType = enumSymbol.EnumUnderlyingType.SpecialType;

                Optional <object> optional = FlagsUtility.GetUniquePowerOfTwo(specialType, values);

                if (optional.HasValue)
                {
                    context.RegisterRefactoring(
                        "Generate enum member",
                        cancellationToken => RefactorAsync(context.Document, enumDeclaration, enumSymbol, optional.Value, cancellationToken),
                        RefactoringIdentifiers.GenerateEnumMember);

                    Optional <object> optional2 = FlagsUtility.GetUniquePowerOfTwo(specialType, values, startFromHighestExistingValue: true);

                    if (optional2.HasValue &&
                        !optional.Value.Equals(optional2.Value))
                    {
                        context.RegisterRefactoring(
                            $"Generate enum member (with value {optional2.Value})",
                            cancellationToken => RefactorAsync(context.Document, enumDeclaration, enumSymbol, optional2.Value, cancellationToken),
                            RefactoringIdentifiers.GenerateEnumMember);
                    }
                }
            }
            else
            {
                context.RegisterRefactoring(
                    "Generate enum member",
                    cancellationToken => RefactorAsync(context.Document, enumDeclaration, enumSymbol, null, cancellationToken),
                    RefactoringIdentifiers.GenerateEnumMember);
            }
        }