public override void Analyze(SymbolAnalysisContext context, List<IncludeAttributeData> includeTags, List<ProtobufAttributeData> memberTags, List<ContractAttributeData> contractAttributes)
 {
     foreach (var tag in memberTags.Where(a => a.Tag >= 19000 && a.Tag <= 19999))
     {
         context.ReportDiagnostic(Diagnostic.Create(GetDescriptor(), tag.GetLocation(), tag.Tag, tag.Symbol.Name));
     }
 }
        private void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbol flagsAttribute)
        {
            var symbol = (INamedTypeSymbol)context.Symbol;

            if (symbol.TypeKind != TypeKind.Enum)
            {
                return;
            }

            SpecialType underlyingType = symbol.EnumUnderlyingType.SpecialType;
            if (underlyingType == SpecialType.System_Int32)
            {
                return;
            }

            // If accessibility of enum is not public exit
            if (symbol.GetResultantVisibility() != SymbolVisibility.Public)
            {
                return;
            }

            // If enum is Int64 and has Flags attributes then exit
            bool hasFlagsAttribute = symbol.GetAttributes().Any(a => a.AttributeClass.Equals(flagsAttribute));
            if (underlyingType == SpecialType.System_Int64 && hasFlagsAttribute)
            {
                return;
            }

            context.ReportDiagnostic(symbol.CreateDiagnostic(Rule, symbol.Name, symbol.EnumUnderlyingType));
        }
        private void AnalyzeSymbol(SymbolAnalysisContext context)
        {
            var symbol = (IMethodSymbol)context.Symbol;
            if (CommonFunctions.SkipSymbolAnalysisIgnoringAttributes(symbol, _settingsHandler)) return;

            var ignoredVariables = CommonFunctions.ItemsToIgnoreFromAttributes(symbol, SuppressionAttributes).ToList();
            var syntax = symbol.DeclaringSyntaxReferences[0].GetSyntaxAsync().Result;

            var identifiers = syntax.DescendantNodes()
                                    .Where(node => node.IsKind(SyntaxKind.VariableDeclarator))
                                    .Cast<VariableDeclaratorSyntax>()
                                    .Select(variable => variable.Identifier.Value.ToString()).ToList();


            foreach (var reassignment in GetAllNonIgnoredMutations(syntax, ignoredVariables, identifiers))
            {
                context.ReportDiagnostic(Diagnostic.Create(AnalyzerRule,
                                                           reassignment.Location,
                                                           reassignment.Name));
            }

            foreach (var ignoredSyntaxInfo in NonExistantIgnoredVariables(ignoredVariables, identifiers))
            {
                context.ReportDiagnostic(Diagnostic.Create(SuppressionMisuseRule,
                                                           ignoredSyntaxInfo.Location,
                                                           ignoredSyntaxInfo.Name));
            }
        }
        private static void AnalyzeField(SymbolAnalysisContext symbolAnalysisContext)
        {
            var fieldDeclarationSyntax = (IFieldSymbol)symbolAnalysisContext.Symbol;
            if (!IsFieldPrivate(fieldDeclarationSyntax) &&
                !IsStaticReadonly(fieldDeclarationSyntax) &&
                IsParentAClass(fieldDeclarationSyntax) &&
                !fieldDeclarationSyntax.IsConst)
            {
                foreach (var location in symbolAnalysisContext.Symbol.Locations)
                {
                    if (!location.IsInSource)
                    {
                        // assume symbols not defined in a source document are "out of reach"
                        return;
                    }

                    if (location.SourceTree.IsGeneratedDocument(symbolAnalysisContext.Compilation, symbolAnalysisContext.CancellationToken))
                    {
                        return;
                    }
                }

                symbolAnalysisContext.ReportDiagnostic(Diagnostic.Create(Descriptor, fieldDeclarationSyntax.Locations[0]));
            }
        }
        private static void AnalyzeSymbol(SymbolAnalysisContext context)
        {
            var namedSymbol = context.Symbol as INamedTypeSymbol;
            var iMvxViewType = context.Compilation.GetTypeByMetadataName(typeof(IMvxView).FullName);

            if (namedSymbol != null &&
                namedSymbol.ImplementsSymbol(iMvxViewType) &&
                namedSymbol.GetMembers(ViewModelPropertyName).Any())
            {
                var viewModelProperty = namedSymbol.GetMembers(ViewModelPropertyName).FirstOrDefault() as IPropertySymbol;
                var viewModelReturnType = viewModelProperty?.Type;

                if (!IsViewModelType(context, viewModelReturnType))
                    return;

                var syntax = namedSymbol.DeclaringSyntaxReferences.First().GetSyntax() as ClassDeclarationSyntax;

                var baseType = syntax?.BaseList.Types.First();

                if (baseType?.Type is GenericNameSyntax) return;

                context.ReportDiagnostic(
                    Diagnostic.Create(
                        Rule
                        , baseType?.GetLocation()
                        , baseType?.ToString())
                );
            }
        }
예제 #6
0
        /// <summary>
        /// Détermine si l'ordre d'assignations des champs est correct (en tête, par ordre alphabétique).
        /// </summary>
        /// <param name="context">Le contexte du symbole.</param>
        /// <returns>Oui ou non.</returns>
        private static async Task<bool> OrdreAssignationEstFaux(SymbolAnalysisContext context)
        {
            // On vérifie que la méthode est bien un constructeur.
            if ((context.Symbol as IMethodSymbol)?.MethodKind != MethodKind.Constructor)
                return false;

            // On récupère les informations nécessaires du contexte du symbole.
            var location = context.Symbol.Locations.First();
            var racine = await location.SourceTree.GetRootAsync();
            var modèleSémantique = context.Compilation.GetSemanticModel(location.SourceTree);
            var méthode = racine.FindNode(location.SourceSpan) as ConstructorDeclarationSyntax;

            // On récupère le corps du constructeur.
            var corps = méthode?.ChildNodes().FirstOrDefault(nœud => nœud as BlockSyntax != null) as BlockSyntax;
            if (corps == null)
                return false;

            // On récupère toutes les conditions sur les paramètres.
            var conditions = Partagé.TrouveConditionsParametres(corps.Statements, méthode.ParameterList, modèleSémantique);

            // On récupère toutes les assignations de champs par des paramètres.
            var assignations = Partagé.TrouverAssignations(corps.Statements, modèleSémantique);

            // On vérifie que toutes les conditions puis toutes les assignations sont au début.
            if (!conditions.Concat(assignations).SequenceEqual(corps.Statements.Take(conditions.Count() + assignations.Count())))
                return true;

            // Et on vérifie l'ordre.
            return !assignations.SequenceEqual(assignations.OrderBy(x => x.ToString()));
        }
        public static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbol iCollectionType, INamedTypeSymbol arrayType, INamedTypeSymbol dataMemberAttribute)
        {
            var property = (IPropertySymbol)context.Symbol;

            // check whether it has a public setter
            IMethodSymbol setter = property.SetMethod;
            if (setter == null || setter.DeclaredAccessibility != Accessibility.Public)
            {
                return;
            }

            // make sure this property is NOT indexer, return type is NOT array but implement ICollection
            if (property.IsIndexer || Inherits(property.Type, arrayType) || !Inherits(property.Type, iCollectionType))
            {
                return;
            }

            if (dataMemberAttribute != null)
            {
                // Special case: the DataContractSerializer requires that a public setter exists.
                bool hasDataMemberAttribute = property.GetAttributes().Any(a => a.AttributeClass.Equals(dataMemberAttribute));
                if (hasDataMemberAttribute)
                {
                    return;
                }
            }

            context.ReportDiagnostic(property.CreateDiagnostic(Rule));
        }
예제 #8
0
        /// <summary>
        /// Vérifie si un champ en lecture seule à bien été initialisé.
        /// </summary>
        /// <param name="context">Le contexte du symbole.</param>
        /// <returns>Oui ou non.</returns>
        private static async Task<bool> EstChampInitialisé(SymbolAnalysisContext context)
        {
            // On récupère les informations nécessaires du contexte du symbole.
            var location = context.Symbol.Locations.First();
            var racine = await location.SourceTree.GetRootAsync();
            var modèleSémantique = context.Compilation.GetSemanticModel(location.SourceTree);
            var déclarationChamp = racine.FindNode(location.SourceSpan) as VariableDeclaratorSyntax;

            // On vérifie que le champ est bien en lecture seule et n'est pas initialisé à la déclaration.
            if (déclarationChamp == null || (context.Symbol as IFieldSymbol)?.IsReadOnly == false || déclarationChamp.Initializer != null)
                return false;

            // On parcourt tous les constructeurs de la classe et récupère les assignations du champ dans chacun.
            var usages = racine.FindNode(déclarationChamp.Ancestors().OfType<ClassDeclarationSyntax>().First().Span)
                .ChildNodes().OfType<ConstructorDeclarationSyntax>()
                .SelectMany(constructeur =>
                    constructeur.DescendantNodes()
                        .Where(x =>
                        {
                            var assignation = x as AssignmentExpressionSyntax;
                            return assignation?.Left != null && modèleSémantique.GetSymbolInfo(assignation.Left).Symbol == context.Symbol;
                        }).Concat(
                    constructeur.DescendantNodes()
                        .Where(x =>
                        {
                            var argument = x as ArgumentSyntax;
                            return argument?.RefOrOutKeyword.Kind() == SyntaxKind.OutKeyword && modèleSémantique.GetSymbolInfo(argument.Expression).Symbol == context.Symbol;
                        })));

            // Si le champ n'est jamais initialisé, on lève l'erreur.
            return usages.Count() == 0;
        }
        private void CheckOperators(SymbolAnalysisContext analysisContext,
            INamedTypeSymbol namedType,
            ImmutableArray<ISymbol> operators1, ImmutableArray<ISymbol> operators2,
            string opName1, string opName2)
        {
            foreach (var operator1 in operators1)
            {
                if (!operator1.IsUserDefinedOperator())
                {
                    continue;
                }

                if (operator1.GetParameters().Length != 2)
                {
                    continue;
                }

                if (HasSymmetricOperator(operator1, operators2))
                {
                    continue;
                }

                // Operator was missing match.
                // Since_0_redefines_operator_1_it_should_also_redefine_operator_2
                analysisContext.ReportDiagnostic(operator1.CreateDiagnostic(
                    Rule, namedType.Name, opName1, opName2));
            }
        }
 private static bool ContainingTypeImplementsIDisposableAndCallsItOnTheField(SymbolAnalysisContext context, IFieldSymbol fieldSymbol)
 {
     var containingType = fieldSymbol.ContainingType;
     if (containingType == null) return false;
     var iDisposableInterface = containingType.AllInterfaces.FirstOrDefault(i => i.ToString() == "System.IDisposable");
     if (iDisposableInterface == null) return false;
     var disposableMethod = iDisposableInterface.GetMembers("Dispose").OfType<IMethodSymbol>().First(d => d.Arity == 0);
     var disposeMethodSymbol = containingType.FindImplementationForInterfaceMember(disposableMethod) as IMethodSymbol;
     if (disposeMethodSymbol == null) return false;
     if (disposeMethodSymbol.IsAbstract) return true;
     foreach (MethodDeclarationSyntax disposeMethod in disposeMethodSymbol.DeclaringSyntaxReferences.Select(sr => sr.GetSyntax()))
     {
         if (disposeMethod == null) return false;
         var semanticModel = context.Compilation.GetSemanticModel(disposeMethod.SyntaxTree);
         if (CallsDisposeOnField(fieldSymbol, disposeMethod, semanticModel)) return true;
         var invocations = disposeMethod.DescendantNodes().OfKind<InvocationExpressionSyntax>(SyntaxKind.InvocationExpression);
         foreach (var invocation in invocations)
         {
             var invocationExpressionSymbol = semanticModel.GetSymbolInfo(invocation.Expression).Symbol;
             if (invocationExpressionSymbol == null
                 || invocationExpressionSymbol.Kind != SymbolKind.Method
                 || invocationExpressionSymbol.Locations.Any(l => l.Kind != LocationKind.SourceFile)
                 || !invocationExpressionSymbol.ContainingType.Equals(containingType)) continue;
             foreach (MethodDeclarationSyntax method in invocationExpressionSymbol.DeclaringSyntaxReferences.Select(sr => sr.GetSyntax()))
                 if (CallsDisposeOnField(fieldSymbol, method, semanticModel)) return true;
         }
     }
     return false;
 }
예제 #11
0
        private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbol equatableType)
        {
            var namedType = context.Symbol as INamedTypeSymbol;
            if (namedType == null || !(namedType.TypeKind == TypeKind.Struct || namedType.TypeKind == TypeKind.Class))
            {
                return;
            }

            bool overridesObjectEquals = namedType.OverridesEquals();

            INamedTypeSymbol constructedEquatable = equatableType.Construct(namedType);
            INamedTypeSymbol implementation = namedType
                .Interfaces
                .Where(x => x.Equals(constructedEquatable))
                .FirstOrDefault();
            bool implementsEquatable = implementation != null;

            if (overridesObjectEquals && !implementsEquatable && namedType.TypeKind == TypeKind.Struct)
            {
                context.ReportDiagnostic(namedType.CreateDiagnostic(s_implementIEquatableDescriptor, namedType));
            }

            if (!overridesObjectEquals && implementsEquatable)
            {
                context.ReportDiagnostic(namedType.CreateDiagnostic(s_overridesObjectEqualsDescriptor, namedType));
            }
        }
        private void HandleMethodDeclaration(SymbolAnalysisContext context)
        {
            IMethodSymbol symbol = (IMethodSymbol)context.Symbol;
            if (symbol.Name.EndsWith("Async", StringComparison.Ordinal))
                return;

            if (symbol.Locations.IsDefaultOrEmpty)
                return;

            Location location = symbol.Locations[0];
            if (!location.IsInSource || location.SourceTree.IsGeneratedDocument(context.CancellationToken))
                return;

            // void-returning methods are not asynchronous according to their signature, even if they use `async`
            if (symbol.ReturnsVoid)
                return;

            if (!string.Equals(nameof(Task), symbol.ReturnType?.Name, StringComparison.Ordinal))
                return;

            if (!string.Equals(typeof(Task).Namespace, symbol.ReturnType?.ContainingNamespace?.ToString(), StringComparison.Ordinal))
                return;

            if (symbol.MethodKind == MethodKind.PropertyGet || symbol.MethodKind == MethodKind.PropertySet)
                return;

            context.ReportDiagnostic(Diagnostic.Create(Descriptor, symbol.Locations[0], symbol.Name));
        }
        public override void Analyze(SymbolAnalysisContext context, List<IncludeAttributeData> includeTags, List<ProtobufAttributeData> memberTags, List<ContractAttributeData> contractAttributes)
        {
            if (!includeTags.Any())
            {
                return;
            }

            var allTags = includeTags.Concat(memberTags);
           
            // Group it by tag
            var groupedByTag = allTags
                .GroupBy(m => m.Tag)
                .ToList();

            // Any group with more than one element is suspicious
            foreach (var group in groupedByTag.Where(g => g.Count() > 1))
            {
                // Any group with an include means an error
                if (group.Any(a => a is ProtoIncludeAttributeData))
                {
                    var symbolList = string.Join(", ", group.Select(g => g.GetRelevantSymbolName()));
                    foreach (var a in group)
                    {
                        var diagnostic = Diagnostic.Create(GetDescriptor(), a.GetLocation(), a.Tag, context.Symbol.Name, symbolList);
                        context.ReportDiagnostic(diagnostic);
                    }
                }
            }
        }
        private static void Analyze(SymbolAnalysisContext context)
        {
            if (context.IsGenerated()) return;
            var symbol = (INamedTypeSymbol)context.Symbol;
            if (symbol.TypeKind != TypeKind.Class) return;
            if (!symbol.Interfaces.Any(i => i.SpecialType == SpecialType.System_IDisposable)) return;
            if (symbol.IsSealed && !ContainsUserDefinedFinalizer(symbol)) return;
            if (!ContainsNonPrivateConstructors(symbol)) return;
            var disposeMethod = FindDisposeMethod(symbol);
            if (disposeMethod == null) return;
            var syntaxTree = disposeMethod.DeclaringSyntaxReferences[0]?.GetSyntax();

            var statements = ((MethodDeclarationSyntax)syntaxTree)?.Body?.Statements.OfType<ExpressionStatementSyntax>();
            if (statements != null)
            {
                foreach (var statement in statements)
                {
                    var invocation = statement.Expression as InvocationExpressionSyntax;
                    var method = invocation?.Expression as MemberAccessExpressionSyntax;
                    var identifierSyntax = method?.Expression as IdentifierNameSyntax;
                    if (identifierSyntax != null && identifierSyntax.Identifier.ToString() == "GC" && method.Name.ToString() == "SuppressFinalize")
                        return;
                }
            }
            context.ReportDiagnostic(Diagnostic.Create(Rule, disposeMethod.Locations[0], symbol.Name));
        }
        /// <summary>
        /// Implementation for CA1044: Properties should not be write only
        /// </summary>
        private static void AnalyzeSymbol(SymbolAnalysisContext context)
        {
            var property = context.Symbol as IPropertySymbol;
            if (property == null)
            {
                return;
            }
            
            // not raising a violation for when: 
            //     property is overridden because the issue can only be fixed in the base type 
            //     property is the implementaton of any interface member 
            if (property.IsOverride || property.IsImplementationOfAnyInterfaceMember())
            {
                return;
            }

            // If property is not visible outside the assembly
            if (property.GetResultantVisibility() != SymbolVisibility.Public)
            {
                return;
            }

            // We handled the non-CA1044 cases earlier.  Now, we handle CA1044 cases
            // If there is no getter then it is not accessible
            if (property.IsWriteOnly)
            {
                context.ReportDiagnostic(property.CreateDiagnostic(AddGetterRule, property.Name));
            }
            // Otherwise if there is a setter, check for its relative accessibility
            else if (!(property.IsReadOnly) && (property.GetMethod.DeclaredAccessibility < property.SetMethod.DeclaredAccessibility))
            {
                context.ReportDiagnostic(property.CreateDiagnostic(MakeMoreAccessibleRule, property.Name));
            }
        }
        private void CheckForDecreasedVisibility(SymbolAnalysisContext context)
        {
            ISymbol symbol = context.Symbol;

            // Only look for methods hiding others (not overriding). Overriding with a different visibility is already a compiler error
            if (symbol.IsOverride)
            {
                return;
            }

            // Bail out if the member is publicly accessible, or sealed, or on a sealed type
            if (IsVisibleOutsideAssembly(symbol) || symbol.IsSealed || (symbol.ContainingType?.IsSealed ?? true))
            {
                return;
            }

            // Event accessors cannot have visibility modifiers, so don't analyze them
            if ((symbol as IMethodSymbol)?.AssociatedSymbol as IEventSymbol != null)
            {
                return;
            }

            // Find members on base types that share the member's name
            System.Collections.Generic.IEnumerable<INamedTypeSymbol> ancestorTypes = symbol?.ContainingType?.GetBaseTypes() ?? Enumerable.Empty<INamedTypeSymbol>();
            System.Collections.Generic.IEnumerable<ISymbol> hiddenOrOverriddenMembers = ancestorTypes.SelectMany(t => t.GetMembers(symbol.Name));

            if (hiddenOrOverriddenMembers.Any(IsVisibleOutsideAssembly))
            {
                context.ReportDiagnostic(symbol.CreateDiagnostic(Rule));
            }
        }
예제 #17
0
        private void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbol objectType, INamedTypeSymbol equatableType)
        {
            var namedType = context.Symbol as INamedTypeSymbol;
            if (namedType == null || !(namedType.TypeKind == TypeKind.Struct || namedType.TypeKind == TypeKind.Class))
            {
                return;
            }

            var methodSymbol = namedType
                .GetMembers("Equals")
                .OfType<IMethodSymbol>()
                .Where(m => IsObjectEqualsOverride(m, objectType))
                .FirstOrDefault();
            var overridesObjectEquals = methodSymbol != null;

            var constructedEquatable = equatableType.Construct(namedType);
            var implementation = namedType
                .Interfaces
                .Where(x => x.Equals(constructedEquatable))
                .FirstOrDefault();
            var implementsEquatable = implementation != null;

            if (overridesObjectEquals && !implementsEquatable && namedType.TypeKind == TypeKind.Struct)
            {
                context.ReportDiagnostic(Diagnostic.Create(s_implementIEquatableDescriptor, methodSymbol.Locations[0], namedType));
            }

            if (!overridesObjectEquals && implementsEquatable)
            {
                context.ReportDiagnostic(Diagnostic.Create(s_overridesObjectEqualsDescriptor, namedType.Locations[0], namedType));
            }
        }
        private static void CheckClassWithOnlyUnusedPrivateConstructors(SymbolAnalysisContext context)
        {
            var namedType = context.Symbol as INamedTypeSymbol;
            if (!namedType.IsClass() ||
                namedType.IsStatic)
            {
                return;
            }

            var members = namedType.GetMembers();
            var constructors = GetConstructors(members).ToList();

            if (!constructors.Any() ||
                HasNonPrivateConstructor(constructors) ||
                HasOnlyStaticMembers(members.Except(constructors).ToList()))
            {
                return;
            }

            var classDeclarations = new RemovableDeclarationCollector(namedType, context.Compilation).ClassDeclarations;

            if (!IsAnyConstructorCalled(namedType, classDeclarations))
            {
                var message = constructors.Count > 1
                    ? "at least one of its constructors"
                    : "its constructor";

                foreach (var classDeclaration in classDeclarations)
                {
                    context.ReportDiagnosticIfNonGenerated(Diagnostic.Create(Rule, classDeclaration.SyntaxNode.Identifier.GetLocation(),
                        message));
                }
            }
        }
        private void AnalyzeSymbol(SymbolAnalysisContext context)
        {
            var symbol = (IPropertySymbol)context.Symbol;
            if (symbol.IsIndexer && !symbol.IsOverride)
            {
                if (symbol.GetParameters().Length == 1)
                {
                    ITypeSymbol paramType = symbol.GetParameters()[0].Type;

                    if (paramType.TypeKind == TypeKind.TypeParameter)
                    {
                        return;
                    }

                    if (paramType.TypeKind == TypeKind.Enum)
                    {
                        paramType = ((INamedTypeSymbol)paramType).EnumUnderlyingType;
                    }

                    if (!s_allowedTypes.Contains(paramType.SpecialType))
                    {
                        context.ReportDiagnostic(symbol.CreateDiagnostic(Rule));
                    }
                }
            }
        }
예제 #20
0
        private static void AnalyzeSymbol(SymbolAnalysisContext context)
        {
            var namedTypeSymbol = (INamedTypeSymbol)context.Symbol;

            if (HasStackOnlyAttribute(namedTypeSymbol)) {
                if (namedTypeSymbol.IsValueType) { return; }
                else { // reference types should not have StackOnlyAttribute applied
                    var diagnosticClass = Diagnostic.Create(RuleStackOnlyClass, namedTypeSymbol.Locations[0], namedTypeSymbol.Name);
                    context.ReportDiagnostic(diagnosticClass);
                }
            }

            // This is not a stack-only type, so ...
            // check if any fields are of stack-only types 
            foreach (var member in namedTypeSymbol.GetMembers())
            {
                var field = member as IFieldSymbol;
                if (field == null) { continue; }

                var fieldType = field.Type;
                if(HasStackOnlyAttribute(fieldType)) { 
                    var diagnostic = Diagnostic.Create(RuleStackOnlyField, field.Locations[0], field.Type.Name);
                    context.ReportDiagnostic(diagnostic);
                }
            }
        }
        protected void AnalyzeType(SymbolAnalysisContext context)
        {
            var potentialController = (INamedTypeSymbol)context.Symbol;
            if (potentialController.AllInterfaces.Length == 0) return;

            var controllerTechnology = DetermineWebTechnology(potentialController.AllInterfaces);
            if (controllerTechnology == WebTechnology.None) return;

            var controllerAttributes = potentialController.GetAttributes();
            foreach (var controllerAttribute in controllerAttributes)
            {
                var attributeTechnology = DetermineWebTechnology(controllerAttribute.AttributeClass.AllInterfaces);
                if (attributeTechnology != WebTechnology.None && attributeTechnology != controllerTechnology)
                    context.ReportDiagnostic(Diagnostic.Create(webTechMixDiagnosticDescriptor, potentialController.Locations[0], 
                        controllerAttribute.AttributeClass.Name, attributeTechnology, potentialController.Name, controllerTechnology));
            }

            foreach (var method in potentialController.GetMembers().Where(m => m.Kind == SymbolKind.Method))
            {
                foreach (var methodAttribute in method.GetAttributes())
                {
                    var attributeTechnology = DetermineWebTechnology(methodAttribute.AttributeClass.AllInterfaces);
                    if (attributeTechnology != WebTechnology.None && attributeTechnology != controllerTechnology)
                    {
                        context.ReportDiagnostic(Diagnostic.Create(webTechMixDiagnosticDescriptor, method.Locations[0],
                            methodAttribute.AttributeClass.Name,
                            attributeTechnology, potentialController.Name, controllerTechnology));
                        break;
                    }
                }
            }
        }
예제 #22
0
        /// <summary>
        /// Returns the first symbol matching the specified <paramref name="type"/>.
        /// </summary>
        /// <param name="type">
        /// The <see cref="T:System.Type"/> for the symbol to match.
        /// </param>
        /// <param name="context">
        /// The context to use to find the symbol.
        /// </param>
        /// <returns>
        /// The symbol if found; otherwise null.
        /// </returns>
        public static INamedTypeSymbol GetNamedSymbol(this Type type, SymbolAnalysisContext context)
        {
            foreach (var reference in context.Compilation.References)
            {
                if(reference == null)
                {
                    continue;
                }

                var assembly = context.Compilation.GetAssemblyOrModuleSymbol(reference) as IAssemblySymbol;
                if (assembly == null)
                {
                    continue;
                }

                if (!assembly.Name.Equals(type.GetTypeInfo().Assembly.GetName().Name, StringComparison.CurrentCultureIgnoreCase))
                {
                    continue;
                }

                var namedTypeSymbol = assembly.GetTypeByMetadataName(type.FullName);
                if(namedTypeSymbol == null)
                {
                    continue;
                }

                return namedTypeSymbol;
            }

            return null;
        }
        private void AnalyzeSymbol(SymbolAnalysisContext context)
        {
            var namedTypeSymbol = (INamedTypeSymbol)context.Symbol;

            var members = namedTypeSymbol.GetMembers().Where(x => !x.IsImplicitlyDeclared && x.CanBeReferencedByName).ToArray();

            var orderedMembers = members.OrderBy(x => x.DeclaredAccessibility).ThenBy(x => x.Kind).ThenBy(x => x.Name).ToArray();

            var alphabetized = true;

            for (var i = 0; i < members.Length; i++)
            {
                if(orderedMembers[i] != members[i])
                {
                    alphabetized = false;
                }
            }

            if (!alphabetized)
            {
                var diagnostic = Diagnostic.Create(Rule, namedTypeSymbol.Locations[0], namedTypeSymbol.Name);

                context.ReportDiagnostic(diagnostic);
            }
        }
        public override void Analyze(SymbolAnalysisContext context, List<IncludeAttributeData> includeTags, List<ProtobufAttributeData> memberTags, List<ContractAttributeData> contractAttributes)
        {
            var grouped = memberTags.GroupBy(t => t.Symbol);

            foreach (var tagPerSymbol in grouped)
            {
                var list = tagPerSymbol.ToList();
                var protoMemberAttributes = list.Where(a => a is ProtoMemberAttributeData).Cast<ProtoMemberAttributeData>().ToList();
                var dataMemberAttributes = list.Where(a => a is DataMemberAttributeData).Cast<DataMemberAttributeData>().ToList();

                foreach (var protoMemberTag in protoMemberAttributes)
                {
                    foreach (var mismatchedDataMember in dataMemberAttributes.Where(d => d.Tag != protoMemberTag.Tag))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(
                            GetDescriptor(), 
                            protoMemberTag.GetLocation(),
                            protoMemberTag.Symbol.Name,
                            protoMemberTag.Tag,
                            mismatchedDataMember.Tag));
                        context.ReportDiagnostic(Diagnostic.Create(
                            GetDescriptor(),
                            mismatchedDataMember.GetLocation(),
                            mismatchedDataMember.Symbol.Name,
                            protoMemberTag.Tag,
                            mismatchedDataMember.Tag));
                    }
                }
            }
        }
        private void HandleMethodDeclaration(SymbolAnalysisContext context)
        {
            IMethodSymbol symbol = (IMethodSymbol)context.Symbol;
            if (symbol.IsAsync)
                return;

            if (!symbol.Name.EndsWith("Async", StringComparison.Ordinal))
                return;

            if (symbol.Locations.IsDefaultOrEmpty)
                return;

            Location location = symbol.Locations[0];
            if (!location.IsInSource || location.SourceTree.IsGeneratedDocument(context.CancellationToken))
                return;

            if (!symbol.ReturnsVoid)
            {
                if (string.Equals(nameof(Task), symbol.ReturnType?.Name, StringComparison.Ordinal)
                    && string.Equals(typeof(Task).Namespace, symbol.ReturnType?.ContainingNamespace?.ToString(), StringComparison.Ordinal))
                {
                    return;
                }
            }

            if (symbol.IsOverride)
                return;

            context.ReportDiagnostic(Diagnostic.Create(Descriptor, symbol.Locations[0], symbol.Name));
        }
        private void AnalyzeSymbol(SymbolAnalysisContext context)
        {
            var namedTypeSymbol = context.Symbol as INamedTypeSymbol;

            //Check if type derives from Exception type
            if (namedTypeSymbol.BaseType == exceptionType)
            {
                //Get the list of constructors
                var constructors = namedTypeSymbol.Constructors;

                //Set flags for the 3 different constructos, that is being searched for
                var defaultConstructorFound = false; //flag for default constructor
                var secondConstructorFound = false; //flag for constructor with string type parameter
                var thirdConstructorFound = false; //flag for constructor with string and exception type parameter

                foreach (var ctor in constructors)
                {
                    var parameters = ctor.GetParameters();

                    //case 1: Default constructor - no parameters
                    if (parameters.Length == 0)
                    {
                        defaultConstructorFound = true;
                    }
                    //case 2: Constructor with string type parameter
                    else if (parameters.Length == 1 && parameters[0].Type.SpecialType == SpecialType.System_String)
                    {
                        secondConstructorFound = true;
                    }
                    //case 3: Constructor with string type and exception type parameter
                    else if (parameters.Length == 2 && parameters[0].Type.SpecialType == SpecialType.System_String &&
                            parameters[1].Type == exceptionType)
                    {
                        thirdConstructorFound = true;
                    }

                    if (defaultConstructorFound && secondConstructorFound && thirdConstructorFound)
                    {
                        //reaches here only when all 3 constructors are found - no diagnostic needed 
                        return;
                    }
                } //end of for loop

                if (!defaultConstructorFound) //missing default constructor
                {
                    BuildDiagnostic(context, namedTypeSymbol, MissingCtorSignature.CtorWithNoParameter, GetConstructorSignatureNoParameter(namedTypeSymbol));
                }

                if (!secondConstructorFound) //missing constructor with string parameter
                {
                    BuildDiagnostic(context, namedTypeSymbol, MissingCtorSignature.CtorWithStringParameter, GetConstructorSignatureStringTypeParameter(namedTypeSymbol));
                }

                if (!thirdConstructorFound) //missing constructor with string and exception type parameter - report diagnostic
                {
                    BuildDiagnostic(context, namedTypeSymbol, MissingCtorSignature.CtorWithStringAndExceptionParameters, GetConstructorSignatureStringAndExceptionTypeParameter(namedTypeSymbol));
                }
            }
        }
        private static bool IsViewModelType(SymbolAnalysisContext context, ITypeSymbol symbol)
        {
            var iMvxViewModelType = context.Compilation.GetTypeByMetadataName(typeof(IMvxViewModel).FullName);
            var iNotifyPropertyChangedType = context.Compilation.GetTypeByMetadataName(typeof(System.ComponentModel.INotifyPropertyChanged).FullName);

            return symbol.ImplementsSymbol(iMvxViewModelType) ||
                   symbol.ImplementsSymbol(iNotifyPropertyChangedType);
        }
 internal void AnalyzeSymbol(SymbolAnalysisContext symbolContext)
 {
     var namedType = (INamedTypeSymbol)symbolContext.Symbol;
     if (namedType.GetBaseTypes().Any(IsDiagnosticAnalyzer))
     {
         AnalyzeDiagnosticAnalyzer(symbolContext);
     }
 }
        private void HandleMethodDeclaration(SymbolAnalysisContext context)
        {
            IMethodSymbol symbol = (IMethodSymbol)context.Symbol;
            if (!symbol.IsAsync || !symbol.ReturnsVoid)
                return;

            context.ReportDiagnostic(Diagnostic.Create(Descriptor, symbol.Locations[0], symbol.Name));
        }
 private void AnalyzeInterface(SymbolAnalysisContext context)
 {
     var symbol = (INamedTypeSymbol)context.Symbol;
     if (symbol.TypeKind == TypeKind.Interface && !symbol.GetMembers().Any() && !symbol.AllInterfaces.SelectMany(s => s.GetMembers()).Any())
     {
         context.ReportDiagnostic(symbol.CreateDiagnostic(Rule));
     }
 }
예제 #31
0
        public static void AnalyzeNamedType(SymbolAnalysisContext context)
        {
            var symbol = (INamedTypeSymbol)context.Symbol;

            if (symbol.TypeKind != TypeKind.Class)
            {
                return;
            }

            if (symbol.IsStatic)
            {
                return;
            }

            if (symbol.IsAbstract)
            {
                return;
            }

            if (symbol.IsImplicitClass)
            {
                return;
            }

            if (symbol.IsImplicitlyDeclared)
            {
                return;
            }

            if (symbol.BaseType?.IsObject() != true)
            {
                return;
            }

            if (!symbol.Interfaces.IsDefaultOrEmpty)
            {
                return;
            }

            var syntaxReferences = default(ImmutableArray <SyntaxReference>);

            if (symbol.IsSealed)
            {
                syntaxReferences = symbol.DeclaringSyntaxReferences;

                if (syntaxReferences.Length != 1)
                {
                    return;
                }
            }

            if (!AnalyzeMembers(symbol))
            {
                return;
            }

            if (syntaxReferences.IsDefault)
            {
                syntaxReferences = symbol.DeclaringSyntaxReferences;
            }

            foreach (SyntaxReference syntaxReference in syntaxReferences)
            {
                var classDeclaration = (ClassDeclarationSyntax)syntaxReference.GetSyntax(context.CancellationToken);

                if (!classDeclaration.Modifiers.Contains(SyntaxKind.StaticKeyword))
                {
                    context.ReportDiagnostic(DiagnosticDescriptors.MakeClassStatic, classDeclaration.Identifier);
                    break;
                }
            }
        }
예제 #32
0
        private void AnalyzeProperty(ConcurrentBag <AnalysisResult> analysisResults, SymbolAnalysisContext symbolContext)
        {
            var property = (IPropertySymbol)symbolContext.Symbol;

            if (property.IsIndexer)
            {
                return;
            }

            // The property can't be virtual.  We don't know if it is overridden somewhere.  If it
            // is, then calls to it may not actually assign to the field.
            if (property.IsVirtual || property.IsOverride || property.IsSealed)
            {
                return;
            }

            if (property.IsWithEvents)
            {
                return;
            }

            if (property.Parameters.Length > 0)
            {
                return;
            }

            // Need at least a getter.
            if (property.GetMethod == null)
            {
                return;
            }

            var containingType = property.ContainingType;

            if (containingType == null)
            {
                return;
            }

            var declarations = property.DeclaringSyntaxReferences;

            if (declarations.Length != 1)
            {
                return;
            }

            var cancellationToken   = symbolContext.CancellationToken;
            var propertyDeclaration = property.DeclaringSyntaxReferences[0].GetSyntax(cancellationToken).FirstAncestorOrSelf <TPropertyDeclaration>();

            if (propertyDeclaration == null)
            {
                return;
            }

            var semanticModel = symbolContext.Compilation.GetSemanticModel(propertyDeclaration.SyntaxTree);
            var getterField   = GetGetterField(semanticModel, property.GetMethod, cancellationToken);

            if (getterField == null)
            {
                return;
            }

            // If the user made the field readonly, we only want to convert it to a property if we
            // can keep it readonly.
            if (getterField.IsReadOnly && !SupportsReadOnlyProperties(symbolContext.Compilation))
            {
                return;
            }

            if (!containingType.Equals(getterField.ContainingType))
            {
                // Field and property have to be in the same type.
                return;
            }

            // Property and field have to agree on type.
            if (!property.Type.Equals(getterField.Type))
            {
                return;
            }

            // Don't want to remove constants.
            if (getterField.IsConst)
            {
                return;
            }

            if (getterField.DeclaringSyntaxReferences.Length != 1)
            {
                return;
            }

            // Field and property should match in static-ness
            if (getterField.IsStatic != property.IsStatic)
            {
                return;
            }

            // A setter is optional though.
            var setMethod = property.SetMethod;

            if (setMethod != null)
            {
                var setterField = GetSetterField(semanticModel, containingType, setMethod, cancellationToken);
                if (setterField != getterField)
                {
                    // If there is a getter and a setter, they both need to agree on which field they are
                    // writing to.
                    return;
                }
            }

            var fieldReference     = getterField.DeclaringSyntaxReferences[0];
            var variableDeclarator = fieldReference.GetSyntax(symbolContext.CancellationToken) as TVariableDeclarator;

            if (variableDeclarator == null)
            {
                return;
            }

            var initializer = GetFieldInitializer(variableDeclarator, cancellationToken);

            if (initializer != null && !SupportsPropertyInitializer(symbolContext.Compilation))
            {
                return;
            }

            var fieldDeclaration = variableDeclarator?.Parent?.Parent as TFieldDeclaration;

            if (fieldDeclaration == null)
            {
                return;
            }

            // Can't remove the field if it has attributes on it.
            if (getterField.GetAttributes().Length > 0)
            {
                return;
            }

            // Looks like a viable property/field to convert into an auto property.
            analysisResults.Add(new AnalysisResult(property, getterField, propertyDeclaration, fieldDeclaration, variableDeclarator,
                                                   property.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)));
        }
        public static void AnalyzeNamedType(SymbolAnalysisContext context)
        {
            var namedType = (INamedTypeSymbol)context.Symbol;

            if (namedType.IsTypeKind(TypeKind.Class, TypeKind.Struct) &&
                namedType.Arity > 0 &&
                !namedType.IsStatic &&
                !namedType.IsImplicitClass &&
                !namedType.IsImplicitlyDeclared)
            {
                foreach (ISymbol member in namedType.GetMembers())
                {
                    if (!member.IsImplicitlyDeclared &&
                        member.IsStatic &&
                        member.IsDeclaredAccessibility(Accessibility.Public, Accessibility.Internal, Accessibility.ProtectedOrInternal))
                    {
                        switch (member.Kind)
                        {
                        case SymbolKind.Event:
                        {
                            var eventSymbol = (IEventSymbol)member;

                            if (!ContainsAnyTypeParameter(namedType.TypeParameters, eventSymbol.Type))
                            {
                                ReportDiagnostic(context, eventSymbol);
                            }

                            break;
                        }

                        case SymbolKind.Field:
                        {
                            var fieldSymbol = (IFieldSymbol)member;

                            if (!ContainsAnyTypeParameter(namedType.TypeParameters, fieldSymbol.Type))
                            {
                                ReportDiagnostic(context, fieldSymbol);
                            }

                            break;
                        }

                        case SymbolKind.Method:
                        {
                            var methodsymbol = (IMethodSymbol)member;

                            if (methodsymbol.MethodKind == MethodKind.Ordinary)
                            {
                                ImmutableArray <ITypeParameterSymbol> typeParameters = namedType.TypeParameters;

                                if (!ContainsAnyTypeParameter(typeParameters, methodsymbol.ReturnType) &&
                                    !methodsymbol.Parameters.Any(parameter => ContainsAnyTypeParameter(typeParameters, parameter.Type)))
                                {
                                    ReportDiagnostic(context, methodsymbol);
                                }
                            }

                            break;
                        }

                        case SymbolKind.Property:
                        {
                            var propertySymbol = (IPropertySymbol)member;

                            if (!propertySymbol.IsIndexer &&
                                !ContainsAnyTypeParameter(namedType.TypeParameters, propertySymbol.Type))
                            {
                                ReportDiagnostic(context, propertySymbol);
                            }

                            break;
                        }
                        }
                    }
                }
            }
        }
        private static void AnalyzeSymbolForAttribute(ref SymbolAnalysisContext context, INamedTypeSymbol exportAttributeOpt, INamedTypeSymbol importingConstructorAttribute, INamedTypeSymbol namedType, IEnumerable <AttributeData> namedTypeAttributes)
        {
            if (exportAttributeOpt is null)
            {
                return;
            }

            var exportAttributeApplication = namedTypeAttributes.FirstOrDefault(ad => ad.AttributeClass.DerivesFrom(exportAttributeOpt));

            if (exportAttributeApplication is null)
            {
                return;
            }

            IMethodSymbol importingConstructor = null;
            ImmutableArray <IMethodSymbol> nonImportingConstructors = ImmutableArray <IMethodSymbol> .Empty;

            foreach (var constructor in namedType.Constructors)
            {
                if (constructor.IsStatic)
                {
                    // Ignore static constructors
                    continue;
                }

                if (constructor.IsImplicitlyDeclared)
                {
                    if (exportAttributeApplication.ApplicationSyntaxReference is object)
                    {
                        // '{0}' is MEF-exported and should have a single importing constructor of the correct form
                        context.ReportDiagnostic(Diagnostic.Create(Rule, exportAttributeApplication.ApplicationSyntaxReference.GetSyntax().GetLocation(), ScenarioProperties.ImplicitConstructor, namedType.Name));
                    }

                    continue;
                }

                var constructorAttributes = constructor.GetAttributes();
                var appliedImportingConstructorAttribute = constructorAttributes.FirstOrDefault(ad => ad.AttributeClass.DerivesFrom(importingConstructorAttribute));
                if (appliedImportingConstructorAttribute is null)
                {
                    nonImportingConstructors = nonImportingConstructors.Add(constructor);
                    continue;
                }

                importingConstructor = constructor;
                if (constructor.DeclaredAccessibility != Accessibility.Public)
                {
                    // '{0}' is MEF-exported and should have a single importing constructor of the correct form
                    context.ReportDiagnostic(Diagnostic.Create(Rule, appliedImportingConstructorAttribute.ApplicationSyntaxReference.GetSyntax().GetLocation(), ScenarioProperties.NonPublicConstructor, namedType.Name));
                    continue;
                }
            }

            IMethodSymbol missingImportingConstructor = null;

            if (importingConstructor is null)
            {
                missingImportingConstructor = nonImportingConstructors.FirstOrDefault(constructor => constructor.DeclaredAccessibility == Accessibility.Public)
                                              ?? nonImportingConstructors.FirstOrDefault();
            }

            foreach (var constructor in nonImportingConstructors)
            {
                var properties = Equals(constructor, missingImportingConstructor) ? ScenarioProperties.MissingAttribute : ScenarioProperties.MultipleConstructors;

                // '{0}' is MEF-exported and should have a single importing constructor of the correct form
                context.ReportDiagnostic(Diagnostic.Create(Rule, constructor.DeclaringSyntaxReferences.First().GetSyntax().GetLocation(), properties, namedType.Name));
                continue;
            }
        }
예제 #35
0
        public static void AnalyzeNamedType(SymbolAnalysisContext context)
        {
            var typeSymbol = (INamedTypeSymbol)context.Symbol;

            if (typeSymbol.IsImplicitlyDeclared)
            {
                return;
            }

            if (typeSymbol.TypeKind != TypeKind.Enum)
            {
                return;
            }

            bool isFlags = typeSymbol.HasAttribute(MetadataNames.System_FlagsAttribute);

            ImmutableArray <ISymbol> members = default;

            if (isFlags &&
                !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 (isFlags &&
                !context.IsAnalyzerSuppressed(DiagnosticDescriptors.CompositeEnumValueContainsUndefinedFlag))
            {
                enumInfo = EnumSymbolInfo.Create(typeSymbol);

                ImmutableArray <EnumFieldSymbolInfo> fields = enumInfo.Fields;

                for (int i = 0; i < fields.Length; i++)
                {
                    if (fields[i].HasValue &&
                        fields[i].HasCompositeValue())
                    {
                        foreach (ulong value in (fields[i].DecomposeValue()))
                        {
                            if (!enumInfo.Contains(value))
                            {
                                ReportUndefinedFlag(context, fields[i].Symbol, value.ToString());
                            }
                        }
                    }
                }
            }

            if (isFlags &&
                !context.IsAnalyzerSuppressed(DiagnosticDescriptors.DeclareEnumValueAsCombinationOfNames))
            {
                if (members.IsDefault)
                {
                    members = typeSymbol.GetMembers();
                }

                foreach (ISymbol member in members)
                {
                    if (!(member is IFieldSymbol fieldSymbol))
                    {
                        continue;
                    }

                    if (!fieldSymbol.HasConstantValue)
                    {
                        return;
                    }

                    EnumFieldSymbolInfo fieldInfo = EnumFieldSymbolInfo.Create(fieldSymbol);

                    if (!fieldInfo.HasCompositeValue())
                    {
                        continue;
                    }

                    var declaration = (EnumMemberDeclarationSyntax)fieldInfo.Symbol.GetSyntax(context.CancellationToken);

                    ExpressionSyntax expression = declaration.EqualsValue?.Value;

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

                        List <EnumFieldSymbolInfo> values = enumInfo.Decompose(fieldInfo);

                        if (values?.Count > 1)
                        {
                            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.DeclareEnumValueAsCombinationOfNames, expression);
                        }
                    }
                }
            }

            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);
                            }
                        }
                        else if (value2 == null)
                        {
                            ReportDuplicateValue(context, enumMember2);
                        }
                        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);
                            }
                        }
                    }
                }
            }
        }
        private static void ReportDiagnostic(SymbolAnalysisContext context, [NotNull] ISymbol symbol, [NotNull] string name)
        {
            Diagnostic diagnostic = Diagnostic.Create(Rule, symbol.Locations[0], name);

            context.ReportDiagnostic(diagnostic);
        }
예제 #37
0
            protected override void AnalyzeNode(SymbolAnalysisContext symbolContext, TInvocationExpressionSyntax invocation, SemanticModel semanticModel)
            {
                var symbol = semanticModel.GetSymbolInfo(invocation, symbolContext.CancellationToken).Symbol;

                if (symbol == null || symbol.Kind != SymbolKind.Method || !symbol.Name.StartsWith("Register"))
                {
                    return;
                }

                var method = (IMethodSymbol)symbol;
                var isRegisterSymbolAction         = IsRegisterAction(RegisterSymbolActionName, method, analysisContext, compilationStartAnalysisContext);
                var isRegisterSyntaxNodeAction     = IsRegisterAction(RegisterSyntaxNodeActionName, method, analysisContext, compilationStartAnalysisContext, codeBlockStartAnalysisContext);
                var isRegisterCodeBlockStartAction = IsRegisterAction(RegisterCodeBlockStartActionName, method, analysisContext, compilationStartAnalysisContext);

                if (isRegisterSymbolAction || isRegisterSyntaxNodeAction)
                {
                    if (method.Parameters.Length == 2 && method.Parameters[1].IsParams)
                    {
                        var arguments = GetArgumentExpressions(invocation);
                        if (arguments != null)
                        {
                            var argumentCount = arguments.Count();
                            if (argumentCount >= 1)
                            {
                                var type = semanticModel.GetTypeInfo(arguments.First(), symbolContext.CancellationToken).ConvertedType;
                                if (type == null || type.Name.Equals(nameof(Action)))
                                {
                                    if (argumentCount == 1)
                                    {
                                        string arg1, arg2;
                                        if (isRegisterSymbolAction)
                                        {
                                            arg1 = nameof(SymbolKind);
                                            arg2 = "symbol";
                                        }
                                        else
                                        {
                                            arg1 = "SyntaxKind";
                                            arg2 = "syntax";
                                        }

                                        var invocationExpression = GetInvocationExpression(invocation);
                                        var diagnostic           = Diagnostic.Create(MissingKindArgumentRule, invocationExpression.GetLocation(), arg1, arg2);
                                        symbolContext.ReportDiagnostic(diagnostic);
                                    }
                                    else if (isRegisterSymbolAction)
                                    {
                                        foreach (var argument in arguments.Skip(1))
                                        {
                                            symbol = semanticModel.GetSymbolInfo(argument, symbolContext.CancellationToken).Symbol;
                                            if (symbol != null &&
                                                symbol.Kind == SymbolKind.Field &&
                                                symbolKind.Equals(symbol.ContainingType) &&
                                                !supportedSymbolKinds.Contains(symbol.Name))
                                            {
                                                var diagnostic = Diagnostic.Create(UnsupportedSymbolKindArgumentRule, argument.GetLocation(), symbol.Name);
                                                symbolContext.ReportDiagnostic(diagnostic);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                if (isRegisterSyntaxNodeAction || isRegisterCodeBlockStartAction)
                {
                    Debug.Assert(method.TypeParameters.Length > 0);

                    ITypeSymbol typeArgument = null;
                    if (method.TypeParameters.Length == 1)
                    {
                        if (method.TypeParameters[0].Name == TLanguageKindEnumName)
                        {
                            typeArgument = method.TypeArguments[0];
                        }
                    }
                    else
                    {
                        var typeParam = method.TypeParameters.SingleOrDefault(t => t.Name == TLanguageKindEnumName);
                        if (typeParam != null)
                        {
                            var index = method.TypeParameters.IndexOf(typeParam);
                            typeArgument = method.TypeArguments[index];
                        }
                    }

                    if (typeArgument != null &&
                        typeArgument.TypeKind != TypeKind.TypeParameter &&
                        typeArgument.TypeKind != TypeKind.Error &&
                        !IsSyntaxKind(typeArgument))
                    {
                        var location = typeArgument.Locations[0];
                        if (!location.IsInSource)
                        {
                            var invocationExpression = GetInvocationExpression(invocation);
                            location = invocationExpression.GetLocation();
                        }

                        var diagnostic = Diagnostic.Create(InvalidSyntaxKindTypeArgumentRule, location, typeArgument.Name, TLanguageKindEnumName, method.Name);
                        symbolContext.ReportDiagnostic(diagnostic);
                    }
                }
            }
        private static void AnalyzeEvent(SymbolAnalysisContext context)
        {
            var eventSymbol = (IEventSymbol)context.Symbol;

            if (eventSymbol.IsImplicitlyDeclared)
            {
                return;
            }

            if (eventSymbol.IsOverride)
            {
                return;
            }

            if (!eventSymbol.ExplicitInterfaceImplementations.IsDefaultOrEmpty)
            {
                return;
            }

            var namedType = eventSymbol.Type as INamedTypeSymbol;

            if (namedType?.Arity != 0)
            {
                return;
            }

            if (namedType.HasMetadataName(MetadataNames.System_EventHandler))
            {
                return;
            }

            IMethodSymbol delegateInvokeMethod = namedType.DelegateInvokeMethod;

            if (delegateInvokeMethod == null)
            {
                return;
            }

            ImmutableArray <IParameterSymbol> parameters = delegateInvokeMethod.Parameters;

            if (parameters.Length != 2)
            {
                return;
            }

            if (!parameters[0].Type.IsObject())
            {
                return;
            }

            if (eventSymbol.ImplementsInterfaceMember <IEventSymbol>(allInterfaces: true))
            {
                return;
            }

            SyntaxNode node = eventSymbol.GetSyntax(context.CancellationToken);

            TypeSyntax type = GetTypeSyntax(node);

            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UseGenericEventHandler, type);
        }
            private static void ReportDiagnostic(ITypeSymbol type, TTypeSyntax typeSyntax, SymbolAnalysisContext context)
            {
                var diagnostic = Diagnostic.Create(DoNotStorePerCompilationDataOntoFieldsRule, typeSyntax.GetLocation(), type.ToDisplayString());

                context.ReportDiagnostic(diagnostic);
            }
예제 #40
0
            public void AnalyzeSymbol(SymbolAnalysisContext context)
            {
                var namedTypeSymbol = (INamedTypeSymbol)context.Symbol;

                if (namedTypeSymbol.TypeKind is TypeKind.Delegate or TypeKind.Interface)
                {
                    return;
                }

                var implementsISerializable = namedTypeSymbol.AllInterfaces.Contains(_iserializableTypeSymbol);
                var isSerializable          = IsSerializable(namedTypeSymbol);

                // If the type is public and implements ISerializable
                if (namedTypeSymbol.DeclaredAccessibility == Accessibility.Public && implementsISerializable)
                {
                    if (!isSerializable)
                    {
                        // CA2237 : Mark serializable types with the SerializableAttribute
                        if (namedTypeSymbol.BaseType.SpecialType == SpecialType.System_Object ||
                            IsSerializable(namedTypeSymbol.BaseType))
                        {
                            context.ReportDiagnostic(namedTypeSymbol.CreateDiagnostic(RuleCA2237, namedTypeSymbol.Name));
                        }
                    }
                    else
                    {
                        // Look for a serialization constructor.
                        // A serialization constructor takes two params of type SerializationInfo and StreamingContext.
                        IMethodSymbol serializationCtor = namedTypeSymbol.Constructors
                                                          .FirstOrDefault(c => c.IsSerializationConstructor(_serializationInfoTypeSymbol, _streamingContextTypeSymbol));

                        // There is no serialization ctor - issue a diagnostic.
                        if (serializationCtor == null)
                        {
                            context.ReportDiagnostic(namedTypeSymbol.CreateDiagnostic(RuleCA2229Default, namedTypeSymbol.Name));
                        }
                        else
                        {
                            // Check the accessibility
                            // The serialization ctor should be protected if the class is unsealed and private if the class is sealed.
                            if (namedTypeSymbol.IsSealed &&
                                serializationCtor.DeclaredAccessibility != Accessibility.Private)
                            {
                                context.ReportDiagnostic(serializationCtor.CreateDiagnostic(RuleCA2229Sealed, namedTypeSymbol.Name));
                            }

                            if (!namedTypeSymbol.IsSealed &&
                                serializationCtor.DeclaredAccessibility != Accessibility.Protected)
                            {
                                context.ReportDiagnostic(serializationCtor.CreateDiagnostic(RuleCA2229Unsealed, namedTypeSymbol.Name));
                            }
                        }
                    }
                }

                // If this is type is marked Serializable and doesn't implement ISerializable, check its fields' types as well
                if (isSerializable && !implementsISerializable)
                {
                    foreach (ISymbol member in namedTypeSymbol.GetMembers())
                    {
                        // Only process field members
                        if (member is not IFieldSymbol field)
                        {
                            continue;
                        }

                        // Only process instance fields
                        if (field.IsStatic)
                        {
                            continue;
                        }

                        // Only process non-serializable fields
                        if (IsSerializable(field.Type))
                        {
                            continue;
                        }

                        // We bail out from reporting CA2235 in netstandard assemblies for types in metadata
                        // due to missing support: https://github.com/dotnet/roslyn-analyzers/issues/1775#issuecomment-519686818
                        if (_isNetStandardAssembly && field.Type.Locations.All(l => !l.IsInSource))
                        {
                            continue;
                        }

                        // Check for [NonSerialized]
                        if (field.GetAttributes().Any(x => x.AttributeClass.Equals(_nonSerializedAttributeTypeSymbol)))
                        {
                            continue;
                        }

                        // Handle compiler-generated fields (without source declaration) that have an associated symbol in code.
                        // For example, auto-property backing fields.
                        ISymbol targetSymbol = field.IsImplicitlyDeclared && field.AssociatedSymbol != null
                            ? field.AssociatedSymbol
                            : field;

                        context.ReportDiagnostic(
                            targetSymbol.CreateDiagnostic(
                                RuleCA2235,
                                targetSymbol.Name,
                                namedTypeSymbol.Name,
                                field.Type));
                    }
                }
            }
예제 #41
0
        private void AnalyzeType(SymbolAnalysisContext context)
        {
            // Are there any problems with this symbol? If there is, I don't want to continue because the code
            // fix needs a good class declaration because I will build up the DebuggerDisplay parameter based
            // on the inheritance (IEnumerable only), properties, and fields. I don't want to create a string
            // with bad data.
            var diagnostics = context.Compilation.GetDeclarationDiagnostics();

            if (diagnostics.Any())
            {
                return;
            }

            INamedTypeSymbol namedSymbol = context.Symbol as INamedTypeSymbol;

            // Right now this analyzer only applies to classes. It could be applicable to structs, but
            if (namedSymbol.IsValueType)
            {
                return;
            }

            if (namedSymbol.DeclaredAccessibility != Accessibility.Public)
            {
                return;
            }

            // If there's no "state" (fields or properties) there's no sense to have a DebuggerDisplayAttribute.
            var propsOrFields = namedSymbol.GetMembers().Where(n => ((n.Kind == SymbolKind.Property) || (n.Kind == SymbolKind.Field)));

            if (!propsOrFields.Any())
            {
                return;
            }

            // Make sure we look for the parameterless ToString that is on this type.
            IMethodSymbol method = namedSymbol.GetSpecificMethod("ToString", new Type[0]);

            if (method != null)
            {
                return;
            }

            // Grind through the attributes for DebuggerDisplay.
            var attributes = namedSymbol.GetAttributes();

            for (Int32 i = 0; i < attributes.Length; i++)
            {
                String name = attributes[i].AttributeClass.Name;
                if (name.EndsWith("DebuggerDisplayAttribute"))
                {
                    var args = attributes[i].ConstructorArguments;
                    for (Int32 j = 0; j < args.Count(); j++)
                    {
                        String textValue = args[j].Value.ToString();
                        if (!(String.IsNullOrEmpty(textValue)))
                        {
                            return;
                        }
                    }
                }
            }

            var diagnostic = Diagnostic.Create(Rule, namedSymbol.Locations[0], namedSymbol.Name);

            context.ReportDiagnostic(diagnostic);
        }
예제 #42
0
        private static void AnalyzeMethodSymbol(SymbolAnalysisContext analysisContext)
        {
            var methodSymbol = (IMethodSymbol)analysisContext.Symbol;

            if (!methodSymbol.IsExternallyVisible() ||
                !(methodSymbol.CanBeReferencedByName || methodSymbol.IsImplementationOfAnyExplicitInterfaceMember()) ||
                !methodSymbol.Locations.Any(x => x.IsInSource) ||
                string.IsNullOrWhiteSpace(methodSymbol.Name))
            {
                return;
            }

            if (!methodSymbol.IsOverride && !methodSymbol.IsImplementationOfAnyImplicitInterfaceMember())
            {
                return;
            }

            ImmutableArray <IMethodSymbol> originalDefinitions = GetOriginalDefinitions(methodSymbol);

            if (originalDefinitions.Length == 0)
            {
                // We did not find any original definitions so we don't have to do anything.
                // This can happen when the method has an override modifier,
                // but does not have any valid method it is overriding.
                return;
            }

            IMethodSymbol bestMatch      = null;
            int           bestMatchScore = -1;

            foreach (var originalDefinition in originalDefinitions)
            {
                // always prefer the method override, if it is available
                // (the overridden method will always be the first item in the list.)
                if (originalDefinition.ContainingType.TypeKind != TypeKind.Interface)
                {
                    bestMatch = originalDefinition;
                    break;
                }

                int currentMatchScore = 0;
                for (int i = 0; i < methodSymbol.Parameters.Length; i++)
                {
                    IParameterSymbol currentParameter  = methodSymbol.Parameters[i];
                    IParameterSymbol originalParameter = originalDefinition.Parameters[i];

                    if (currentParameter.Name == originalParameter.Name)
                    {
                        currentMatchScore++;
                    }
                }

                if (currentMatchScore > bestMatchScore)
                {
                    bestMatch      = originalDefinition;
                    bestMatchScore = currentMatchScore;

                    if (bestMatchScore == methodSymbol.Parameters.Length)
                    {
                        break;
                    }
                }
            }

            for (int i = 0; i < methodSymbol.Parameters.Length; i++)
            {
                IParameterSymbol currentParameter   = methodSymbol.Parameters[i];
                IParameterSymbol bestMatchParameter = bestMatch.Parameters[i];

                if (currentParameter.Name != bestMatchParameter.Name)
                {
                    var properties = ImmutableDictionary <string, string> .Empty.SetItem(NewNamePropertyName, bestMatchParameter.Name);

                    analysisContext.ReportDiagnostic(Diagnostic.Create(Rule, currentParameter.Locations.First(), properties, methodSymbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat), currentParameter.Name, bestMatchParameter.Name, bestMatch.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)));
                }
            }
        }
예제 #43
0
 private static void ReportDuplicateValue(SymbolAnalysisContext context, SyntaxNode node)
 {
     DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.DuplicateEnumValue, node);
 }
예제 #44
0
        private static void AnalyzeSymbol(
            SymbolAnalysisContext context,
            INamedTypeSymbol?iCollectionType,
            INamedTypeSymbol?gCollectionType,
            INamedTypeSymbol?iEnumerableType,
            INamedTypeSymbol?gEnumerableType,
            INamedTypeSymbol?iListType,
            INamedTypeSymbol?gListType)
        {
            var namedTypeSymbol = (INamedTypeSymbol)context.Symbol;

            // FxCop compat: only fire on externally visible types by default.
            if (!namedTypeSymbol.MatchesConfiguredVisibility(context.Options, Rule, context.CancellationToken))
            {
                return;
            }

            var allInterfacesStatus = default(CollectionsInterfaceStatus);

            foreach (var @interface in namedTypeSymbol.AllInterfaces)
            {
                var originalDefinition = @interface.OriginalDefinition;
                if (originalDefinition.Equals(iCollectionType))
                {
                    allInterfacesStatus.ICollectionPresent = true;
                }
                else if (originalDefinition.Equals(iEnumerableType))
                {
                    allInterfacesStatus.IEnumerablePresent = true;
                }
                else if (originalDefinition.Equals(iListType))
                {
                    allInterfacesStatus.IListPresent = true;
                }
                else if (originalDefinition.Equals(gCollectionType))
                {
                    allInterfacesStatus.GenericICollectionPresent = true;
                }
                else if (originalDefinition.Equals(gEnumerableType))
                {
                    allInterfacesStatus.GenericIEnumerablePresent = true;
                }
                else if (originalDefinition.Equals(gListType))
                {
                    allInterfacesStatus.GenericIListPresent = true;
                }
            }

            INamedTypeSymbol?missingInterface;
            INamedTypeSymbol?implementedInterface;

            if (allInterfacesStatus.GenericIListPresent)
            {
                // Implemented IList<T>, meaning has all 3 generic interfaces. Nothing can be wrong.
                return;
            }
            else if (allInterfacesStatus.IListPresent)
            {
                // Implemented IList but not IList<T>.
                missingInterface     = gListType;
                implementedInterface = iListType;
            }
            else if (allInterfacesStatus.GenericICollectionPresent)
            {
                // Implemented ICollection<T>, and doesn't have an inherit of IList. Nothing can be wrong
                return;
            }
            else if (allInterfacesStatus.ICollectionPresent)
            {
                // Implemented ICollection but not ICollection<T>
                missingInterface     = gCollectionType;
                implementedInterface = iCollectionType;
            }
            else if (allInterfacesStatus.GenericIEnumerablePresent)
            {
                // Implemented IEnumerable<T>, and doesn't have an inherit of ICollection. Nothing can be wrong
                return;
            }
            else if (allInterfacesStatus.IEnumerablePresent)
            {
                // Implemented IEnumerable, but not IEnumerable<T>
                missingInterface     = gEnumerableType;
                implementedInterface = iEnumerableType;
            }
            else
            {
                // No collections implementation, nothing can be wrong.
                return;
            }

            RoslynDebug.Assert(missingInterface != null && implementedInterface != null);
            context.ReportDiagnostic(Diagnostic.Create(Rule,
                                                       namedTypeSymbol.Locations.First(),
                                                       namedTypeSymbol.Name,
                                                       implementedInterface.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                       missingInterface.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)));
        }
예제 #45
0
        private static async Task AnalyzeAttributesWithinUnBoundFieldAsync(IPropertySymbol property, ImmutableArray <AttributeData> attributes,
                                                                           PXContext pxContext, SymbolAnalysisContext symbolContext, AttributeInformation attributeInformation)
        {
            foreach (AttributeData attribute in attributes)
            {
                if (attributeInformation.IsAttributeDerivedFromClass(attribute.AttributeClass, pxContext.AttributeTypes.PXDefaultAttribute) &&
                    !attributeInformation.IsAttributeDerivedFromClass(attribute.AttributeClass, pxContext.AttributeTypes.PXUnboundDefaultAttribute))
                {
                    foreach (KeyValuePair <string, TypedConstant> argument in attribute.NamedArguments)
                    {
                        if (isAttributeContainsPersistingCheckNothing(argument))
                        {
                            return;
                        }
                    }
                    Location attributeLocation = await GetAttributeLocationAsync(attribute, symbolContext.CancellationToken);

                    if (attributeLocation != null)
                    {
                        var diagnosticProperties = new Dictionary <string, string>
                        {
                            { DiagnosticProperty.IsBoundField, false.ToString() }
                        }.ToImmutableDictionary();

                        symbolContext.ReportDiagnostic(
                            Diagnostic.Create(
                                Descriptors.PX1030_DefaultAttibuteToExisitingRecords, attributeLocation, diagnosticProperties));
                    }
                }
            }
        }
 private static void AnalyzeField(SymbolAnalysisContext context, INamedTypeSymbol nonDefaultableAttribute, ConcurrentDictionary <ITypeSymbol, bool> knownNonDefaultableTypes)
 {
     AnalyzeField(context, (IFieldSymbol)context.Symbol, nonDefaultableAttribute, knownNonDefaultableTypes);
 }
            public void AnalyzeSymbol(SymbolAnalysisContext context)
            {
                var namedTypeSymbol = (INamedTypeSymbol)context.Symbol;

                if (namedTypeSymbol.TypeKind == TypeKind.Delegate || namedTypeSymbol.TypeKind == TypeKind.Interface)
                {
                    return;
                }

                // If the type is public and implements ISerializable
                if (namedTypeSymbol.DeclaredAccessibility == Accessibility.Public && namedTypeSymbol.AllInterfaces.Contains(_iserializableTypeSymbol))
                {
                    if (!IsSerializable(namedTypeSymbol))
                    {
                        // CA2237 : Mark serializable types with the SerializableAttribute
                        if (namedTypeSymbol.BaseType.SpecialType == SpecialType.System_Object ||
                            IsSerializable(namedTypeSymbol.BaseType))
                        {
                            context.ReportDiagnostic(namedTypeSymbol.CreateDiagnostic(RuleCA2237, namedTypeSymbol.Name));
                        }
                    }
                    else
                    {
                        // Look for a serialization constructor.
                        // A serialization constructor takes two params of type SerializationInfo and StreamingContext.
                        IMethodSymbol serializationCtor = namedTypeSymbol.Constructors.Where(c => c.Parameters.Count() == 2 &&
                                                                                             c.Parameters[0].Type ==
                                                                                             _serializationInfoTypeSymbol &&
                                                                                             c.Parameters[1].Type ==
                                                                                             _streamingContextTypeSymbol)
                                                          .SingleOrDefault();

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

                            if (!namedTypeSymbol.IsSealed &&
                                serializationCtor.DeclaredAccessibility != Accessibility.Protected)
                            {
                                context.ReportDiagnostic(serializationCtor.CreateDiagnostic(RuleCA2229,
                                                                                            string.Format(
                                                                                                MicrosoftNetFrameworkAnalyzersResources.ImplementSerializationConstructorsMessageMakeUnsealedMagicConstructorFamily,
                                                                                                namedTypeSymbol.Name)));
                            }
                        }
                    }
                }

                // If this is type is marked Serializable check it's fields types' as well
                if (IsSerializable(namedTypeSymbol))
                {
                    System.Collections.Generic.IEnumerable <IFieldSymbol> nonSerializableFields =
                        namedTypeSymbol.GetMembers().OfType <IFieldSymbol>().Where(m => !IsSerializable(m.Type));
                    foreach (IFieldSymbol field in nonSerializableFields)
                    {
                        // Check for [NonSerialized]
                        if (field.GetAttributes().Any(x => x.AttributeClass.Equals(_nonSerializedAttributeTypeSymbol)))
                        {
                            continue;
                        }

                        if (field.IsImplicitlyDeclared && field.AssociatedSymbol != null)
                        {
                            context.ReportDiagnostic(field.AssociatedSymbol.CreateDiagnostic(RuleCA2235,
                                                                                             field.AssociatedSymbol.Name, namedTypeSymbol.Name, field.Type));
                        }
                        else
                        {
                            context.ReportDiagnostic(field.CreateDiagnostic(RuleCA2235, field.Name, namedTypeSymbol.Name,
                                                                            field.Type));
                        }
                    }
                }
            }
    private static Location GetAttributeLocation(ref SymbolAnalysisContext symbolAnalysisContext, AttributeData attribute)
    {
        var syntax = attribute.ApplicationSyntaxReference.GetSyntax(symbolAnalysisContext.CancellationToken);

        return(syntax?.GetLocation() ?? Location.None);
    }
예제 #49
0
        private void RegisterDiagnosticForIdentifier(SyntaxToken identifier, PXContext pxContext, SymbolAnalysisContext context)
        {
            bool isDeletedDatabaseRecord          = string.Equals(identifier.ValueText, DeletedDatabaseRecord, StringComparison.OrdinalIgnoreCase);
            DiagnosticDescriptor descriptorToShow =
                isDeletedDatabaseRecord && !pxContext.CodeAnalysisSettings.IsvSpecificAnalyzersEnabled
                                        ? Descriptors.PX1027_ForbiddenFieldsInDacDeclaration_NonISV
                                        : Descriptors.PX1027_ForbiddenFieldsInDacDeclaration;

            context.ReportDiagnosticWithSuppressionCheck(
                Diagnostic.Create(descriptorToShow, identifier.GetLocation(), identifier.ValueText),
                pxContext.CodeAnalysisSettings);
        }
예제 #50
0
 /// <summary>
 /// Check namespace naming rules.
 /// </summary>
 /// <param name="context">Analysis context.</param>
 private static void AnalyzeNamespaceName(SymbolAnalysisContext context)
 {
     // Delegate.
     CheckName(context, NameNamespacesWithPascalCasing, IsPascalCase);
 }
예제 #51
0
 /// <summary>
 /// Check property naming rules.
 /// </summary>
 /// <param name="context">Analysis context.</param>
 private static void AnalyzePropertyName(SymbolAnalysisContext context)
 {
     // Delegate.
     CheckName(context, NamePropertiesWithPascalCase, IsPascalCase);
 }
예제 #52
0
 protected abstract void AnalyzeSymbol(SymbolAnalysisContext context, PXContext pxContext);
예제 #53
0
 public static void ReportDiagnosticWhenActive(this SymbolAnalysisContext context, Diagnostic diagnostic) =>
 ReportDiagnostic(new ReportingContext(context, diagnostic), SonarAnalysisContext.IsTestProjectNoCache(context.Compilation, context.Options));
예제 #54
0
 protected abstract void AnalyzeDiagnosticAnalyzer(SymbolAnalysisContext symbolContext);
예제 #55
0
 private static AttributeSyntax GetAttributeSyntax(SymbolAnalysisContext context, AttributeData attribute)
 => (AttributeSyntax)attribute.ApplicationSyntaxReference.GetSyntax(context.CancellationToken);
예제 #56
0
 public static SyntaxTree GetFirstSyntaxTree(this SymbolAnalysisContext context) =>
 context.Symbol.Locations.FirstOrDefault(l => l.SourceTree != null)?.SourceTree;
예제 #57
0
 private void AnalyzeSymbol(SymbolAnalysisContext context)
 {
     OnAbstractMember("Symbol", symbol: context.Symbol);
     OnOptions(context.Options);
 }
        private static void AnalyzeSymbol(SymbolAnalysisContext symbolContext)
        {
            var methodSymbol = (IMethodSymbol)symbolContext.Symbol;

            // FxCop compat: only analyze externally visible symbols.
            if (!methodSymbol.IsExternallyVisible())
            {
                return;
            }

            if (methodSymbol.ContainingSymbol is ITypeSymbol typeSymbol && (methodSymbol.MethodKind == MethodKind.UserDefinedOperator || methodSymbol.MethodKind == MethodKind.Conversion))
            {
                string operatorName = methodSymbol.Name;
                if (IsPropertyExpected(operatorName) && operatorName != OpFalseText)
                {
                    // don't report a diagnostic on the `op_False` method because then the user would see two diagnostics for what is really one error
                    // special-case looking for `IsTrue` instance property
                    // named properties can't be overloaded so there will only ever be 0 or 1
                    IPropertySymbol property = typeSymbol.GetMembers(IsTrueText).OfType <IPropertySymbol>().SingleOrDefault();
                    if (property == null || property.Type.SpecialType != SpecialType.System_Boolean)
                    {
                        symbolContext.ReportDiagnostic(CreateDiagnostic(PropertyRule, GetSymbolLocation(methodSymbol), AddAlternateText, IsTrueText, operatorName));
                    }
                    else if (!property.IsPublic())
                    {
                        symbolContext.ReportDiagnostic(CreateDiagnostic(VisibilityRule, GetSymbolLocation(property), FixVisibilityText, IsTrueText, operatorName));
                    }
                }
                else
                {
                    ExpectedAlternateMethodGroup expectedGroup = GetExpectedAlternateMethodGroup(operatorName, methodSymbol.ReturnType);
                    if (expectedGroup == null)
                    {
                        // no alternate methods required
                        return;
                    }

                    var matchedMethods   = new List <IMethodSymbol>();
                    var unmatchedMethods = new HashSet <string>()
                    {
                        expectedGroup.AlternateMethod1
                    };
                    if (expectedGroup.AlternateMethod2 != null)
                    {
                        unmatchedMethods.Add(expectedGroup.AlternateMethod2);
                    }

                    foreach (IMethodSymbol candidateMethod in typeSymbol.GetMembers().OfType <IMethodSymbol>())
                    {
                        if (candidateMethod.Name == expectedGroup.AlternateMethod1 || candidateMethod.Name == expectedGroup.AlternateMethod2)
                        {
                            // found an appropriately-named method
                            matchedMethods.Add(candidateMethod);
                            unmatchedMethods.Remove(candidateMethod.Name);
                        }
                    }

                    // only one public method match is required
                    if (matchedMethods.Any(m => m.IsPublic()))
                    {
                        // at least one public alternate method was found, do nothing
                    }
                    else
                    {
                        // either we found at least one method that should be public or we didn't find anything
                        IMethodSymbol notPublicMethod = matchedMethods.FirstOrDefault(m => !m.IsPublic());
                        if (notPublicMethod != null)
                        {
                            // report error for improper visibility directly on the method itself
                            symbolContext.ReportDiagnostic(CreateDiagnostic(VisibilityRule, GetSymbolLocation(notPublicMethod), FixVisibilityText, notPublicMethod.Name, operatorName));
                        }
                        else
                        {
                            // report error for missing methods on the operator overload
                            if (expectedGroup.AlternateMethod2 == null)
                            {
                                // only one alternate expected
                                symbolContext.ReportDiagnostic(CreateDiagnostic(DefaultRule, GetSymbolLocation(methodSymbol), AddAlternateText, expectedGroup.AlternateMethod1, operatorName));
                            }
                            else
                            {
                                // one of two alternates expected
                                symbolContext.ReportDiagnostic(CreateDiagnostic(MultipleRule, GetSymbolLocation(methodSymbol), AddAlternateText, expectedGroup.AlternateMethod1, expectedGroup.AlternateMethod2, operatorName));
                            }
                        }
                    }
                }
            }
        }
예제 #59
0
 /// <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));
     }
 }
        private static void Collect(
            SymbolAnalysisContext context,
            ConcurrentDictionary <INamedTypeSymbol, bool> privateOrInternalBaseClasses,
            ConcurrentDictionary <INamedTypeSymbol, Location> privateOrInternalUnsealedClasses
            )
        {
            var symbol = (INamedTypeSymbol)context.Symbol;

            if (!symbol.IsDefinition)
            {
                return;
            }

            // We can ignore types in other assemblies (forgetting about
            // InternalsVisibleTo because if we're seeing them here they must
            // be public so 1) not our deal 2) not subtypes of our internal
            // or private types. This isn't strictly necessary because of
            // the next check (ignore public types) but it is more explicit.
            if (symbol.ContainingAssembly != context.Compilation.Assembly)
            {
                return;
            }

            // We can't make calls about public unsealed types and a public
            // type can't have an internal or private base type so we can
            // safely ignore them.
            if (symbol.DeclaredAccessibility.HasFlag(Accessibility.Public))
            {
                return;
            }

            if (symbol.BaseType != null)
            {
                privateOrInternalBaseClasses[symbol.BaseType] = true;
            }

            // From this point we are trying to determine if symbol represents
            // an internal or private unsealed type

            if (symbol.IsStatic)
            {
                return;
            }

            if (symbol.IsSealed)
            {
                return;
            }

            // An abstract class can't be sealed. If this analyzer would emit a
            // diagnostic then this class is probably dead-code. That's worth
            // complaining about but not in this analyzer.
            if (symbol.IsAbstract)
            {
                return;
            }

            // Not sure how this would happen... implicit types?
            if (symbol.DeclaringSyntaxReferences.Length == 0)
            {
                return;
            }

            var firstDecl = symbol
                            .DeclaringSyntaxReferences
                            .First()
                            .GetSyntax();

            if (firstDecl is ClassDeclarationSyntax)
            {
                // at this point we know its a class, its private or internal and its not sealed
                privateOrInternalUnsealedClasses[symbol] = (firstDecl as ClassDeclarationSyntax).Identifier.GetLocation();
            }
        }