Roslyn: Analiza przepływu kontroli

W poprzednim wpisie zajęliśmy się przepływem danych, czyli sprawdzaliśmy jakie zmienne zostały zapisane lub odczytane. Analogiczną analizą jest control flow. Dzięki niej, wiemy  w którym momencie funkcja może zakończyć działanie np. przez instrukcje “return”.

Tak jak wcześniej, najpierw musimy skompilować kod:

SyntaxTree tree = CSharpSyntaxTree.ParseText(@" public class Class1 { public string TestMethod1(string a) { int localA=3,localB=5; for(int i=0;i<=10;i++) { if(a[i]!='') break; } localB++; return a; } } "); var mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location); var compilation = CSharpCompilation.Create("TestAssembly", new[] { tree }, new[] { mscorlib });

Kolejny krok to uzyskanie SemanticsModel:

SemanticModel model = compilation.GetSemanticModel(tree,true);

Analiza przypływu kontroli sprowadza się do:

ControlFlowAnalysis controlFlow = model.AnalyzeControlFlow(node);

Zajrzyjmy, co za pomocą ControlFlowAnalysis możemy dowiedzieć się:

public abstract class ControlFlowAnalysis { public abstract ImmutableArray<SyntaxNode> EntryPoints { get; } public abstract ImmutableArray<SyntaxNode> ExitPoints { get; } public abstract bool EndPointIsReachable { get; } public abstract bool StartPointIsReachable { get; } public abstract ImmutableArray<SyntaxNode> ReturnStatements { get; } public abstract bool Succeeded { get; } }

EntryPoints oraz ExitPoitns opisują wejścia do gałęzi kodu oraz ich wyjścia. ReturnStatements, jak nie trudno domyślić się, zawiera informacje o instrukcjach return, które zawsze kończą działanie funkcji.

Leave a Reply

Your email address will not be published.