Skip to content

Instantly share code, notes, and snippets.

@jmarolf
Last active September 22, 2016 06:28
Show Gist options
  • Save jmarolf/b2e26b7945144a978f97ad522c2a3ca0 to your computer and use it in GitHub Desktop.
Save jmarolf/b2e26b7945144a978f97ad522c2a3ca0 to your computer and use it in GitHub Desktop.
using System.Collections.Generic;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using static Microsoft.CodeAnalysis.Diagnostic;
namespace Analyzer1 {
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class NamespaceAnalyzer : DiagnosticAnalyzer {
public const string DiagnosticId = "NamespaceAnalyzer";
private static readonly string ParameterTitle = "Parameter Namespace";
private static readonly string LocalTitle = "Local Namespace";
private static readonly string MessageFormat = "Namespace name {0}";
private static readonly string Description = "Containing Namespace";
private const string Category = "Naming";
private static DiagnosticDescriptor ShowParameterContainingNamespace =
new DiagnosticDescriptor(
DiagnosticId,
ParameterTitle,
MessageFormat,
Category,
DiagnosticSeverity.Warning,
isEnabledByDefault: true,
description: Description);
private static DiagnosticDescriptor ShowLocalContainingNamespace =
new DiagnosticDescriptor(
DiagnosticId,
LocalTitle,
MessageFormat,
Category,
DiagnosticSeverity.Warning,
isEnabledByDefault: true,
description: Description);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
ImmutableArray.Create(ShowParameterContainingNamespace, ShowLocalContainingNamespace);
public override void Initialize(AnalysisContext context) {
context.RegisterSyntaxNodeAction(AnaylzeSyntax, SyntaxKind.Parameter, SyntaxKind.VariableDeclarator);
}
private void AnaylzeSyntax(SyntaxNodeAnalysisContext context) {
var syntaxNode = context.Node;
var semanticModel = context.SemanticModel;
var cancellationToken = context.CancellationToken;
var parameterNode = syntaxNode as ParameterSyntax;
if (parameterNode != null) {
var parameterSymbol = semanticModel.GetDeclaredSymbol(parameterNode, cancellationToken);
var parameterNamespaceSymbol = parameterSymbol?.ContainingNamespace;
if (parameterNamespaceSymbol != null) {
context.ReportDiagnostic(
Create(
ShowParameterContainingNamespace,
parameterNode.GetLocation(),
GetNamespaceName(parameterNamespaceSymbol)));
}
}
var localNode = syntaxNode as VariableDeclaratorSyntax;
if (localNode != null) {
var localSymbol = semanticModel.GetDeclaredSymbol(localNode, cancellationToken);
var localNamespaceSymbol = localSymbol?.ContainingNamespace;
if (localNamespaceSymbol != null) {
context.ReportDiagnostic(
Create(
ShowLocalContainingNamespace,
localNode.GetLocation(),
GetNamespaceName(localNamespaceSymbol)));
}
}
}
private static string GetNamespaceName(INamespaceSymbol namespaceSymbol) {
var result = new List<string>();
GetNameParts(namespaceSymbol, result);
return string.Join(".", result);
}
private static void GetNameParts(INamespaceSymbol namespaceSymbol, List<string> result) {
if (namespaceSymbol == null || namespaceSymbol.IsGlobalNamespace) {
return;
}
GetNameParts(namespaceSymbol.ContainingNamespace, result);
result.Add(namespaceSymbol.Name);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment