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