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)); }
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)); }