Created
December 14, 2017 21:02
-
-
Save sonnemaf/0001b88db198be33d83f346a47ad874f to your computer and use it in GitHub Desktop.
InParameterOnNonReadonlyStructAnalyzer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Collections.Immutable; | |
using System.ComponentModel; | |
using System.Linq; | |
using System.Runtime.CompilerServices; | |
using System.Threading; | |
using Microsoft.CodeAnalysis; | |
using Microsoft.CodeAnalysis.CSharp; | |
using Microsoft.CodeAnalysis.CSharp.Syntax; | |
using Microsoft.CodeAnalysis.Diagnostics; | |
namespace Analyzer1 { | |
[DiagnosticAnalyzer(LanguageNames.CSharp)] | |
public class InParameterOnNonReadonlyStructAnalyzer : DiagnosticAnalyzer { | |
public const string DiagnosticId = "InParameterOnNonReadonlyStructAnalyzer"; | |
// You can change these strings in the Resources.resx file. If you do not want your analyzer to be localize-able, you can use regular strings for Title and MessageFormat. | |
// See https://github.com/dotnet/roslyn/blob/master/docs/analyzers/Localizing%20Analyzers.md for more on localization | |
private static readonly LocalizableString Title = new LocalizableResourceString(nameof(Resources.AnalyzerTitle), Resources.ResourceManager, typeof(Resources)); | |
private static readonly LocalizableString MessageFormat = new LocalizableResourceString(nameof(Resources.AnalyzerMessageFormat), Resources.ResourceManager, typeof(Resources)); | |
private static readonly LocalizableString Description = new LocalizableResourceString(nameof(Resources.AnalyzerDescription), Resources.ResourceManager, typeof(Resources)); | |
private const string Category = "Naming"; | |
private static DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, description: Description); | |
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } } | |
public override void Initialize(AnalysisContext context) { | |
context.RegisterSyntaxNodeAction(AnalyzeNode, ImmutableArray.Create(SyntaxKind.Parameter)); | |
} | |
private static void AnalyzeNode(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); | |
// Test for an InParameter with a Non-Readonly ValueType | |
if (parameterNode != null && | |
parameterNode.Modifiers.Any(m => m.IsKind(SyntaxKind.InKeyword)) && | |
parameterSymbol.Type.IsValueType && | |
!IsReadonly(parameterSymbol.Type)) { | |
// Create the Code Diagnostic | |
var diagnostic = Diagnostic.Create(Rule, parameterNode.GetLocation(), parameterNode.Identifier.Text.ToString()); | |
context.ReportDiagnostic(diagnostic); | |
} | |
} | |
} | |
private static bool IsReadonly(ITypeSymbol type) { | |
return type.GetAttributes().Any(a => a.AttributeClass.GetType().FullName == "System.Runtime.CompilerServices.IsReadOnlyAttribute"); | |
} | |
private void Foo(in int a) { | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment