private static void AnalyzeCodeRefactoringProvider(SymbolAnalysisContext context, INamedTypeSymbol symbol) { AttributeData attribute = symbol.GetAttribute(RoslynMetadataNames.Microsoft_CodeAnalysis_CodeRefactorings_ExportCodeRefactoringProviderAttribute); if (attribute == null) { return; } if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UnknownLanguageName)) { AnalyzeLanguageName(context, attribute); } if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.SpecifyExportCodeRefactoringProviderAttributeName) && !ContainsNamedArgument(attribute, "Name")) { ReportDiagnostic(context, attribute, DiagnosticDescriptors.SpecifyExportCodeRefactoringProviderAttributeName); } }
private static void AnalyzeDiagnosticAnalyzer(SymbolAnalysisContext context, INamedTypeSymbol symbol) { AttributeData attribute = symbol.GetAttribute(RoslynMetadataNames.Microsoft_CodeAnalysis_Diagnostics_DiagnosticAnalyzerAttribute); if (attribute == null) { return; } if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UnknownLanguageName)) { AnalyzeLanguageName(context, attribute); } }
private static void AnalyzeFieldSymbol(SymbolAnalysisContext context) { var fieldSymbol = (IFieldSymbol)context.Symbol; if (!fieldSymbol.IsConst && !fieldSymbol.IsImplicitlyDeclared && fieldSymbol.DeclaredAccessibility == Accessibility.Private && !string.IsNullOrEmpty(fieldSymbol.Name) && !IsValidIdentifier(fieldSymbol.Name)) { if (!fieldSymbol.IsStatic || !fieldSymbol.IsReadOnly || context.IsAnalyzerSuppressed(AnalyzerOptions.DoNotRenamePrivateStaticReadOnlyFieldToCamelCaseWithUnderscore)) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.RenamePrivateFieldToCamelCaseWithUnderscore, fieldSymbol.Locations[0]); } } }
private static void AnalyzeNamedType(SymbolAnalysisContext context) { var typeSymbol = (INamedTypeSymbol)context.Symbol; if (typeSymbol.IsImplicitlyDeclared) { return; } if (typeSymbol.TypeKind != TypeKind.Enum) { return; } bool hasFlagsAttribute = typeSymbol.HasAttribute(MetadataNames.System_FlagsAttribute); ImmutableArray <ISymbol> members = default; if (hasFlagsAttribute && !context.IsAnalyzerSuppressed(DiagnosticDescriptors.DeclareEnumMemberWithZeroValue)) { members = typeSymbol.GetMembers(); if (!ContainsFieldWithZeroValue(members)) { var enumDeclaration = (EnumDeclarationSyntax)typeSymbol.GetSyntax(context.CancellationToken); DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.DeclareEnumMemberWithZeroValue, enumDeclaration.Identifier); } } EnumSymbolInfo enumInfo = default; if (hasFlagsAttribute && !context.IsAnalyzerSuppressed(DiagnosticDescriptors.CompositeEnumValueContainsUndefinedFlag)) { enumInfo = EnumSymbolInfo.Create(typeSymbol); foreach (EnumFieldSymbolInfo field in enumInfo.Fields) { if (field.HasValue && ConvertHelpers.CanConvertFromUInt64(field.Value, typeSymbol.EnumUnderlyingType.SpecialType) && !IsMaxValue(field.Value, typeSymbol.EnumUnderlyingType.SpecialType) && field.HasCompositeValue()) { foreach (ulong value in (field.DecomposeValue())) { if (!enumInfo.Contains(value)) { ReportUndefinedFlag(context, field.Symbol, value.ToString()); } } } } } if (hasFlagsAttribute && !context.IsAnalyzerSuppressed(DiagnosticDescriptors.DeclareEnumValueAsCombinationOfNames)) { if (members.IsDefault) { members = typeSymbol.GetMembers(); } foreach (ISymbol member in members) { if (!(member is IFieldSymbol fieldSymbol)) { continue; } if (!fieldSymbol.HasConstantValue) { break; } EnumFieldSymbolInfo fieldInfo = EnumFieldSymbolInfo.Create(fieldSymbol); if (!fieldInfo.HasCompositeValue()) { continue; } var declaration = (EnumMemberDeclarationSyntax)fieldInfo.Symbol.GetSyntax(context.CancellationToken); ExpressionSyntax expression = declaration.EqualsValue?.Value.WalkDownParentheses(); if (expression != null && (expression.IsKind(SyntaxKind.NumericLiteralExpression) || expression .DescendantNodes() .Any(f => f.IsKind(SyntaxKind.NumericLiteralExpression)))) { if (enumInfo.IsDefault) { enumInfo = EnumSymbolInfo.Create(typeSymbol); if (enumInfo.Fields.Any(f => !f.HasValue)) { break; } } List <EnumFieldSymbolInfo> values = enumInfo.Decompose(fieldInfo); if (values?.Count > 1) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.DeclareEnumValueAsCombinationOfNames, expression); } } } } if (hasFlagsAttribute && !context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseBitShiftOperator)) { if (members.IsDefault) { members = typeSymbol.GetMembers(); } foreach (ISymbol member in members) { if (!(member is IFieldSymbol fieldSymbol)) { continue; } if (!fieldSymbol.HasConstantValue) { continue; } EnumFieldSymbolInfo fieldInfo = EnumFieldSymbolInfo.Create(fieldSymbol); if (fieldInfo.Value <= 1) { continue; } if (fieldInfo.HasCompositeValue()) { continue; } var declaration = (EnumMemberDeclarationSyntax)fieldInfo.Symbol.GetSyntax(context.CancellationToken); ExpressionSyntax expression = declaration.EqualsValue?.Value.WalkDownParentheses(); if (expression.IsKind(SyntaxKind.NumericLiteralExpression)) { var enumDeclaration = (EnumDeclarationSyntax)typeSymbol.GetSyntax(context.CancellationToken); DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UseBitShiftOperator, enumDeclaration.Identifier); break; } } } if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.DuplicateEnumValue)) { if (enumInfo.IsDefault) { enumInfo = EnumSymbolInfo.Create(typeSymbol); } ImmutableArray <EnumFieldSymbolInfo> fields = enumInfo.Fields; if (fields.Length > 1) { EnumFieldSymbolInfo symbolInfo1 = fields[0]; EnumFieldSymbolInfo symbolInfo2 = default; for (int i = 1; i < fields.Length; i++, symbolInfo1 = symbolInfo2) { symbolInfo2 = fields[i]; if (!symbolInfo1.HasValue || !symbolInfo2.HasValue || symbolInfo1.Value != symbolInfo2.Value) { continue; } var enumMember1 = (EnumMemberDeclarationSyntax)symbolInfo1.Symbol.GetSyntax(context.CancellationToken); if (enumMember1 == null) { continue; } var enumMember2 = (EnumMemberDeclarationSyntax)symbolInfo2.Symbol.GetSyntax(context.CancellationToken); if (enumMember2 == null) { continue; } ExpressionSyntax value1 = enumMember1.EqualsValue?.Value?.WalkDownParentheses(); ExpressionSyntax value2 = enumMember2.EqualsValue?.Value?.WalkDownParentheses(); if (value1 == null) { if (value2 != null) { ReportDuplicateValue(context, enumMember1, value2); } } else if (value2 == null) { ReportDuplicateValue(context, enumMember2, value1); } else { SyntaxKind kind1 = value1.Kind(); SyntaxKind kind2 = value2.Kind(); if (kind1 == SyntaxKind.NumericLiteralExpression) { if (kind2 == SyntaxKind.NumericLiteralExpression) { var enumDeclaration = (EnumDeclarationSyntax)enumMember1.Parent; SeparatedSyntaxList <EnumMemberDeclarationSyntax> enumMembers = enumDeclaration.Members; if (enumMembers.IndexOf(enumMember1) < enumMembers.IndexOf(enumMember2)) { ReportDuplicateValue(context, value2); } else { ReportDuplicateValue(context, value1); } } else if (!string.Equals((value2 as IdentifierNameSyntax)?.Identifier.ValueText, enumMember1.Identifier.ValueText, StringComparison.Ordinal)) { ReportDuplicateValue(context, value1); } } else if (kind2 == SyntaxKind.NumericLiteralExpression && !string.Equals((value1 as IdentifierNameSyntax)?.Identifier.ValueText, enumMember2.Identifier.ValueText, StringComparison.Ordinal)) { ReportDuplicateValue(context, value2); } } } } } }