示例#1
0
        private static async Task <Document> UseBitShiftOperatorAsync(
            Document document,
            EnumDeclarationSyntax enumDeclaration,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            EnumDeclarationSyntax newEnumDeclaration = enumDeclaration.ReplaceNodes(
                GetExpressionsToRewrite(),
                (expression, _) =>
            {
                Optional <object> constantValue = semanticModel.GetConstantValue(expression, cancellationToken);

                var power = (int)Math.Log(Convert.ToDouble(constantValue.Value), 2);

                BinaryExpressionSyntax leftShift = LeftShiftExpression(NumericLiteralExpression(1), NumericLiteralExpression(power));

                return(leftShift.WithTriviaFrom(expression));
            });

            return(await document.ReplaceNodeAsync(enumDeclaration, newEnumDeclaration, cancellationToken).ConfigureAwait(false));

            IEnumerable <ExpressionSyntax> GetExpressionsToRewrite()
            {
                foreach (EnumMemberDeclarationSyntax member in enumDeclaration.Members)
                {
                    ExpressionSyntax expression = member.EqualsValue?.Value.WalkDownParentheses();

                    if (expression != null &&
                        semanticModel.GetDeclaredSymbol(member, cancellationToken) is IFieldSymbol fieldSymbol &&
                        fieldSymbol.HasConstantValue)
                    {
                        EnumFieldSymbolInfo fieldInfo = EnumFieldSymbolInfo.Create(fieldSymbol);

                        if (fieldInfo.Value > 1 &&
                            !fieldInfo.HasCompositeValue())
                        {
                            yield return(expression);
                        }
                    }
                }
            }
        }
示例#2
0
        private static Task <Document> RefactorAsync(
            Document document,
            EnumDeclarationSyntax enumDeclaration,
            INamedTypeSymbol enumSymbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            ulong value = 0;

            SpecialType numericType = enumSymbol.EnumUnderlyingType.SpecialType;

            IEnumerable <EnumMemberDeclarationSyntax> newMembers = (enumSymbol.HasAttribute(MetadataNames.System_FlagsAttribute))
                ? enumDeclaration.Members.Select(f => CreateNewFlagsMember(f))
                : enumDeclaration.Members.Select(f => CreateNewMember(f));

            EnumDeclarationSyntax newEnumDeclaration = enumDeclaration.ReplaceNodes(
                enumDeclaration.Members,
                (f, _) =>
            {
                return((enumSymbol.HasAttribute(MetadataNames.System_FlagsAttribute))
                        ? CreateNewFlagsMember(f)
                        : CreateNewMember(f));
            });

            return(document.ReplaceNodeAsync(enumDeclaration, newEnumDeclaration, cancellationToken));

            EnumMemberDeclarationSyntax CreateNewFlagsMember(EnumMemberDeclarationSyntax enumMember)
            {
                if (!ConvertHelpers.CanConvertFromUInt64(value, numericType))
                {
                    return(enumMember);
                }

                IFieldSymbol fieldSymbol = semanticModel.GetDeclaredSymbol(enumMember, cancellationToken);

                if (fieldSymbol.HasConstantValue &&
                    FlagsUtility <ulong> .Instance.IsComposite(SymbolUtility.GetEnumValueAsUInt64(fieldSymbol.ConstantValue, enumSymbol)))
                {
                    return(enumMember);
                }

                EnumMemberDeclarationSyntax newEnumMember = CreateNewEnumMember(enumMember, value, numericType);

                value = (value == 0) ? 1 : value * 2;

                return(newEnumMember);
            }

            EnumMemberDeclarationSyntax CreateNewMember(EnumMemberDeclarationSyntax enumMember)
            {
                if (!ConvertHelpers.CanConvertFromUInt64(value, numericType))
                {
                    return(enumMember);
                }

                EnumMemberDeclarationSyntax newEnumMember = CreateNewEnumMember(enumMember, value, numericType);

                value++;

                return(newEnumMember);
            }
        }