Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect closures in code with Roslyn?

Tags:

c#

roslyn

Can I detect (using roslyn) that x reference in the lambda body is closure over outer variable x, not some variable local to lambda itself?

var x = "foo";
var a = string[0];
a.Any(i => i == x);
like image 482
Seldon Avatar asked May 18 '15 10:05

Seldon


1 Answers

Yup. You can use the DataFlowAnalysis API.

var tree = CSharpSyntaxTree.ParseText(
    @"
class C{
void M(){
    var x = ""foo"";
    var a = new string[0];
    var testing = a.Any(i => i == x);
}
} 
");
var Mscorlib = PortableExecutableReference.CreateFromAssembly(typeof(object).Assembly);
var compilation = CSharpCompilation.Create("MyCompilation",
    syntaxTrees: new[] { tree }, references: new[] { Mscorlib });
var model = compilation.GetSemanticModel(tree);

var lambda = tree.GetRoot().DescendantNodes().OfType<LocalDeclarationStatementSyntax>().Last();

var dataFlowAnalysis = model.AnalyzeDataFlow(lambda);
var capturedVariables = dataFlowAnalysis.Captured;

foreach(var variable in capturedVariables)
{
    //Do something
}
like image 100
JoshVarty Avatar answered Sep 23 '22 18:09

JoshVarty