0

I'm trying to write an analyzer that does the following:

  • Find all static field declarations
  • If there are any present, check if there is a function with RuntimeInitializeOnLoadMethod attribute. If there is not, raise a diagnostic
  • If present, check whether the static field is assigned to within the method scope. If not, raise a diagnostic

Stages 1 and 2 work well, however I am running into issues with 3. My approach was to fetch the SyntaxNode of the function with the RuntimeInitializeOnLoadMethod attribute, perform data flow analysis on it, then check if the symbol of the static field is in DataFlowAnalysis.AlwaysAssigned. However, when I run the data flow analysis, the analyzer does not seem to proceed any further. The code is as follows:

        private static void AnalyzeStaticFields(SyntaxNodeAnalysisContext context)
        {
            var declaration = (FieldDeclarationSyntax)context.Node;

            if (declaration.Modifiers.Any(SyntaxKind.StaticKeyword))
            {
                // Find node with RuntimeInitializeOnLoadMethodAttribute
                SyntaxNode initializationNode;
                
                if (GetInitializationNode(context, out initializationNode)) {

                    DataFlowAnalysis dataFlowAnalysis = context.SemanticModel.AnalyzeDataFlow(initializationNode);
                    foreach (var variable in declaration.Declaration.Variables)
                    {
                        //Get symbol of static variable
                       ISymbol variableSymbol = context.SemanticModel.GetDeclaredSymbol(variable, context.CancellationToken);

                        //Check if static variable is assigned within scope of function
                        if (dataFlowAnalysis.AlwaysAssigned.Contains(variableSymbol))
                        {
                            var diagnostic = Diagnostic.Create(FieldRule, context.Node.GetLocation(), declaration.Declaration.Variables.First().Identifier.ValueText);

                            context.ReportDiagnostic(diagnostic);
                        }
                    }
                }
            }
        }

In the test snippet below, I would expect a diagnostic to be raised for the intContent variable in Class2, but it is not happening. If I remove the call to AnalyzeDataFlow and comment out conditions, the diagnostics are displayed.

class Class2
{
    private static string stringContent = "This is the default value";
    private static int intContent = -1;

    [RuntimeInitializeOnLoadMethod]
    static void OnEnterPlayMode() {
        stringContent = "Initialised value";
    }

    public static void Test()
    {
        Debug.Log($"{stringContent} {intContent}");
        EventExample.StaticEvent += Test;
    }
}

Am I doing something wrong re. the DataFlowAnalysis? I would appreciate any insight that can be provided!

0 Answers0