protected override SyntaxNode CreateExplicitlyCastedLiteralValue(
            INamedTypeSymbol enumType,
            SpecialType underlyingSpecialType,
            object constantValue)
        {
            var expression = ExpressionGenerator.GenerateNonEnumValueExpression(
                enumType.EnumUnderlyingType, constantValue, canUseFieldReference: true);

            var constantValueULong = EnumUtilities.ConvertEnumUnderlyingTypeToUInt64(constantValue, underlyingSpecialType);

            if (constantValueULong == 0)
            {
                // 0 is always convertible to an enum type without needing a cast.
                return(expression);
            }

            return(CSharpSyntaxGenerator.Instance.CastExpression(enumType, expression));
        }
Beispiel #2
0
        private static ExpressionSyntax CreateEnumMemberValue(EnumDeclarationSyntax destinationOpt, IFieldSymbol enumMember)
        {
            if (!enumMember.HasConstantValue)
            {
                return(null);
            }

            if (enumMember.ConstantValue is not byte and
                not sbyte and
                not ushort and
                not short and
                not int and
                not uint and
                not long and
                not ulong)
            {
                return(null);
            }

            var value = IntegerUtilities.ToInt64(enumMember.ConstantValue);

            if (destinationOpt != null)
            {
                if (destinationOpt.Members.Count == 0)
                {
                    if (value == 0)
                    {
                        return(null);
                    }
                }
                else
                {
                    // Don't generate an initializer if no other members have them, and our value
                    // would be correctly inferred from our position.
                    if (destinationOpt.Members.Count == value &&
                        destinationOpt.Members.All(m => m.EqualsValue == null))
                    {
                        return(null);
                    }

                    // Existing members, try to stay consistent with their style.
                    var lastMember = destinationOpt.Members.LastOrDefault(m => m.EqualsValue != null);
                    if (lastMember != null)
                    {
                        var lastExpression = lastMember.EqualsValue.Value;
                        if (lastExpression.Kind() == SyntaxKind.LeftShiftExpression &&
                            IntegerUtilities.HasOneBitSet(value))
                        {
                            var binaryExpression = (BinaryExpressionSyntax)lastExpression;
                            if (binaryExpression.Left.Kind() == SyntaxKind.NumericLiteralExpression)
                            {
                                var numericLiteral = (LiteralExpressionSyntax)binaryExpression.Left;
                                if (numericLiteral.Token.ValueText == "1")
                                {
                                    // The user is left shifting ones, stick with that pattern
                                    var shiftValue = IntegerUtilities.LogBase2(value);

                                    // Re-use the numericLiteral text so type suffixes match too
                                    return(SyntaxFactory.BinaryExpression(
                                               SyntaxKind.LeftShiftExpression,
                                               SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(numericLiteral.Token.Text, 1)),
                                               SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(shiftValue.ToString(), shiftValue))));
                                }
                            }
                        }
                        else if (lastExpression.IsKind(SyntaxKind.NumericLiteralExpression, out LiteralExpressionSyntax numericLiteral))
                        {
                            var numericToken = numericLiteral.Token;
                            var numericText  = numericToken.ToString();

                            if (numericText.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
                            {
                                // Hex
                                return(SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression,
                                                                       SyntaxFactory.Literal(numericText.Substring(0, 2) + value.ToString("X"), value)));
                            }
                            else if (numericText.StartsWith("0b", StringComparison.OrdinalIgnoreCase))
                            {
                                return(SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression,
                                                                       SyntaxFactory.Literal(numericText.Substring(0, 2) + Convert.ToString(value, 2), value)));
                            }
                        }
                    }
                }
            }

            var namedType      = enumMember.Type as INamedTypeSymbol;
            var underlyingType = namedType?.EnumUnderlyingType;

            return(ExpressionGenerator.GenerateNonEnumValueExpression(
                       underlyingType,
                       enumMember.ConstantValue,
                       canUseFieldReference: true));
        }
Beispiel #3
0
 public override SyntaxNode CreateConstantExpression(object value)
 {
     return(ExpressionGenerator.GenerateNonEnumValueExpression(null, value, canUseFieldReference: true));
 }
Beispiel #4
0
        private static ExpressionSyntax CreateEnumMemberValue(EnumDeclarationSyntax destinationOpt, IFieldSymbol enumMember)
        {
            var valueOpt = enumMember.ConstantValue is IConvertible
                ? (long?)IntegerUtilities.ToInt64(enumMember.ConstantValue)
                : null;

            if (valueOpt == null)
            {
                return(null);
            }

            var value = valueOpt.Value;

            if (destinationOpt != null)
            {
                if (destinationOpt.Members.Count == 0)
                {
                    if (value == 0)
                    {
                        return(null);
                    }
                }
                else
                {
                    // Don't generate an initializer if no other members have them, and our value
                    // would be correctly inferred from our position.
                    if (destinationOpt.Members.Count == value &&
                        destinationOpt.Members.All(m => m.EqualsValue == null))
                    {
                        return(null);
                    }

                    // Existing members, try to stay consistent with their style.
                    var lastMember = destinationOpt.Members.LastOrDefault(m => m.EqualsValue != null);
                    if (lastMember != null)
                    {
                        var lastExpression = lastMember.EqualsValue.Value;
                        if (lastExpression.CSharpKind() == SyntaxKind.LeftShiftExpression &&
                            IntegerUtilities.HasOneBitSet(value))
                        {
                            var binaryExpression = (BinaryExpressionSyntax)lastExpression;
                            if (binaryExpression.Left.CSharpKind() == SyntaxKind.NumericLiteralExpression)
                            {
                                var numericLiteral = (LiteralExpressionSyntax)binaryExpression.Left;
                                if (numericLiteral.Token.ValueText == "1")
                                {
                                    // The user is left shifting ones, stick with that pattern
                                    var shiftValue = IntegerUtilities.LogBase2(value);
                                    return(SyntaxFactory.BinaryExpression(
                                               SyntaxKind.LeftShiftExpression,
                                               SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal("1", 1)),
                                               SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(shiftValue.ToString(), shiftValue))));
                                }
                            }
                        }
                        else if (lastExpression.CSharpKind() == SyntaxKind.NumericLiteralExpression)
                        {
                            var numericLiteral = (LiteralExpressionSyntax)lastExpression;
                            var numericToken   = numericLiteral.Token;
                            var numericText    = numericToken.ToString();

                            if (numericText.StartsWith("0x") || numericText.StartsWith("0X"))
                            {
                                // Hex
                                return(SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression,
                                                                       SyntaxFactory.Literal(numericText.Substring(0, 2) + value.ToString("X"), value)));
                            }
                        }
                    }
                }
            }

            var namedType      = enumMember.Type as INamedTypeSymbol;
            var underlyingType = namedType != null ? namedType.EnumUnderlyingType : null;

            return(ExpressionGenerator.GenerateNonEnumValueExpression(
                       underlyingType,
                       enumMember.ConstantValue,
                       canUseFieldReference: true));
        }