public static void AnalyzeNamedType(SymbolAnalysisContext context, INamedTypeSymbol flagsAttribute) { var enumSymbol = (INamedTypeSymbol)context.Symbol; if (enumSymbol.IsEnum() && enumSymbol.HasAttribute(flagsAttribute)) { var infos = default(ImmutableArray <EnumFieldInfo>); foreach (ISymbol member in enumSymbol.GetMembers()) { if (member.IsField()) { var fieldSymbol = (IFieldSymbol)member; if (!fieldSymbol.HasConstantValue) { break; } var info = new EnumFieldInfo(fieldSymbol); if (info.IsComposite()) { var declaration = (EnumMemberDeclarationSyntax)info.Symbol.GetSyntax(context.CancellationToken); ExpressionSyntax valueExpression = declaration.EqualsValue?.Value; if (valueExpression != null && (valueExpression.IsKind(SyntaxKind.NumericLiteralExpression) || valueExpression .DescendantNodes() .Any(f => f.IsKind(SyntaxKind.NumericLiteralExpression)))) { if (infos.IsDefault) { infos = EnumFieldInfo.CreateRange(enumSymbol); if (infos.IsDefault) { break; } } List <EnumFieldInfo> values = info.Decompose(infos); if (values?.Count > 1) { context.ReportDiagnostic( DiagnosticDescriptors.DeclareEnumValueAsCombinationOfNames, valueExpression); } } } } } } }
public static async Task <Document> RefactorAsync( Document document, EnumMemberDeclarationSyntax enumMemberDeclaration, CancellationToken cancellationToken) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); IFieldSymbol enumMemberSymbol = semanticModel.GetDeclaredSymbol(enumMemberDeclaration, cancellationToken); ImmutableArray <EnumFieldInfo> infos = EnumFieldInfo.CreateRange(enumMemberSymbol.ContainingType); ExpressionSyntax value = enumMemberDeclaration.EqualsValue?.Value; var info = new EnumFieldInfo(enumMemberSymbol); List <EnumFieldInfo> values = info.Decompose(infos); values.Sort((f, g) => { if (f.IsComposite()) { if (g.IsComposite()) { return(((IComparable)f.Value).CompareTo((IComparable)g.Value)); } else { return(-1); } } else if (g.IsComposite()) { return(1); } return(((IComparable)f.Value).CompareTo((IComparable)g.Value)); }); BinaryExpressionSyntax newValue = BitwiseOrExpression(values[0].ToIdentifierName(), values[1].ToIdentifierName()); for (int i = 2; i < values.Count; i++) { newValue = BitwiseOrExpression(newValue, values[i].ToIdentifierName()); } newValue = newValue.WithFormatterAnnotation(); return(await document.ReplaceNodeAsync(value, newValue, cancellationToken).ConfigureAwait(false)); }