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"); }
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); }
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); }
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); }