private static void HandleSyntaxTree(SyntaxTreeAnalysisContext context, StyleCopSettings settings)
        {
            var syntaxRoot = context.Tree.GetRoot(context.CancellationToken);

            var descentNodes = syntaxRoot.DescendantNodes(descendIntoChildren: node => node != null && !node.IsKind(SyntaxKind.ClassDeclaration));
            var classNodes = from descentNode in descentNodes
                                where descentNode.IsKind(SyntaxKind.ClassDeclaration)
                                select descentNode as ClassDeclarationSyntax;

            string suffix;
            var fileName = FileNameHelpers.GetFileNameAndSuffix(context.Tree.FilePath, out suffix);
            var preferredClassNode = classNodes.FirstOrDefault(n => FileNameHelpers.GetConventionalFileName(n, settings.DocumentationRules.FileNamingConvention) == fileName) ?? classNodes.FirstOrDefault();

            if (preferredClassNode == null)
            {
                return;
            }

            string foundClassName = null;
            bool isPartialClass = false;

            foundClassName = preferredClassNode.Identifier.Text;
            isPartialClass = preferredClassNode.Modifiers.Any(SyntaxKind.PartialKeyword);

            foreach (var classNode in classNodes)
            {
                if (classNode == preferredClassNode || (isPartialClass && foundClassName == classNode.Identifier.Text))
                {
                    continue;
                }

                var location = NamedTypeHelpers.GetNameOrIdentifierLocation(classNode);
                if (location != null)
                {
                    context.ReportDiagnostic(Diagnostic.Create(Descriptor, location));
                }
            }
        }
            public static void HandleBaseTypeDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
            {
                if (context.GetDocumentationMode() == DocumentationMode.None)
                {
                    return;
                }

                BaseTypeDeclarationSyntax declaration = (BaseTypeDeclarationSyntax)context.Node;
                if (declaration.Modifiers.Any(SyntaxKind.PartialKeyword))
                {
                    // Handled by SA1601
                    return;
                }

                Accessibility declaredAccessibility = declaration.GetDeclaredAccessibility(context.SemanticModel, context.CancellationToken);
                Accessibility effectiveAccessibility = declaration.GetEffectiveAccessibility(context.SemanticModel, context.CancellationToken);
                if (NeedsComment(settings.DocumentationRules, declaration.Kind(), declaration.Parent.Kind(), declaredAccessibility, effectiveAccessibility))
                {
                    if (!XmlCommentHelper.HasDocumentation(declaration))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, declaration.Identifier.GetLocation()));
                    }
                }
            }
        private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
        {
            var elementOrder = settings.OrderingRules.ElementOrder;
            int kindIndex = elementOrder.IndexOf(OrderingTrait.Kind);
            if (kindIndex < 0)
            {
                return;
            }

            var compilationUnit = (NamespaceDeclarationSyntax)context.Node;

            HandleMemberList(context, elementOrder, kindIndex, compilationUnit.Members, OuterOrder);
        }
        private static void HandleTypeDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
        {
            var elementOrder = settings.OrderingRules.ElementOrder;
            int kindIndex = elementOrder.IndexOf(OrderingTrait.Kind);
            if (kindIndex < 0)
            {
                return;
            }

            var typeDeclaration = (TypeDeclarationSyntax)context.Node;

            HandleMemberList(context, elementOrder, kindIndex, typeDeclaration.Members, TypeMemberOrder);
        }
            public UsingsHelper(StyleCopSettings settings, SemanticModel semanticModel, Document document, CompilationUnitSyntax compilationUnit)
            {
                this.settings = settings;
                this.semanticModel = semanticModel;
                this.conditionalDirectiveTree = DirectiveSpan.BuildConditionalDirectiveTree(compilationUnit);
                this.separateSystemDirectives = settings.OrderingRules.SystemUsingDirectivesFirst;

                this.ProcessUsingDirectives(compilationUnit.Usings);
                this.ProcessMembers(compilationUnit.Members);
            }
        private static void HandleTypeDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
        {
            var elementOrder  = settings.OrderingRules.ElementOrder;
            int constantIndex = elementOrder.IndexOf(OrderingTrait.Constant);

            if (constantIndex < 0)
            {
                return;
            }

            var typeDeclaration = (TypeDeclarationSyntax)context.Node;

            var members = typeDeclaration.Members;
            var previousFieldConstant = true;
            var previousFieldStatic   = false;
            var previousFieldReadonly = false;
            var previousAccessLevel   = AccessLevel.NotSpecified;

            foreach (var member in members)
            {
                var field = member as FieldDeclarationSyntax;
                if (field == null)
                {
                    continue;
                }

                AccessLevel currentAccessLevel   = MemberOrderHelper.GetAccessLevelForOrdering(field, field.Modifiers);
                bool        currentFieldConstant = field.Modifiers.Any(SyntaxKind.ConstKeyword);
                bool        currentFieldReadonly = currentFieldConstant || field.Modifiers.Any(SyntaxKind.ReadOnlyKeyword);
                bool        currentFieldStatic   = currentFieldConstant || field.Modifiers.Any(SyntaxKind.StaticKeyword);
                bool        compareConst         = true;
                for (int j = 0; compareConst && j < constantIndex; j++)
                {
                    switch (elementOrder[j])
                    {
                    case OrderingTrait.Accessibility:
                        if (currentAccessLevel != previousAccessLevel)
                        {
                            compareConst = false;
                        }

                        continue;

                    case OrderingTrait.Readonly:
                        if (currentFieldReadonly != previousFieldReadonly)
                        {
                            compareConst = false;
                        }

                        continue;

                    case OrderingTrait.Static:
                        if (currentFieldStatic != previousFieldStatic)
                        {
                            compareConst = false;
                        }

                        continue;

                    case OrderingTrait.Kind:
                        // Only fields may be marked const, and all fields have the same kind.
                        continue;

                    case OrderingTrait.Constant:
                    default:
                        continue;
                    }
                }

                if (compareConst)
                {
                    if (!previousFieldConstant && currentFieldConstant)
                    {
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(member)));
                    }
                }

                previousFieldConstant = currentFieldConstant;
                previousFieldReadonly = currentFieldReadonly;
                previousFieldStatic   = currentFieldStatic;
                previousAccessLevel   = currentAccessLevel;
            }
        }
            private static void CheckIdentifier(SyntaxNodeAnalysisContext context, SyntaxToken identifier, StyleCopSettings settings, bool fieldDeclaration = false)
            {
                if (identifier.IsMissing)
                {
                    return;
                }

                string name = identifier.ValueText;
                if (string.IsNullOrEmpty(name))
                {
                    return;
                }

                var match = HungarianRegex.Match(name);
                if (!match.Success)
                {
                    return;
                }

                var notationValue = match.Groups["notation"].Value;
                if (settings.NamingRules.AllowCommonHungarianPrefixes && CommonPrefixes.Contains(notationValue))
                {
                    return;
                }

                if (settings.NamingRules.AllowedHungarianPrefixes.Contains(notationValue))
                {
                    return;
                }

                // Variable names must begin with lower-case letter
                context.ReportDiagnostic(Diagnostic.Create(Descriptor, identifier.GetLocation(), fieldDeclaration ? "field" : "variable", name));
            }
 public static void HandleJoinIntoClause(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
 {
     CheckIdentifier(context, ((JoinIntoClauseSyntax)context.Node).Identifier, settings);
 }
        /// <summary>
        /// This method reports a diagnostic for any using directive placed outside a namespace declaration. No
        /// diagnostics are reported unless <see cref="OrderingSettings.UsingDirectivesPlacement"/> is
        /// <see cref="UsingDirectivesPlacement.InsideNamespace"/>.
        /// </summary>
        /// <param name="context">The analysis context.</param>
        /// <param name="settings">The effective StyleCop analysis settings.</param>
        private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
        {
            if (settings.OrderingRules.UsingDirectivesPlacement != UsingDirectivesPlacement.InsideNamespace)
            {
                return;
            }

            CompilationUnitSyntax syntax = (CompilationUnitSyntax)context.Node;

            List<SyntaxNode> usingDirectives = new List<SyntaxNode>();
            foreach (SyntaxNode child in syntax.ChildNodes())
            {
                switch (child.Kind())
                {
                case SyntaxKind.ClassDeclaration:
                case SyntaxKind.InterfaceDeclaration:
                case SyntaxKind.EnumDeclaration:
                case SyntaxKind.StructDeclaration:
                case SyntaxKind.DelegateDeclaration:
                    // Suppress SA1200 if file contains a type in the global namespace
                    return;

                case SyntaxKind.AttributeList:
                    // suppress SA1200 if file contains an attribute in the global namespace
                    return;

                case SyntaxKind.UsingDirective:
                    usingDirectives.Add(child);
                    continue;

                case SyntaxKind.ExternAliasDirective:
                case SyntaxKind.NamespaceDeclaration:
                default:
                    continue;
                }
            }

            foreach (var directive in usingDirectives)
            {
                // Using directive must appear within a namespace declaration
                context.ReportDiagnostic(Diagnostic.Create(DescriptorInside, directive.GetLocation()));
            }
        }
            public static void HandleIndexerDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
            {
                if (context.GetDocumentationMode() == DocumentationMode.None)
                {
                    return;
                }

                IndexerDeclarationSyntax declaration = (IndexerDeclarationSyntax)context.Node;

                Accessibility declaredAccessibility = declaration.GetDeclaredAccessibility(context.SemanticModel, context.CancellationToken);
                Accessibility effectiveAccessibility = declaration.GetEffectiveAccessibility(context.SemanticModel, context.CancellationToken);
                if (NeedsComment(settings.DocumentationRules, declaration.Kind(), declaration.Parent.Kind(), declaredAccessibility, effectiveAccessibility))
                {
                    if (!XmlCommentHelper.HasDocumentation(declaration))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, declaration.ThisKeyword.GetLocation()));
                    }
                }
            }
            public static void HandleEventFieldDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
            {
                if (context.GetDocumentationMode() == DocumentationMode.None)
                {
                    return;
                }

                EventFieldDeclarationSyntax declaration = (EventFieldDeclarationSyntax)context.Node;
                VariableDeclarationSyntax variableDeclaration = declaration.Declaration;

                Accessibility declaredAccessibility = declaration.GetDeclaredAccessibility(context.SemanticModel, context.CancellationToken);
                Accessibility effectiveAccessibility = declaration.GetEffectiveAccessibility(context.SemanticModel, context.CancellationToken);
                if (variableDeclaration != null && NeedsComment(settings.DocumentationRules, declaration.Kind(), declaration.Parent.Kind(), declaredAccessibility, effectiveAccessibility))
                {
                    if (!XmlCommentHelper.HasDocumentation(declaration))
                    {
                        var locations = variableDeclaration.Variables.Select(v => v.Identifier.GetLocation());
                        foreach (var location in locations)
                        {
                            context.ReportDiagnostic(Diagnostic.Create(Descriptor, location));
                        }
                    }
                }
            }
            public static void HandleVariableDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
            {
                var syntax = (VariableDeclarationSyntax)context.Node;

                if (syntax.Parent.IsKind(SyntaxKind.EventFieldDeclaration))
                {
                    return;
                }

                if (NamedTypeHelpers.IsContainedInNativeMethodsClass(syntax))
                {
                    return;
                }

                var fieldDeclaration = syntax.Parent.IsKind(SyntaxKind.FieldDeclaration);
                foreach (var variableDeclarator in syntax.Variables)
                {
                    if (variableDeclarator == null)
                    {
                        continue;
                    }

                    var identifier = variableDeclarator.Identifier;
                    if (identifier.IsMissing)
                    {
                        continue;
                    }

                    string name = identifier.ValueText;
                    if (string.IsNullOrEmpty(name))
                    {
                        continue;
                    }

                    var match = HungarianRegex.Match(name);
                    if (!match.Success)
                    {
                        continue;
                    }

                    var notationValue = match.Groups["notation"].Value;
                    if (settings.NamingRules.AllowCommonHungarianPrefixes && CommonPrefixes.Contains(notationValue))
                    {
                        continue;
                    }

                    if (settings.NamingRules.AllowedHungarianPrefixes.Contains(notationValue))
                    {
                        continue;
                    }

                    // Variable names must begin with lower-case letter
                    context.ReportDiagnostic(Diagnostic.Create(Descriptor, identifier.GetLocation(), fieldDeclaration ? "field" : "variable", name));
                }
            }
            public static void HandleParameterDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
            {
                var parameter = (ParameterSyntax)context.Node;

                if (NamedTypeHelpers.IsContainedInNativeMethodsClass(parameter))
                {
                    return;
                }

                // Only parameters from method declarations can be exempt from this rule
                var memberDeclaration = parameter?.Parent?.Parent as MemberDeclarationSyntax;
                if (memberDeclaration != null)
                {
                    var semanticModel = context.SemanticModel;
                    var symbol = semanticModel.GetDeclaredSymbol(memberDeclaration);
                    if (symbol != null)
                    {
                        if (symbol.IsOverride || NamedTypeHelpers.IsImplementingAnInterfaceMember(symbol))
                        {
                            return;
                        }
                    }
                }

                CheckIdentifier(context, parameter.Identifier, settings, "parameter");
            }
Пример #14
0
            public Analyzer(AnalyzerOptions options)
            {
                StyleCopSettings settings = options.GetStyleCopSettings();

                this.documentationSettings = settings.DocumentationRules;
            }
            public static void HandleVariableDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
            {
                var syntax = (VariableDeclarationSyntax)context.Node;

                if (syntax.Parent.IsKind(SyntaxKind.EventFieldDeclaration))
                {
                    return;
                }

                if (NamedTypeHelpers.IsContainedInNativeMethodsClass(syntax))
                {
                    return;
                }

                var fieldDeclaration = syntax.Parent.IsKind(SyntaxKind.FieldDeclaration);
                foreach (var variableDeclarator in syntax.Variables)
                {
                    if (variableDeclarator == null)
                    {
                        continue;
                    }

                    var identifier = variableDeclarator.Identifier;
                    CheckIdentifier(context, identifier, settings, fieldDeclaration);
                }
            }
        /// <summary>
        /// This method reports a diagnostic for any using directive placed within a namespace declaration. No
        /// diagnostics are reported unless <see cref="OrderingSettings.UsingDirectivesPlacement"/> is
        /// <see cref="UsingDirectivesPlacement.OutsideNamespace"/>.
        /// </summary>
        /// <param name="context">The analysis context.</param>
        /// <param name="settings">The effective StyleCop analysis settings.</param>
        private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
        {
            if (settings.OrderingRules.UsingDirectivesPlacement != UsingDirectivesPlacement.OutsideNamespace)
            {
                return;
            }

            NamespaceDeclarationSyntax syntax = (NamespaceDeclarationSyntax)context.Node;
            foreach (UsingDirectiveSyntax directive in syntax.Usings)
            {
                // Using directive must appear outside a namespace declaration
                context.ReportDiagnostic(Diagnostic.Create(DescriptorOutside, directive.GetLocation()));
            }
        }
 public static void HandleQueryContinuation(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
 {
     CheckIdentifier(context, ((QueryContinuationSyntax)context.Node).Identifier, settings);
 }
        private static Document CreateTestDocument(string source, int indentationSize = 4, bool useTabs = false, int tabSize = 4)
        {
            var workspace = new AdhocWorkspace();
            workspace.Options = workspace.Options
                .WithChangedOption(FormattingOptions.IndentationSize, LanguageNames.CSharp, indentationSize)
                .WithChangedOption(FormattingOptions.UseTabs, LanguageNames.CSharp, useTabs)
                .WithChangedOption(FormattingOptions.TabSize, LanguageNames.CSharp, tabSize);

            var projectId = ProjectId.CreateNewId();
            var documentId = DocumentId.CreateNewId(projectId);
            var compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true);

            var solution = workspace.CurrentSolution
                .AddProject(projectId, TestProjectName, TestProjectName, LanguageNames.CSharp)
                .WithProjectCompilationOptions(projectId, compilationOptions)
                .AddMetadataReference(projectId, MetadataReferences.CorlibReference)
                .AddMetadataReference(projectId, MetadataReferences.SystemReference)
                .AddMetadataReference(projectId, MetadataReferences.SystemCoreReference)
                .AddMetadataReference(projectId, MetadataReferences.CSharpSymbolsReference)
                .AddMetadataReference(projectId, MetadataReferences.CodeAnalysisReference)
                .AddDocument(documentId, TestFilename, SourceText.From(source));

            StyleCopSettings defaultSettings = new StyleCopSettings();
            if (indentationSize != defaultSettings.Indentation.IndentationSize
                || useTabs != defaultSettings.Indentation.UseTabs
                || tabSize != defaultSettings.Indentation.TabSize)
            {
                string settings = $@"
{{
  ""settings"": {{
    ""indentation"": {{
      ""indentationSize"": {indentationSize},
      ""useTabs"": {useTabs.ToString().ToLowerInvariant()},
      ""tabSize"": {tabSize}
    }}
  }}
}}
";
                var settingsDocumentId = DocumentId.CreateNewId(projectId);
                solution = solution.AddAdditionalDocument(documentId, SettingsHelper.SettingsFileName, settings);
            }

            return solution.GetDocument(documentId);
        }
 public static void HandleForEachStatement(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
 {
     CheckIdentifier(context, ((ForEachStatementSyntax)context.Node).Identifier, settings);
 }
        private static void HandleTypeDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
        {
            var elementOrder = settings.OrderingRules.ElementOrder;
            int constantIndex = elementOrder.IndexOf(OrderingTrait.Constant);
            if (constantIndex < 0)
            {
                return;
            }

            var typeDeclaration = (TypeDeclarationSyntax)context.Node;

            var members = typeDeclaration.Members;
            var previousFieldConstant = true;
            var previousFieldStatic = false;
            var previousFieldReadonly = false;
            var previousAccessLevel = AccessLevel.NotSpecified;

            foreach (var member in members)
            {
                var field = member as FieldDeclarationSyntax;
                if (field == null)
                {
                    continue;
                }

                AccessLevel currentAccessLevel = MemberOrderHelper.GetAccessLevelForOrdering(field, field.Modifiers);
                bool currentFieldConstant = field.Modifiers.Any(SyntaxKind.ConstKeyword);
                bool currentFieldReadonly = currentFieldConstant || field.Modifiers.Any(SyntaxKind.ReadOnlyKeyword);
                bool currentFieldStatic = currentFieldConstant || field.Modifiers.Any(SyntaxKind.StaticKeyword);
                bool compareConst = true;
                for (int j = 0; compareConst && j < constantIndex; j++)
                {
                    switch (elementOrder[j])
                    {
                    case OrderingTrait.Accessibility:
                        if (currentAccessLevel != previousAccessLevel)
                        {
                            compareConst = false;
                        }

                        continue;

                    case OrderingTrait.Readonly:
                        if (currentFieldReadonly != previousFieldReadonly)
                        {
                            compareConst = false;
                        }

                        continue;

                    case OrderingTrait.Static:
                        if (currentFieldStatic != previousFieldStatic)
                        {
                            compareConst = false;
                        }

                        continue;

                    case OrderingTrait.Kind:
                        // Only fields may be marked const, and all fields have the same kind.
                        continue;

                    case OrderingTrait.Constant:
                    default:
                        continue;
                    }
                }

                if (compareConst)
                {
                    if (!previousFieldConstant && currentFieldConstant)
                    {
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(member)));
                    }
                }

                previousFieldConstant = currentFieldConstant;
                previousFieldReadonly = currentFieldReadonly;
                previousFieldStatic = currentFieldStatic;
                previousAccessLevel = currentAccessLevel;
            }
        }
            public UsingsHelper(StyleCopSettings settings, SemanticModel semanticModel, CompilationUnitSyntax compilationUnit, ImmutableArray<SyntaxTrivia> fileHeader)
            {
                this.settings = settings;
                this.semanticModel = semanticModel;
                this.fileHeader = fileHeader;

                this.conditionalDirectiveTree = DirectiveSpan.BuildConditionalDirectiveTree(compilationUnit);
                this.separateSystemDirectives = settings.OrderingRules.SystemUsingDirectivesFirst;

                this.ProcessUsingDirectives(compilationUnit.Usings);
                this.ProcessMembers(compilationUnit.Members);
            }
Пример #22
0
        private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
        {
            var elementOrder = settings.OrderingRules.ElementOrder;
            int staticIndex  = elementOrder.IndexOf(OrderingTrait.Static);

            if (staticIndex < 0)
            {
                return;
            }

            var compilationUnit = (NamespaceDeclarationSyntax)context.Node;

            HandleMemberList(context, elementOrder, staticIndex, compilationUnit.Members);
        }