private IMethodSummarizer GetBytecodeSummarizerForMethod(IMethodDefinition methodDefinition) { //return simpleBytecodeSummarizer; TypesLocalFlowMethodSummarizer localFlowSummarizer = new TypesLocalFlowMethodSummarizer(); if (localFlowSummarizer.CanSummarizeMethod(methodDefinition)) { countUsedFlowBasedSummarizer++; return(localFlowSummarizer); } else { return(simpleBytecodeSummarizer); } }
public void TestJoinedLocalVariableLocalFlow() { string source = @"internal class Super { internal virtual int M(bool f) {return 17;} } internal class Sub1 : Super { internal Sub1(int param) { } internal override int M(bool f) { return 32; } } internal class Sub2 : Super { internal Sub2(int param) { } internal override int M(bool f) { return 3622; } } class Foo { void Run(bool flag) { Super s; if (flag) { s = new Sub1(17); } else { s = new Sub2(32); } s.M(false); } } "; ConstructWholeProgramForSources(new string[] { source }, (compilerResults, wholeProgram) => { IMethodDefinition fooRunMethod = compilerResults.FindMethodWithName("Foo::Run"); Assert.IsNotNull(fooRunMethod); LocalFlowMethodSummarizer summarizer = new TypesLocalFlowMethodSummarizer(); Assert.IsTrue(summarizer.CanSummarizeMethod(fooRunMethod)); ReachabilitySummary summary = summarizer.SummarizeMethod(fooRunMethod, wholeProgram); Assert.IsNotNull(summary); Assert.IsFalse(summary.VirtuallyCalledMethods.Contains(compilerResults.FindMethodWithName("Sub1::M"))); Assert.IsFalse(summary.VirtuallyCalledMethods.Contains(compilerResults.FindMethodWithName("Sub2::M"))); Assert.IsTrue(summary.VirtuallyCalledMethods.Contains(compilerResults.FindMethodWithName("Super::M"))); }); }
public void TestJoinedOperandStackLocalFlow() { string source = @"internal class Super { public Super() {} internal virtual int M(bool f) {return 17;} } internal class Sub1 : Super { internal Sub1(int param) {} internal override int M(bool f) { return 32; } } internal class SubSub1 : Sub1 { internal SubSub1(int param) :base(param) {} internal override int M(bool f) { return 66; } } class Foo { void Run(bool flag) { (flag? new Sub1(17) : new SubSub1(3)).M(false); (flag? new SubSub1(3) : new Sub1(17)).M(false); } } "; ConstructWholeProgramForSources(new string[] { source }, (compilerResults, wholeProgram) => { IMethodDefinition fooRunMethod = compilerResults.FindMethodWithName("Foo::Run"); Assert.IsNotNull(fooRunMethod); LocalFlowMethodSummarizer summarizer = new TypesLocalFlowMethodSummarizer(); Assert.IsTrue(summarizer.CanSummarizeMethod(fooRunMethod)); ReachabilitySummary summary = summarizer.SummarizeMethod(fooRunMethod, wholeProgram); Assert.IsNotNull(summary); Assert.IsTrue(summary.VirtuallyCalledMethods.Contains(compilerResults.FindMethodWithName("Sub1::M"))); // Note: although this method could be called, we don't actually want to dispatch on it, but rather Sub1::M Assert.IsFalse(summary.VirtuallyCalledMethods.Contains(compilerResults.FindMethodWithName("SubSub1::M"))); Assert.IsFalse(summary.VirtuallyCalledMethods.Contains(compilerResults.FindMethodWithName("Super::M"))); }); }
private IMethodSummarizer GetBytecodeSummarizerForMethod(IMethodDefinition methodDefinition) { //return simpleBytecodeSummarizer; TypesLocalFlowMethodSummarizer localFlowSummarizer = new TypesLocalFlowMethodSummarizer(); if (localFlowSummarizer.CanSummarizeMethod(methodDefinition)) { countUsedFlowBasedSummarizer++; return localFlowSummarizer; } else { return simpleBytecodeSummarizer; } }