internal void SetCodeProvider(CodeProvider codeProvider) { this.codeProvider = codeProvider; }
internal static async Task<CodeProvider> GetAsync(MethodDescriptor methodDescriptor) { Contract.Assert(CodeProvider.Solution != null); var cancellationSource = new CancellationTokenSource(); var continuations = new List<Task<Compilation>>(); foreach (var project in CodeProvider.Solution.Projects) { var compilation = await project.GetCompilationAsync(cancellationSource.Token); foreach (var tree in compilation.SyntaxTrees) { var codeProvider = new CodeProvider(tree, compilation); var pair = await codeProvider.FindMethodSyntaxAsync(methodDescriptor); if (pair != null) { // found it cancellationSource.Cancel(); return codeProvider; } } } // In some cases (e.g, default constructors or library methods, we are not going to find the code in the solution) // We should not throw an exception. Maybe return a dummy code Provider to let the analysis evolve // or an informative message in order to let the caller continue. We can declare the exception // throw new ArgumentException("Cannot find a provider for " + methodDescriptor); return null; }
internal PropagationEffects Propagate(CodeProvider codeProvider) { this.codeProvider = codeProvider; var calls = new HashSet<AnalysisInvocationExpession>(); bool retModified = false; while (workList.Count > 0) { var analysisNode = workList.First(); this.RemoveFromWorkList(analysisNode); if (IsCallNode(analysisNode) || IsDelegateCallNode(analysisNode)) { calls.Add(GetInvocationInfo(analysisNode)); continue; } if (IsRetNode(analysisNode)) { retModified = true; } var v = GetVertex(analysisNode); var types = GetTypes(analysisNode); foreach (var v1 in graph.EnumerateAdjacentVertices(v)) { var n1 = GetAnalysisNode(v1); DiffProp(types, n1); var e = graph.GetEdge(v, v1); e["Types"] = types; DiffPropDelegates(GetDelegates(analysisNode), n1); } } HasBeenPropagated = true; return new PropagationEffects(calls, retModified); }