1 //---------------------------------------------------------------- 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //---------------------------------------------------------------- 4 5 namespace System.Activities.Debugger 6 { 7 using System.Collections.Generic; 8 using System.Activities.Debugger.Symbol; 9 10 // Keep track of instrumentation information. 11 // - which subroot has source file but not yet instrumented. 12 // - which subroots share the same source file 13 // SubRoot is defined as an activity that has a source file 14 // (Custom Activity). 15 class InstrumentationTracker 16 { 17 // Root of the workflow to keep track. 18 Activity root; 19 20 // Mapping of subroots to their source files. 21 Dictionary<Activity, string> uninstrumentedSubRoots; 22 23 Dictionary<Activity, string> UninstrumentedSubRoots 24 { 25 get 26 { 27 if (this.uninstrumentedSubRoots == null) 28 { 29 InitializeUninstrumentedSubRoots(); 30 } 31 return this.uninstrumentedSubRoots; 32 } 33 } 34 InstrumentationTracker(Activity root)35 public InstrumentationTracker(Activity root) 36 { 37 this.root = root; 38 } 39 40 // Initialize UninstrumentedSubRoots by traversing the workflow. InitializeUninstrumentedSubRoots()41 void InitializeUninstrumentedSubRoots() 42 { 43 this.uninstrumentedSubRoots = new Dictionary<Activity, string>(); 44 45 Queue<Activity> activitiesRemaining = new Queue<Activity>(); 46 47 CollectSubRoot(this.root); 48 activitiesRemaining.Enqueue(this.root); 49 50 while (activitiesRemaining.Count > 0) 51 { 52 Activity toProcess = activitiesRemaining.Dequeue(); 53 54 foreach (Activity activity in WorkflowInspectionServices.GetActivities(toProcess)) 55 { 56 if (!uninstrumentedSubRoots.ContainsKey(activity)) 57 { 58 CollectSubRoot(activity); 59 activitiesRemaining.Enqueue(activity); 60 } 61 } 62 } 63 } 64 65 // Collect subroot as uninstrumented activity. CollectSubRoot(Activity activity)66 void CollectSubRoot(Activity activity) 67 { 68 string wfSymbol = DebugSymbol.GetSymbol(activity) as string; 69 if (!string.IsNullOrEmpty(wfSymbol)) 70 { 71 this.uninstrumentedSubRoots.Add(activity, wfSymbol); 72 } 73 else 74 { 75 string sourcePath = XamlDebuggerXmlReader.GetFileName(activity) as string; 76 if (!string.IsNullOrEmpty(sourcePath)) 77 { 78 this.uninstrumentedSubRoots.Add(activity, sourcePath); 79 } 80 } 81 } 82 83 // Whether this is unistrumented sub root. IsUninstrumentedSubRoot(Activity subRoot)84 public bool IsUninstrumentedSubRoot(Activity subRoot) 85 { 86 return this.UninstrumentedSubRoots.ContainsKey(subRoot); 87 } 88 89 90 // Returns Activities that have the same source as the given subRoot. 91 // This will return other instantiation of the same custom activity. 92 // Needed to avoid re-instrumentation of the same file. GetSameSourceSubRoots(Activity subRoot)93 public List<Activity> GetSameSourceSubRoots(Activity subRoot) 94 { 95 string sourcePath; 96 List<Activity> sameSourceSubRoots = new List<Activity>(); 97 if (this.UninstrumentedSubRoots.TryGetValue(subRoot, out sourcePath)) 98 { 99 foreach (KeyValuePair<Activity, string> entry in this.UninstrumentedSubRoots) 100 { 101 if (entry.Value == sourcePath && entry.Key != subRoot) 102 { 103 sameSourceSubRoots.Add(entry.Key); 104 } 105 } 106 } 107 return sameSourceSubRoots; 108 } 109 110 // Mark this sub root as instrumented. MarkInstrumented(Activity subRoot)111 public void MarkInstrumented(Activity subRoot) 112 { 113 this.UninstrumentedSubRoots.Remove(subRoot); 114 } 115 } 116 } 117