private static void AnalyzeSymbol(INamedTypeSymbol namedTypeSymbol, INamedTypeSymbol comparableType, INamedTypeSymbol genericComparableType, Action <Diagnostic> addDiagnostic)
        {
            if (namedTypeSymbol.TypeKind == TypeKind.Interface ||
                namedTypeSymbol.TypeKind == TypeKind.Enum ||
                !namedTypeSymbol.IsExternallyVisible())
            {
                return;
            }

            if (namedTypeSymbol.AllInterfaces.Any(t => t.Equals(comparableType) ||
                                                  (t.ConstructedFrom?.Equals(genericComparableType) ?? false)))
            {
                var    overridesEquals           = namedTypeSymbol.OverridesEquals();
                string comparisonOperatorsString = GetNeededComparisonOperators(namedTypeSymbol);

                if (!overridesEquals && comparisonOperatorsString.Length != 0)
                {
                    addDiagnostic(namedTypeSymbol.CreateDiagnostic(RuleBoth, namedTypeSymbol.Name, comparisonOperatorsString));
                }
                else if (!overridesEquals)
                {
                    addDiagnostic(namedTypeSymbol.CreateDiagnostic(RuleEquals, namedTypeSymbol.Name));
                }
                else if (comparisonOperatorsString.Length != 0)
                {
                    addDiagnostic(namedTypeSymbol.CreateDiagnostic(RuleOperator, namedTypeSymbol.Name, comparisonOperatorsString));
                }
            }
        }
Ejemplo n.º 2
0
        private static void AnalyzeSymbol(INamedTypeSymbol symbol, INamedTypeSymbol flagsAttributeType, Action <Diagnostic> addDiagnostic)
        {
            if (symbol != null &&
                symbol.TypeKind == TypeKind.Enum &&
                symbol.DeclaredAccessibility == Accessibility.Public)
            {
                IList <ulong> memberValues;
                if (EnumHelpers.TryGetEnumMemberValues(symbol, out memberValues))
                {
                    bool hasFlagsAttribute = symbol.GetAttributes().Any(a => a.AttributeClass == flagsAttributeType);
                    if (hasFlagsAttribute)
                    {
                        // Check "CA2217: Do not mark enums with FlagsAttribute"
                        IEnumerable <ulong> missingValues;
                        if (!ShouldBeFlags(memberValues, out missingValues))
                        {
                            Debug.Assert(missingValues != null);

                            string missingValuesString = missingValues.Select(v => v.ToString()).Aggregate((i, j) => i + ", " + j);
                            addDiagnostic(symbol.CreateDiagnostic(Rule2217, symbol.Name, missingValuesString));
                        }
                    }
                    else
                    {
                        // Check "CA1027: Mark enums with FlagsAttribute"
                        // Ignore contiguous value enums to reduce noise.
                        if (!IsContiguous(memberValues) && ShouldBeFlags(memberValues))
                        {
                            addDiagnostic(symbol.CreateDiagnostic(Rule1027, symbol.Name));
                        }
                    }
                }
            }
        }
Ejemplo n.º 3
0
        private static void AnalyzeType(SymbolAnalysisContext context, INamedTypeSymbol dynamicInterfaceCastableImplementationAttribute)
        {
            INamedTypeSymbol targetType = (INamedTypeSymbol)context.Symbol;

            if (targetType.TypeKind != TypeKind.Interface)
            {
                return;
            }

            if (!targetType.HasAttribute(dynamicInterfaceCastableImplementationAttribute))
            {
                return;
            }

            // Default Interface Methods are required to provide an IDynamicInterfaceCastable implementation type.
            // Since Visual Basic does not support DIMs, an implementation type cannot be correctly provided in VB.
            if (context.Compilation.Language == LanguageNames.VisualBasic)
            {
                context.ReportDiagnostic(targetType.CreateDiagnostic(DynamicInterfaceCastableImplementationUnsupported));
                return;
            }

            bool missingMethodImplementations = false;

            foreach (var iface in targetType.AllInterfaces)
            {
                foreach (var member in iface.GetMembers())
                {
                    if (member.IsAbstract &&
                        member.Kind != SymbolKind.NamedType &&
                        context.Compilation.IsSymbolAccessibleWithin(member, targetType) &&
                        targetType.FindImplementationForInterfaceMember(member) is null)
                    {
                        missingMethodImplementations = true;
                        break;
                    }
                }

                // Once we find one missing method implementation, we can stop searching for missing implementations.
                if (missingMethodImplementations)
                {
                    break;
                }
            }

            if (missingMethodImplementations)
            {
                context.ReportDiagnostic(targetType.CreateDiagnostic(InterfaceMembersMissingImplementation, targetType.ToDisplayString()));
            }

            foreach (var member in targetType.GetMembers())
            {
                if (!member.IsImplementationOfAnyExplicitInterfaceMember() && !member.IsStatic)
                {
                    // We don't want to emit diagnostics when the member is an accessor method.
                    if (member is not IMethodSymbol {
                        AssociatedSymbol: IPropertySymbol or IEventSymbol
                    })
            protected override void AnalyzeSymbol(INamedTypeSymbol namedTypeSymbol, Compilation compilation, Action <Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken)
            {
                // If the type is public and implements ISerializable
                if (namedTypeSymbol.DeclaredAccessibility == Accessibility.Public && namedTypeSymbol.AllInterfaces.Contains(this.iserializableTypeSymbol))
                {
                    if (!IsSerializable(namedTypeSymbol))
                    {
                        // CA2237 : Mark serializable types with the SerializableAttribute
                        if (namedTypeSymbol.BaseType.SpecialType == SpecialType.System_Object ||
                            IsSerializable(namedTypeSymbol.BaseType))
                        {
                            addDiagnostic(namedTypeSymbol.CreateDiagnostic(RuleCA2237, namedTypeSymbol.Name));
                        }
                    }
                    else
                    {
                        // Look for a serialization constructor.
                        // A serialization constructor takes two params of type SerializationInfo and StreamingContext.
                        var serializationCtor = namedTypeSymbol.Constructors.Where(c => c.Parameters.Count() == 2 &&
                                                                                   c.Parameters[0].Type == this.serializationInfoTypeSymbol &&
                                                                                   c.Parameters[1].Type == this.streamingContextTypeSymbol).SingleOrDefault();

                        // There is no serialization ctor - issue a diagnostic.
                        if (serializationCtor == null)
                        {
                            addDiagnostic(namedTypeSymbol.CreateDiagnostic(RuleCA2229, string.Format(FxCopRulesResources.SerializableTypeDoesntHaveCtor, namedTypeSymbol.Name)));
                        }
                        else
                        {
                            // Check the accessibility
                            // The serializationctor should be protected if the class is unsealed and private if the class is sealed.
                            if (namedTypeSymbol.IsSealed && serializationCtor.DeclaredAccessibility != Accessibility.Private)
                            {
                                addDiagnostic(serializationCtor.CreateDiagnostic(RuleCA2229, string.Format(FxCopRulesResources.SerializationCtorAccessibilityForSealedType, namedTypeSymbol.Name)));
                            }

                            if (!namedTypeSymbol.IsSealed && serializationCtor.DeclaredAccessibility != Accessibility.Protected)
                            {
                                addDiagnostic(serializationCtor.CreateDiagnostic(RuleCA2229, string.Format(FxCopRulesResources.SerializationCtorAccessibilityForUnSealedType, namedTypeSymbol.Name)));
                            }
                        }
                    }
                }

                // If this is type is marked Serializable check it's fields types' as well
                if (IsSerializable(namedTypeSymbol))
                {
                    var nonSerialableFields = namedTypeSymbol.GetMembers().OfType <IFieldSymbol>().Where(m => !IsSerializable(m.Type));
                    foreach (var field in nonSerialableFields)
                    {
                        addDiagnostic(field.CreateDiagnostic(RuleCA2235, field.Name, namedTypeSymbol.Name, field.Type));
                    }
                }
            }
 protected override void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compilation, Action <Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken)
 {
     if (symbol.GetMembers().Any(member => IsDllImport(member)) && !IsTypeNamedCorrectly(symbol.Name))
     {
         addDiagnostic(symbol.CreateDiagnostic(Rule));
     }
 }
 /// <summary>
 /// Check rule: Remove IDisposable from the list of interfaces implemented by {0} as it is already implemented by base type {1}.
 /// </summary>
 private static void CheckIDisposableReimplementationRule(INamedTypeSymbol type, SymbolAnalysisContext context, bool implementsDisposableInBaseType)
 {
     if (implementsDisposableInBaseType)
     {
         context.ReportDiagnostic(type.CreateDiagnostic(IDisposableReimplementationRule, type.Name, type.BaseType.Name));
     }
 }
Ejemplo n.º 7
0
            public void AnalyzeSymbol(SymbolAnalysisContext symbolContext)
            {
                INamedTypeSymbol namedType = (INamedTypeSymbol)symbolContext.Symbol;

                if (!namedType.AllInterfaces.Contains(_disposableTypeSymbol))
                {
                    IEnumerable <IFieldSymbol> disposableFields = from member in namedType.GetMembers()
                                                                  where member.Kind == SymbolKind.Field && !member.IsStatic
                                                                  let field = member as IFieldSymbol
                                                                              where field.Type != null && field.Type.AllInterfaces.Contains(_disposableTypeSymbol)
                                                                              select field;

                    if (disposableFields.Any())
                    {
                        var disposableFieldsHashSet = new HashSet <ISymbol>(disposableFields);
                        IEnumerable <TTypeDeclarationSyntax> classDecls = GetClassDeclarationNodes(namedType, symbolContext.CancellationToken);
                        foreach (TTypeDeclarationSyntax classDecl in classDecls)
                        {
                            SemanticModel            model       = symbolContext.Compilation.GetSemanticModel(classDecl.SyntaxTree);
                            IEnumerable <SyntaxNode> syntaxNodes = classDecl.DescendantNodes(n => !(n is TTypeDeclarationSyntax) || ReferenceEquals(n, classDecl))
                                                                   .Where(n => IsDisposableFieldCreation(n,
                                                                                                         model,
                                                                                                         disposableFieldsHashSet,
                                                                                                         symbolContext.CancellationToken));
                            if (syntaxNodes.Any())
                            {
                                symbolContext.ReportDiagnostic(namedType.CreateDiagnostic(Rule, namedType.Name));
                                return;
                            }
                        }
                    }
                }
            }
 /// <summary>
 /// Checks rule: Remove the finalizer from type {0}, override Dispose(bool disposing), and put the finalization logic in the code path where 'disposing' is false.
 /// </summary>
 private static void CheckFinalizeOverrideRule(INamedTypeSymbol type, SymbolAnalysisContext context)
 {
     if (type.HasFinalizer())
     {
         context.ReportDiagnostic(type.CreateDiagnostic(FinalizeOverrideRule, type.Name));
     }
 }
 private static void ReportInvalidContentDataType(SymbolAnalysisContext symbolContext, INamedTypeSymbol namedType)
 {
     symbolContext.ReportDiagnostic(
         namedType.CreateDiagnostic(
             Descriptors.Epi1003ContentTypeShouldImplementContentData,
             namedType.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat)));
 }
Ejemplo n.º 10
0
 private static void AnalyzeSymbol(INamedTypeSymbol symbol, Action <Diagnostic> addDiagnostic)
 {
     if (symbol.GetMembers().Any(member => IsDllImport(member)) && !IsTypeNamedCorrectly(symbol.Name))
     {
         addDiagnostic(symbol.CreateDiagnostic(Rule));
     }
 }
 protected override void AnalyzeSymbol(INamedTypeSymbol namedTypeSymbol, Compilation compilation, Action <Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken)
 {
     if (namedTypeSymbol.IsValueType && IsOverridesEquals(namedTypeSymbol) && !IsEqualityOperatorImplemented(namedTypeSymbol))
     {
         addDiagnostic(namedTypeSymbol.CreateDiagnostic(Rule));
     }
 }
 private static void AnalyzeSymbol(INamedTypeSymbol namedTypeSymbol, Action<Diagnostic> addDiagnostic)
 {
     if (namedTypeSymbol.IsValueType && namedTypeSymbol.DoesOverrideEquals() && !IsEqualityOperatorImplemented(namedTypeSymbol))
     {
         addDiagnostic(namedTypeSymbol.CreateDiagnostic(Rule));
     }
 }
 private void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compilation, Action<Diagnostic> addDiagnostic)
 {
     if (symbol.GetMembers().Any(member => IsDllImport(member)) && !IsTypeNamedCorrectly(symbol.Name))
     {
         addDiagnostic(symbol.CreateDiagnostic(Rule));
     }
 }
        private static void CheckFlags(INamedTypeSymbol namedType, ImmutableArray <IFieldSymbol> zeroValuedFields, Action <Diagnostic> addDiagnostic)
        {
            switch (zeroValuedFields.Length)
            {
            case 0:
                break;

            case 1:
                if (!IsMemberNamedNone(zeroValuedFields[0]))
                {
                    // In enum '{0}', change the name of '{1}' to 'None'.
                    addDiagnostic(zeroValuedFields[0].CreateDiagnostic(RuleRename, namedType.Name, zeroValuedFields[0].Name));
                }

                break;

            default:
            {
                // Remove all members that have the value zero from {0} except for one member that is named 'None'.
                addDiagnostic(namedType.CreateDiagnostic(RuleMultipleZero, namedType.Name));
            }

            break;
            }
        }
 private static void AnalyzeSymbol(INamedTypeSymbol namedTypeSymbol, Action <Diagnostic> addDiagnostic)
 {
     if (namedTypeSymbol.IsValueType && namedTypeSymbol.OverridesEquals() && !namedTypeSymbol.ImplementsEqualityOperators())
     {
         addDiagnostic(namedTypeSymbol.CreateDiagnostic(Rule));
     }
 }
Ejemplo n.º 16
0
 public override void AnalyzeSymbol(INamedTypeSymbol namedTypeSymbol, Compilation compilation, Action<Diagnostic> addDiagnostic, CancellationToken cancellationToken)
 {
     if (namedTypeSymbol.IsValueType && IsOverridesEquals(namedTypeSymbol) && !IsEqualityOperatorImplemented(namedTypeSymbol))
     {
         addDiagnostic(namedTypeSymbol.CreateDiagnostic(Rule));
     }
 }
Ejemplo n.º 17
0
        protected override void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compilation, Action <Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken)
        {
            var attributeUsageAttribute = WellKnownTypes.AttributeUsageAttribute(compilation);

            if (attributeUsageAttribute == null)
            {
                return;
            }

            if (symbol.IsAbstract || !symbol.IsAttribute())
            {
                return;
            }

            if (attributeUsageAttribute == null)
            {
                return;
            }

            var hasAttributeUsageAttribute = symbol.GetAttributes().Any(attribute => attribute.AttributeClass == attributeUsageAttribute);

            if (!hasAttributeUsageAttribute)
            {
                addDiagnostic(symbol.CreateDiagnostic(Rule, symbol.Name));
            }
        }
Ejemplo n.º 18
0
 public override void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compilation, Action<Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken)
 {
     if (symbol.GetMembers().Any(member => IsDllImport(member)) && !IsTypeNamedCorrectly(symbol.Name))
     {
         addDiagnostic(symbol.CreateDiagnostic(Rule));
     }
 }
 private static void CheckNonFlags(INamedTypeSymbol namedType, ImmutableArray <IFieldSymbol> zeroValuedFields, Action <Diagnostic> addDiagnostic)
 {
     if (zeroValuedFields.IsEmpty)
     {
         // Add a member to {0} that has a value of zero with a suggested name of 'None'.
         addDiagnostic(namedType.CreateDiagnostic(RuleNoZero, namedType.Name));
     }
 }
Ejemplo n.º 20
0
        public override void AnalyzeSymbol(INamedTypeSymbol namedType, Compilation compilation, Action <Diagnostic> addDiagnostic, CancellationToken cancellationToken)
        {
            if (namedType.IsAbstract || namedType.IsSealed || !namedType.IsAttribute())
            {
                return;
            }

            // Non-sealed non-abstract attribute type.
            addDiagnostic(namedType.CreateDiagnostic(Rule));
        }
        private static void AnalyzeSymbol(INamedTypeSymbol namedType, INamedTypeSymbol attributeType, Action <Diagnostic> addDiagnostic)
        {
            if (namedType.IsAbstract || namedType.IsSealed || !namedType.GetBaseTypesAndThis().Contains(attributeType))
            {
                return;
            }

            // Non-sealed non-abstract attribute type.
            addDiagnostic(namedType.CreateDiagnostic(Rule));
        }
        private static void AnalyzeSymbol(INamedTypeSymbol namedType, INamedTypeSymbol attributeType, Action<Diagnostic> addDiagnostic)
        {
            if (namedType.IsAbstract || namedType.IsSealed || !namedType.GetBaseTypesAndThis().Contains(attributeType))
            {
                return;
            }

            // Non-sealed non-abstract attribute type.
            addDiagnostic(namedType.CreateDiagnostic(Rule));
        }
        public override void AnalyzeSymbol(INamedTypeSymbol namedType, Compilation compilation, Action<Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken)
        {
            if (namedType.IsAbstract || namedType.IsSealed || !namedType.IsAttribute())
            {
                return;
            }

            // Non-sealed non-abstract attribute type.
            addDiagnostic(namedType.CreateDiagnostic(Rule));
        }
Ejemplo n.º 24
0
        private void CheckNaming(INamedTypeSymbol namedTypeSymbol, SymbolAnalysisContext context)
        {
            var name = namedTypeSymbol.Name;

            if (string.IsNullOrWhiteSpace(name))
            {
                return;
            }
            if (namedTypeSymbol.ImplementsInterface <IEvent>())
            {
                if (!validEventSuffixes_en.Any(e => name.EndsWith(e, StringComparison.Ordinal)))
                {
                    context.ReportDiagnostic(namedTypeSymbol.CreateDiagnostic(RuleMp0110, name));
                }
            }
            // IEvent derives from IMessage, so don't check if we've checked IEvent
            else if (namedTypeSymbol.ImplementsInterface <IMessage>())
            {
                if (!validMessageSuffixes_en.Any(e => name.EndsWith(e, StringComparison.Ordinal)))
                {
                    context.ReportDiagnostic(namedTypeSymbol.CreateDiagnostic(RuleMp0110, name));
                }
            }
            if (namedTypeSymbol.ImplementsInterface(typeof(IConsumer <>)))
            {
                if (!name.EndsWith(Utilities.HandlerClassSuffix, StringComparison.Ordinal))
                {
                    context.ReportDiagnostic(namedTypeSymbol.CreateDiagnostic(RuleMp0111, name));
                }
                else
                {
                    foreach (var @interface in namedTypeSymbol.AllInterfaces.Where(e => e.IsGenericType && e.TypeParameters.Length == 1 && e.Name.StartsWith("IConsumer", StringComparison.Ordinal)))
                    {
                        var suggestedName = $"{@interface.TypeArguments.First().Name}Handler";
                        if (!name.Equals(suggestedName, StringComparison.Ordinal))
                        {
                            context.ReportDiagnostic(namedTypeSymbol.CreateDiagnostic(RuleMp0113, name, suggestedName));
                        }
                    }
                }
            }
        }
Ejemplo n.º 25
0
        private static void AnalyzeNamedTypeSymbol(INamedTypeSymbol symbol, bool allowSingleLetterTypeParameters, Action <Diagnostic> addDiagnostic)
        {
            AnalyzeTypeParameters(symbol.TypeParameters, allowSingleLetterTypeParameters, addDiagnostic);

            if (symbol.TypeKind == TypeKind.Interface &&
                symbol.IsPublic() &&
                !HasCorrectPrefix(symbol, 'I'))
            {
                addDiagnostic(symbol.CreateDiagnostic(InterfaceRule, symbol.Name));
            }
        }
        private static void AnalyzeSymbol(INamedTypeSymbol symbol, INamedTypeSymbol attributeType, INamedTypeSymbol attributeUsageAttributeType, Action <Diagnostic> addDiagnostic)
        {
            if (symbol.IsAbstract || symbol.BaseType == null || !symbol.BaseType.Equals(attributeType))
            {
                return;
            }

            if (!symbol.HasAttribute(attributeUsageAttributeType))
            {
                addDiagnostic(symbol.CreateDiagnostic(Rule, symbol.Name));
            }
        }
 /// <summary>
 /// Checks rule: Remove the finalizer from type {0}, override Dispose(bool disposing), and put the finalization logic in the code path where 'disposing' is false. Otherwise, it might lead to duplicate Dispose invocations as the Base type '{1}' also provides a finalizer.
 /// </summary>
 private static void CheckFinalizeOverrideRule(INamedTypeSymbol type, SymbolAnalysisContext context)
 {
     if (type.HasFinalizer())
     {
         // Flag the finalizer if there is any base type with a finalizer, this can cause duplicate Dispose(false) invocations.
         var baseTypeWithFinalizerOpt = GetFirstBaseTypeWithFinalizerOrDefault(type);
         if (baseTypeWithFinalizerOpt != null)
         {
             context.ReportDiagnostic(type.CreateDiagnostic(FinalizeOverrideRule, type.Name, baseTypeWithFinalizerOpt.Name));
         }
     }
 }
Ejemplo n.º 28
0
            static Diagnostic CreateDiagnostic(INamedTypeSymbol violatingType, IMethodSymbol arrayBasedOverride, IMethodSymbol memoryBasedMethod)
            {
                RoslynDebug.Assert(arrayBasedOverride.OverriddenMethod is not null);

                //  We want to underline the name of the violating type in the class declaration. If the violating type
                //  is a partial class, we underline all partial declarations.

                return(violatingType.CreateDiagnostic(
                           Rule,
                           violatingType.Name,
                           arrayBasedOverride.Name,
                           memoryBasedMethod.Name));
            }
        private static void AnalyzeSymbol(INamedTypeSymbol symbol, INamedTypeSymbol attributeType, INamedTypeSymbol attributeUsageAttributeType, Action<Diagnostic> addDiagnostic)
        {
            if (symbol.IsAbstract || !symbol.GetBaseTypesAndThis().Contains(attributeType))
            {
                return;
            }

            bool hasAttributeUsageAttribute = symbol.GetAttributes().Any(attribute => attribute.AttributeClass.Equals(attributeUsageAttributeType));
            if (!hasAttributeUsageAttribute)
            {
                addDiagnostic(symbol.CreateDiagnostic(Rule, symbol.Name));
            }
        }
        private static void AnalyzeSymbol(INamedTypeSymbol symbol, INamedTypeSymbol attributeType, INamedTypeSymbol attributeUsageAttributeType, Action<Diagnostic> addDiagnostic)
        {
            if (symbol.IsAbstract || !symbol.GetBaseTypesAndThis().Contains(attributeType))
            {
                return;
            }

            bool hasAttributeUsageAttribute = symbol.GetAttributes().Any(attribute => attribute.AttributeClass.Equals(attributeUsageAttributeType));
            if (!hasAttributeUsageAttribute)
            {
                addDiagnostic(symbol.CreateDiagnostic(Rule, symbol.Name));
            }
        }
        public override void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compilation, Action <Diagnostic> addDiagnostic, CancellationToken cancellationToken)
        {
            // TODO: should this be restricted to class types?

            // static holder types are not already static/sealed and must be public or protected
            if (!symbol.IsStatic && !symbol.IsSealed &&
                (symbol.DeclaredAccessibility == Accessibility.Public || symbol.DeclaredAccessibility == Accessibility.Protected))
            {
                // only get the explicitly declared members
                var allMembers = symbol.GetMembers().Where(member => !member.IsImplicitlyDeclared);
                if (!allMembers.Any())
                {
                    return;
                }

                // to be a static holder type, all members must be static and not operator overloads
                if (allMembers.All(member => (member.IsStatic || symbol.InstanceConstructors.Contains(member)) && !IsUserdefinedOperator(member)))
                {
                    // Has a default constructor that is implicitly defined
                    if (!symbol.InstanceConstructors.IsEmpty)
                    {
                        if (symbol.InstanceConstructors.Count() == 1 &&
                            symbol.InstanceConstructors.First().Parameters.IsEmpty)
                        {
                            // If there is just the default constructor,  we can make the type static.
                            // Produce Diagnostic CA1052
                            addDiagnostic(symbol.CreateDiagnostic(CA1052Rule, symbol.Name));
                        }
                        else if (symbol.InstanceConstructors.Count() > 0)
                        {
                            // If there are explicitly defined constructors then we cannot make the type static instead just show a diagnostic.
                            // Instead we show a Diagnostic CA1053 with no fix
                            addDiagnostic(symbol.CreateDiagnostic(CA1053Rule, symbol.Name));
                        }
                    }
                }
            }
        }
        protected override void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compilation, Action<Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken)
        {
            // TODO: should this be restricted to class types?

            // static holder types are not already static/sealed and must be public or protected
            if (!symbol.IsStatic && !symbol.IsSealed
                && (symbol.DeclaredAccessibility == Accessibility.Public || symbol.DeclaredAccessibility == Accessibility.Protected))
            {
                // only get the explicitly declared members
                var allMembers = symbol.GetMembers().Where(member => !member.IsImplicitlyDeclared);
                if (!allMembers.Any())
                {
                    return;
                }

                // to be a static holder type, all members must be static and not operator overloads
                if (allMembers.All(member => (member.IsStatic || symbol.InstanceConstructors.Contains(member)) && !IsUserdefinedOperator(member)))
                {
                    // Has a default constructor that is implicitly defined
                    if (!symbol.InstanceConstructors.IsEmpty)
                    {
                        if (symbol.InstanceConstructors.Count() == 1 &&
                        symbol.InstanceConstructors.First().Parameters.IsEmpty)
                        {
                            // If there is just the default constructor,  we can make the type static.
                            // Produce Diagnostic CA1052
                            addDiagnostic(symbol.CreateDiagnostic(CA1052Rule, symbol.Name));
                        }
                        else if (symbol.InstanceConstructors.Count() > 0)
                        {
                            // If there are explicitly defined constructors then we cannot make the type static instead just show a diagnostic.
                            // Instead we show a Diagnostic CA1053 with no fix
                            addDiagnostic(symbol.CreateDiagnostic(CA1053Rule, symbol.Name));
                        }
                    }
                }
            }
        }
 protected override void AnalyzeSymbol(
     INamedTypeSymbol symbol,
     Compilation compilation,
     Action<Diagnostic> addDiagnostic,
     AnalyzerOptions options,
     CancellationToken cancellationToken)
 {
     if (!symbol.IsStatic
         && (symbol.IsPublic() || symbol.IsProtected())
         && symbol.IsStaticHolderType())
     {
         addDiagnostic(symbol.CreateDiagnostic(Rule, symbol.Name));
     }
 }
Ejemplo n.º 34
0
 protected override void AnalyzeSymbol(
     INamedTypeSymbol symbol,
     Compilation compilation,
     Action <Diagnostic> addDiagnostic,
     AnalyzerOptions options,
     CancellationToken cancellationToken)
 {
     if (!symbol.IsStatic &&
         (symbol.IsPublic() || symbol.IsProtected()) &&
         symbol.IsStaticHolderType())
     {
         addDiagnostic(symbol.CreateDiagnostic(Rule, symbol.Name));
     }
 }
Ejemplo n.º 35
0
        private static void AnalyzeSymbol(INamedTypeSymbol namedTypeSymbol, INamedTypeSymbol comparableType, INamedTypeSymbol genericComparableType, Action <Diagnostic> addDiagnostic)
        {
            if (namedTypeSymbol.DeclaredAccessibility == Accessibility.Private || namedTypeSymbol.TypeKind == TypeKind.Interface)
            {
                return;
            }

            if (namedTypeSymbol.AllInterfaces.Any(t => t.Equals(comparableType) ||
                                                  (t.ConstructedFrom?.Equals(genericComparableType) ?? false)))
            {
                if (!(namedTypeSymbol.DoesOverrideEquals() && IsEqualityOperatorImplemented(namedTypeSymbol)))
                {
                    addDiagnostic(namedTypeSymbol.CreateDiagnostic(Rule));
                }
            }
        }
Ejemplo n.º 36
0
        public override void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compilation, Action<Diagnostic> addDiagnostic, CancellationToken cancellationToken)
        {
            if (symbol.IsAbstract)
            {
                // TODO: Should we also check symbol.GetResultantVisibility() == SymbolVisibility.Public?

                var hasAnyPublicConstructors =
                    symbol.InstanceConstructors.Any(
                        (constructor) => constructor.DeclaredAccessibility == Accessibility.Public);

                if (hasAnyPublicConstructors)
                {
                    addDiagnostic(symbol.CreateDiagnostic(Rule, symbol.Name));
                }
            }
        }
        private static void AnalyzeSymbol(INamedTypeSymbol symbol, INamedTypeSymbol disposableType, Action<Diagnostic> addDiagnostic)
        {
            if (!symbol.AllInterfaces.Contains(disposableType))
            {
                var disposableFields = from member in symbol.GetMembers()
                                       where member.Kind == SymbolKind.Field && !member.IsStatic
                                       let field = member as IFieldSymbol
                                       where field.Type != null && field.Type.AllInterfaces.Contains(disposableType)
                                       select field;

                if (disposableFields.Any())
                {
                    addDiagnostic(symbol.CreateDiagnostic(Rule, symbol.Name));
                }
            }
        }
        private static void AnalyzeSymbol(INamedTypeSymbol symbol, INamedTypeSymbol disposableType, Action <Diagnostic> addDiagnostic)
        {
            if (!symbol.AllInterfaces.Contains(disposableType))
            {
                var disposableFields = from member in symbol.GetMembers()
                                       where member.Kind == SymbolKind.Field && !member.IsStatic
                                       let field = member as IFieldSymbol
                                                   where field.Type != null && field.Type.AllInterfaces.Contains(disposableType)
                                                   select field;

                if (disposableFields.Any())
                {
                    addDiagnostic(symbol.CreateDiagnostic(Rule, symbol.Name));
                }
            }
        }
Ejemplo n.º 39
0
        protected override void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compilation, Action <Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken)
        {
            if (symbol.IsAbstract)
            {
                // TODO: Should we also check symbol.GetResultantVisibility() == SymbolVisibility.Public?

                var hasAnyPublicConstructors =
                    symbol.InstanceConstructors.Any(
                        (constructor) => constructor.DeclaredAccessibility == Accessibility.Public);

                if (hasAnyPublicConstructors)
                {
                    addDiagnostic(symbol.CreateDiagnostic(Rule, symbol.Name));
                }
            }
        }
        private static void AnalyzeSymbol(INamedTypeSymbol namedTypeSymbol, INamedTypeSymbol comparableType, INamedTypeSymbol genericComparableType, Action<Diagnostic> addDiagnostic)
        {
            if (namedTypeSymbol.DeclaredAccessibility == Accessibility.Private || namedTypeSymbol.TypeKind == TypeKind.Interface || namedTypeSymbol.TypeKind == TypeKind.Enum)
            {
                return;
            }

            if (namedTypeSymbol.AllInterfaces.Any(t => t.Equals(comparableType) ||
                                                      (t.ConstructedFrom?.Equals(genericComparableType) ?? false)))
            {
                if (!(namedTypeSymbol.DoesOverrideEquals() && IsEqualityOperatorImplemented(namedTypeSymbol)))
                {
                    addDiagnostic(namedTypeSymbol.CreateDiagnostic(Rule));
                }
            }
        }
Ejemplo n.º 41
0
        private static void AnalyzeSymbol(INamedTypeSymbol namedTypeSymbol, INamedTypeSymbol comparableType, INamedTypeSymbol genericComparableType, Action <Diagnostic> addDiagnostic)
        {
            if (namedTypeSymbol.DeclaredAccessibility == Accessibility.Private || namedTypeSymbol.TypeKind == TypeKind.Interface || namedTypeSymbol.TypeKind == TypeKind.Enum)
            {
                return;
            }

            if (namedTypeSymbol.AllInterfaces.Any(t => t.Equals(comparableType) ||
                                                  (t.ConstructedFrom?.Equals(genericComparableType) ?? false)))
            {
                if (!(namedTypeSymbol.OverridesEquals() && namedTypeSymbol.ImplementsComparisonOperators()))
                {
                    // CA1036: {0} should override Equals since it implements IComparable.
                    addDiagnostic(namedTypeSymbol.CreateDiagnostic(Rule, namedTypeSymbol.Name));
                }
            }
        }
        private static void AnalyzeSymbol(INamedTypeSymbol namedTypeSymbol, INamedTypeSymbol comparableType, INamedTypeSymbol genericComparableType, Action<Diagnostic> addDiagnostic)
        {
            if (namedTypeSymbol.DeclaredAccessibility == Accessibility.Private || namedTypeSymbol.TypeKind == TypeKind.Interface || namedTypeSymbol.TypeKind == TypeKind.Enum)
            {
                return;
            }

            if (namedTypeSymbol.AllInterfaces.Any(t => t.Equals(comparableType) ||
                                                      (t.ConstructedFrom?.Equals(genericComparableType) ?? false)))
            {
                if (!(namedTypeSymbol.OverridesEquals() && namedTypeSymbol.ImplementsComparisonOperators()))
                {
                    // CA1036: {0} should override Equals since it implements IComparable.
                    addDiagnostic(namedTypeSymbol.CreateDiagnostic(Rule, namedTypeSymbol.Name));
                }
            }
        }
        private static void AnalyzeNamedTypeSymbol(INamedTypeSymbol symbol, Action <Diagnostic> addDiagnostic)
        {
            foreach (ITypeParameterSymbol parameter in symbol.TypeParameters)
            {
                if (parameter.Name.Length > 1 && !HasCorrectPrefix(parameter, 'T'))
                {
                    addDiagnostic(parameter.CreateDiagnostic(TypeParameterRule, parameter.Name));
                }
            }

            if (symbol.TypeKind == TypeKind.Interface &&
                symbol.IsPublic() &&
                !HasCorrectPrefix(symbol, 'I'))
            {
                addDiagnostic(symbol.CreateDiagnostic(InterfaceRule, symbol.Name));
            }
        }
        private static void AnalyzeNamedTypeSymbol(INamedTypeSymbol symbol, Action<Diagnostic> addDiagnostic)
        {
            foreach (var parameter in symbol.TypeParameters)
            {
                if (!HasCorrectPrefix(parameter, 'T'))
                {
                    addDiagnostic(parameter.CreateDiagnostic(TypeParameterRule));
                }
            }

            if (symbol.TypeKind == TypeKind.Interface &&
                symbol.IsPublic() &&
                !HasCorrectPrefix(symbol, 'I'))
            {
                addDiagnostic(symbol.CreateDiagnostic(InterfaceRule));
            }
        }
        public override void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compilation, Action<Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken)
        {
            var disposableType = WellKnownTypes.IDisposable(compilation);
            if (disposableType != null && !symbol.AllInterfaces.Contains(disposableType))
            {
                var disposableFields = from member in symbol.GetMembers()
                                       where member.Kind == SymbolKind.Field && !member.IsStatic
                                       let field = member as IFieldSymbol
                                       where field.Type != null && field.Type.AllInterfaces.Contains(disposableType)
                                       select field;

                if (disposableFields.Any())
                {
                    addDiagnostic(symbol.CreateDiagnostic(Rule, symbol.Name));
                }
            }
        }
Ejemplo n.º 46
0
        public override void AnalyzeSymbol(INamedTypeSymbol namedTypeSymbol, Compilation compilation, Action<Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken)
        {
            var comparableType = WellKnownTypes.IComparable(compilation);

            if (comparableType == null)
            {
                return;
            }

            if (namedTypeSymbol.DeclaredAccessibility == Accessibility.Private)
            {
                return;
            }

            if (namedTypeSymbol.Interfaces.Contains(comparableType))
            {
                if (!(DoesOverrideEquals(namedTypeSymbol) && IsEqualityOperatorImplemented(namedTypeSymbol)))
                {
                    addDiagnostic(namedTypeSymbol.CreateDiagnostic(Rule));
                }
            }
        }
Ejemplo n.º 47
0
        protected override void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compilation, Action<Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken)
        {
            var attributeUsageAttribute = WellKnownTypes.AttributeUsageAttribute(compilation);
            if (attributeUsageAttribute == null)
            {
                return;
            }

            if (symbol.IsAbstract || !symbol.IsAttribute())
            {
                return;
            }

            if (attributeUsageAttribute == null)
            {
                return;
            }

            var hasAttributeUsageAttribute = symbol.GetAttributes().Any(attribute => attribute.AttributeClass == attributeUsageAttribute);
            if (!hasAttributeUsageAttribute)
            {
                addDiagnostic(symbol.CreateDiagnostic(Rule, symbol.Name));
            }
        }
Ejemplo n.º 48
0
 private void CheckNonFlags(INamedTypeSymbol namedType, ImmutableArray<IFieldSymbol> zeroValuedFields, Action<Diagnostic> addDiagnostic)
 {
     if (zeroValuedFields.Length == 0)
     {
         // Add a member to {0} that has a value of zero with a suggested name of 'None'.
         addDiagnostic(namedType.CreateDiagnostic(RuleNoZero, namedType.Name));
     }
 }
Ejemplo n.º 49
0
        private void CheckFlags(INamedTypeSymbol namedType, ImmutableArray<IFieldSymbol> zeroValuedFields, Action<Diagnostic> addDiagnostic)
        {
            switch (zeroValuedFields.Length)
            {
                case 0:
                    break;

                case 1:
                    if (!IsMemberNamedNone(zeroValuedFields[0]))
                    {
                        // In enum '{0}', change the name of '{1}' to 'None'.
                        addDiagnostic(zeroValuedFields[0].CreateDiagnostic(RuleRename, namedType.Name, zeroValuedFields[0].Name));
                    }

                    break;

                default:
                    {
                        // Remove all members that have the value zero from {0} except for one member that is named 'None'.
                        addDiagnostic(namedType.CreateDiagnostic(RuleMultipleZero, namedType.Name));
                    }

                    break;
            }
        }
 /// <summary>
 /// Checks rule: Remove the finalizer from type {0}, override Dispose(bool disposing), and put the finalization logic in the code path where 'disposing' is false.
 /// </summary>
 private static void CheckFinalizeOverrideRule(INamedTypeSymbol type, SymbolAnalysisContext context)
 {
     if (type.HasFinalizer())
     {
         context.ReportDiagnostic(type.CreateDiagnostic(FinalizeOverrideRule, type.Name));
     }
 }
 /// <summary>
 /// Check rule: Remove IDisposable from the list of interfaces implemented by {0} and override the base class Dispose implementation instead.
 /// </summary>
 private static void CheckIDisposableReimplementationRule(INamedTypeSymbol type, SymbolAnalysisContext context, bool implementsDisposableInBaseType)
 {
     if (implementsDisposableInBaseType)
     {
         context.ReportDiagnostic(type.CreateDiagnostic(IDisposableReimplementationRule, type.Name));
     }
 }
            public override void AnalyzeSymbol(INamedTypeSymbol namedTypeSymbol, Compilation compilation, Action<Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken)
            {
                // If the type is public and implements ISerializable
                if (namedTypeSymbol.DeclaredAccessibility == Accessibility.Public && namedTypeSymbol.AllInterfaces.Contains(this.iserializableTypeSymbol))
                {
                    if (!IsSerializable(namedTypeSymbol))
                    {
                        // CA2237 : Mark serializable types with the SerializableAttribute
                        if (namedTypeSymbol.BaseType.SpecialType == SpecialType.System_Object ||
                            IsSerializable(namedTypeSymbol.BaseType))
                        {
                            addDiagnostic(namedTypeSymbol.CreateDiagnostic(RuleCA2237, namedTypeSymbol.Name));
                        }
                    }
                    else
                    {
                        // Look for a serialization constructor.
                        // A serialization constructor takes two params of type SerializationInfo and StreamingContext.
                        var serializationCtor = namedTypeSymbol.Constructors.Where(c => c.Parameters.Count() == 2 &&
                                                                                  c.Parameters[0].Type == this.serializationInfoTypeSymbol &&
                                                                                  c.Parameters[1].Type == this.streamingContextTypeSymbol).SingleOrDefault();

                        // There is no serialization ctor - issue a diagnostic.
                        if (serializationCtor == null)
                        {
                            addDiagnostic(namedTypeSymbol.CreateDiagnostic(RuleCA2229, string.Format(FxCopRulesResources.SerializableTypeDoesntHaveCtor, namedTypeSymbol.Name)));
                        }
                        else
                        {
                            // Check the accessibility
                            // The serializationctor should be protected if the class is unsealed and private if the class is sealed.
                            if (namedTypeSymbol.IsSealed && serializationCtor.DeclaredAccessibility != Accessibility.Private)
                            {
                                addDiagnostic(serializationCtor.CreateDiagnostic(RuleCA2229, string.Format(FxCopRulesResources.SerializationCtorAccessibilityForSealedType, namedTypeSymbol.Name)));
                            }

                            if (!namedTypeSymbol.IsSealed && serializationCtor.DeclaredAccessibility != Accessibility.Protected)
                            {
                                addDiagnostic(serializationCtor.CreateDiagnostic(RuleCA2229, string.Format(FxCopRulesResources.SerializationCtorAccessibilityForUnSealedType, namedTypeSymbol.Name)));
                            }
                        }
                    }
                }

                // If this is type is marked Serializable check it's fields types' as well
                if (IsSerializable(namedTypeSymbol))
                {
                    var nonSerialableFields = namedTypeSymbol.GetMembers().OfType<IFieldSymbol>().Where(m => !IsSerializable(m.Type));
                    foreach (var field in nonSerialableFields)
                    {
                        addDiagnostic(field.CreateDiagnostic(RuleCA2235, field.Name, namedTypeSymbol.Name, field.Type));
                    }
                }
            }
Ejemplo n.º 53
0
        private void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compilation, Action<Diagnostic> addDiagnostic, CancellationToken cancellationToken)
        {
            if (symbol != null &&
                symbol.TypeKind == TypeKind.Enum &&
                symbol.DeclaredAccessibility == Accessibility.Public)
            {
                var flagsAttributeType = WellKnownTypes.FlagsAttribute(compilation);
                if (flagsAttributeType == null)
                {
                    return;
                }

                IList<ulong> memberValues;
                if (DiagnosticHelpers.TryGetEnumMemberValues(symbol, out memberValues))
                {
                    bool hasFlagsAttribute = symbol.GetAttributes().Any(a => a.AttributeClass == flagsAttributeType);
                    if (hasFlagsAttribute)
                    {
                        // Check "CA2217: Do not mark enums with FlagsAttribute"
                        IEnumerable<ulong> missingValues;
                        if (!ShouldBeFlags(memberValues, out missingValues))
                        {
                            Debug.Assert(missingValues != null);

                            var missingValuesString = missingValues.Select(v => v.ToString()).Aggregate((i, j) => i + ", " + j);
                            addDiagnostic(symbol.CreateDiagnostic(Rule2217, symbol.Name, missingValuesString));
                        }
                    }
                    else
                    {
                        // Check "CA1027: Mark enums with FlagsAttribute"
                        // Ignore continguous value enums to reduce noise.
                        if (!IsContiguous(memberValues) && ShouldBeFlags(memberValues))
                        {
                            addDiagnostic(symbol.CreateDiagnostic(Rule1027, symbol.Name));
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Checks rule: Provide an overridable implementation of Dispose(bool) on {0} or mark the type as sealed. A call to Dispose(false) should only clean up native resources. A call to Dispose(true) should clean up both managed and native resources.
 /// </summary>
 private static void CheckProvideDisposeBoolRule(INamedTypeSymbol type, SymbolAnalysisContext context)
 {
     context.ReportDiagnostic(type.CreateDiagnostic(ProvideDisposeBoolRule, type.Name));
 }