Not being able to mark a parameter of a method as readonly so that it is impossible to be reassigned in the method, I started thinking abount creating an analyzer for this. The parameter would be attributed with
[AttributeUsage(AttributeTargets.Parameter)]
public class ReadOnlyAttribute: Attribute
{
// ...
}
and the signature of a method would be
public class Foo
{
public void Bar([ReadOnly] MyObject o)
{
o.DoSomething() // this is OK
o = new MyObject() // this would be flagged by the analyzer
}
}
What I have so far is an DiagnosticAnalyzer class with these members:
[DiagnosticAnalyzer(LanguageNames.CSharp)]
internal class MyDiagnosticAnalyzer : DiagnosticAnalyzer
{
private static readonly DiagnosticDescriptor Descriptor =
new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Info, true, Description, HelpLink);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create(Descriptor);
public override void Initialize(AnalysisContext context)
{
context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.Method);
}
private static void AnalyzeSymbol(SymbolAnalysisContext context)
{
var methodSymbol = context.Symbol as IMethodSymbol;
var parameters = methodSymbol.Parameters;
foreach (var p in parameters)
{
var attr = p.GetAttributes();
foreach (var a in attr)
{
if (a.AttributeClass.Name == "ReadOnlyAttribute")
{
// now I have to find all references of p in order to check if any of them is a assignment
}
}
}
}
}
How do I find all reference of a parameter within the method body? And how do I know which one of them are assigments?
I sugges you get SyntaxNode for current IMethodSymbol if it has "ReadOnlyAttribute" parameter then get all descendant nodes from SyntaxNode that are AssignmentExpressionSyntax. So, you only need to compare statement' identifiers and your parameter. Give me know if you have some questions.