1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //-----------------------------------------------------------------------------
4 
5 namespace System.Activities.XamlIntegration
6 {
7     using System;
8     using System.Activities;
9     using System.Activities.Expressions;
10     using System.Collections.Generic;
11 
12     internal abstract class CompiledExpressionActivityVisitor
13     {
14         protected bool ForImplementation
15         {
16             get;
17             private set;
18         }
19 
Visit(Activity activity, bool forImplementation)20         public void Visit(Activity activity, bool forImplementation)
21         {
22             this.ForImplementation = forImplementation;
23             bool exit;
24 
25             VisitRoot(activity, out exit);
26         }
27 
VisitCore(Activity activity, out bool exit)28         void VisitCore(Activity activity, out bool exit)
29         {
30             if (activity is ITextExpression)
31             {
32                 VisitITextExpression(activity, out exit);
33                 return;
34             }
35             // Look for variable scopes
36             if (activity.RuntimeVariables != null && activity.RuntimeVariables.Count > 0)
37             {
38                 VisitVariableScope(activity, out exit);
39                 if (exit)
40                 {
41                     return;
42                 }
43             }
44             else
45             {
46                 Visit(activity, out exit);
47                 if (exit)
48                 {
49                     return;
50                 }
51             }
52 
53             return;
54         }
55 
Visit(Activity activity, out bool exit)56         protected virtual void Visit(Activity activity, out bool exit)
57         {
58             VisitArguments(activity, out exit);
59             if (exit)
60             {
61                 return;
62             }
63 
64             VisitPublicActivities(activity, out exit);
65             if (exit)
66             {
67                 return;
68             }
69         }
70 
VisitRoot(Activity activity, out bool exit)71         protected virtual void VisitRoot(Activity activity, out bool exit)
72         {
73             if (this.ForImplementation)
74             {
75                 VisitRootImplementation(activity, out exit);
76                 if (exit)
77                 {
78                     return;
79                 }
80 
81                 exit = false;
82             }
83             else
84             {
85                 VisitRootPublic(activity, out exit);
86                 if (exit)
87                 {
88                     return;
89                 }
90 
91                 exit = false;
92             }
93         }
94 
VisitRootImplementationArguments(Activity activity, out bool exit)95         protected virtual void VisitRootImplementationArguments(Activity activity, out bool exit)
96         {
97             VisitArguments(activity, out exit, VisitRootImplementationArgument);
98             if (exit)
99             {
100                 return;
101             }
102 
103             exit = false;
104         }
105 
VisitRootImplementationArgument(RuntimeArgument runtimeArgument, out bool exit)106         protected virtual void VisitRootImplementationArgument(RuntimeArgument runtimeArgument, out bool exit)
107         {
108             if (runtimeArgument.IsBound)
109             {
110                 Activity expression = runtimeArgument.BoundArgument.Expression;
111                 if (expression != null)
112                 {
113                     VisitCore(expression, out exit);
114                     if (exit)
115                     {
116                         return;
117                     }
118                 }
119             }
120             exit = false;
121         }
122 
VisitVariableScope(Activity activity, out bool exit)123         protected virtual void VisitVariableScope(Activity activity, out bool exit)
124         {
125             //
126             // Walk the contained variables' default expressions
127             foreach (Variable v in activity.RuntimeVariables)
128             {
129                 if (v.Default != null)
130                 {
131                     VisitCore(v.Default, out exit);
132                     if (exit)
133                     {
134                         return;
135                     }
136                 }
137             }
138 
139             VisitVariableScopeArguments(activity, out exit);
140             if (exit)
141             {
142                 return;
143             }
144 
145             VisitPublicActivities(activity, out exit);
146             if (exit)
147             {
148                 return;
149             }
150 
151             exit = false;
152         }
153 
VisitRootImplementationScope(Activity activity, out bool exit)154         protected virtual void VisitRootImplementationScope(Activity activity, out bool exit)
155         {
156             foreach (Variable v in activity.RuntimeVariables)
157             {
158                 if (v.Default != null)
159                 {
160                     VisitCore(v.Default, out exit);
161                     if (exit)
162                     {
163                         return;
164                     }
165                 }
166             }
167 
168             VisitImportedChildren(activity, out exit);
169             if (exit)
170             {
171                 return;
172             }
173 
174             VisitImportedDelegates(activity, out exit);
175             if (exit)
176             {
177                 return;
178             }
179         }
180 
VisitITextExpression(Activity activity, out bool exit)181         protected virtual void VisitITextExpression(Activity activity, out bool exit)
182         {
183             exit = false;
184         }
185 
VisitChildren(Activity activity, out bool exit)186         protected virtual void VisitChildren(Activity activity, out bool exit)
187         {
188             if (activity.Children != null)
189             {
190                 for (int i = 0; i < activity.Children.Count; i++)
191                 {
192                     if (activity == activity.Children[i].Parent)
193                     {
194                         VisitCore(activity.Children[i], out exit);
195                         if (exit)
196                         {
197                             return;
198                         }
199                     }
200                 }
201             }
202             exit = false;
203         }
204 
VisitImportedChildren(Activity activity, out bool exit)205         protected virtual void VisitImportedChildren(Activity activity, out bool exit)
206         {
207             if (activity.ImportedChildren != null)
208             {
209                 for (int i = 0; i < activity.ImportedChildren.Count; i++)
210                 {
211                     VisitCore(activity.ImportedChildren[i], out exit);
212                     if (exit)
213                     {
214                         return;
215                     }
216                 }
217             }
218             exit = false;
219         }
220 
VisitDelegates(Activity activity, out bool exit)221         protected virtual void VisitDelegates(Activity activity, out bool exit)
222         {
223             if (activity.Delegates != null)
224             {
225                 foreach (ActivityDelegate activityDelegate in activity.Delegates)
226                 {
227                     if (activity == activityDelegate.Owner)
228                     {
229                         VisitDelegate(activityDelegate, out exit);
230 
231                         if (exit)
232                         {
233                             return;
234                         }
235                     }
236                 }
237             }
238             exit = false;
239         }
240 
VisitImportedDelegates(Activity activity, out bool exit)241         protected virtual void VisitImportedDelegates(Activity activity, out bool exit)
242         {
243             if (activity.ImportedDelegates != null)
244             {
245                 foreach (ActivityDelegate activityDelegate in activity.ImportedDelegates)
246                 {
247                     VisitDelegate(activityDelegate, out exit);
248 
249                     if (exit)
250                     {
251                         return;
252                     }
253                 }
254             }
255             exit = false;
256         }
257 
VisitDelegate(ActivityDelegate activityDelegate, out bool exit)258         protected virtual void VisitDelegate(ActivityDelegate activityDelegate, out bool exit)
259         {
260             VisitDelegateArguments(activityDelegate, out exit);
261             if (exit)
262             {
263                 return;
264             }
265 
266             if (activityDelegate.Handler != null)
267             {
268                 VisitCore(activityDelegate.Handler, out exit);
269                 if (exit)
270                 {
271                     return;
272                 }
273             }
274         }
275 
VisitDelegateArguments(ActivityDelegate activityDelegate, out bool exit)276         protected virtual void VisitDelegateArguments(ActivityDelegate activityDelegate, out bool exit)
277         {
278             foreach (RuntimeDelegateArgument delegateArgument in activityDelegate.RuntimeDelegateArguments)
279             {
280                 if (delegateArgument.BoundArgument != null)
281                 {
282                     VisitDelegateArgument(delegateArgument, out exit);
283 
284                     if (exit)
285                     {
286                         return;
287                     }
288                 }
289             }
290 
291             exit = false;
292         }
293 
VisitDelegateArgument(RuntimeDelegateArgument delegateArgument, out bool exit)294         protected virtual void VisitDelegateArgument(RuntimeDelegateArgument delegateArgument, out bool exit)
295         {
296             //
297             // Nothing further to walk into here, this is just a stub for implementors to override
298             exit = false;
299         }
300 
VisitVariableScopeArguments(Activity activity, out bool exit)301         protected virtual void VisitVariableScopeArguments(Activity activity, out bool exit)
302         {
303             VisitArguments(activity, out exit, VisitVariableScopeArgument);
304             if (exit)
305             {
306                 return;
307             }
308 
309             exit = false;
310         }
311 
VisitVariableScopeArgument(RuntimeArgument runtimeArgument, out bool exit)312         protected virtual void VisitVariableScopeArgument(RuntimeArgument runtimeArgument, out bool exit)
313         {
314             VisitArgument(runtimeArgument, out exit);
315             if (exit)
316             {
317                 return;
318             }
319 
320             exit = false;
321         }
322 
VisitArguments(Activity activity, out bool exit)323         protected virtual void VisitArguments(Activity activity, out bool exit)
324         {
325             VisitArguments(activity, out exit, VisitArgument);
326             if (exit)
327             {
328                 return;
329             }
330 
331             exit = false;
332         }
333 
VisitArgument(RuntimeArgument runtimeArgument, out bool exit)334         protected virtual void VisitArgument(RuntimeArgument runtimeArgument, out bool exit)
335         {
336             if (runtimeArgument.IsBound)
337             {
338                 Activity expression = runtimeArgument.BoundArgument.Expression;
339                 if (expression != null)
340                 {
341                     VisitCore(expression, out exit);
342                     if (exit)
343                     {
344                         return;
345                     }
346                 }
347             }
348             exit = false;
349         }
350 
VisitRootPublic(Activity activity, out bool exit)351         void VisitRootPublic(Activity activity, out bool exit)
352         {
353             if (activity.RuntimeVariables != null && activity.RuntimeVariables.Count > 0)
354             {
355                 VisitVariableScope(activity, out exit);
356                 if (exit)
357                 {
358                     return;
359                 }
360             }
361             else
362             {
363                 VisitArguments(activity, out exit);
364                 if (exit)
365                 {
366                     return;
367                 }
368 
369                 VisitPublicActivities(activity, out exit);
370                 if (exit)
371                 {
372                     return;
373                 }
374             }
375         }
376 
VisitRootImplementation(Activity activity, out bool exit)377         void VisitRootImplementation(Activity activity, out bool exit)
378         {
379             VisitRootImplementationArguments(activity, out exit);
380             if (exit)
381             {
382                 return;
383             }
384 
385             VisitRootImplementationScope(activity, out exit);
386 
387             if (activity.ImplementationChildren != null)
388             {
389                 for (int i = 0; i < activity.ImplementationChildren.Count; i++)
390                 {
391                     VisitCore(activity.ImplementationChildren[i], out exit);
392                     if (exit)
393                     {
394                         return;
395                     }
396                 }
397             }
398             exit = false;
399         }
400 
VisitPublicActivities(Activity activity, out bool exit)401         void VisitPublicActivities(Activity activity, out bool exit)
402         {
403             VisitChildren(activity, out exit);
404             if (exit)
405             {
406                 return;
407             }
408 
409             VisitDelegates(activity, out exit);
410             if (exit)
411             {
412                 return;
413             }
414 
415             VisitImportedChildren(activity, out exit);
416             if (exit)
417             {
418                 return;
419             }
420 
421             VisitImportedDelegates(activity, out exit);
422             if (exit)
423             {
424                 return;
425             }
426         }
427 
VisitArguments(Activity activity, out bool exit, VisitArgumentDelegate visitArgument)428         void VisitArguments(Activity activity, out bool exit, VisitArgumentDelegate visitArgument)
429         {
430             foreach (RuntimeArgument runtimeArgument in activity.RuntimeArguments)
431             {
432                 visitArgument(runtimeArgument, out exit);
433                 if (exit)
434                 {
435                     return;
436                 }
437             }
438             exit = false;
439         }
440 
VisitArgumentDelegate(RuntimeArgument runtimeArgument, out bool exit)441         delegate void VisitArgumentDelegate(RuntimeArgument runtimeArgument, out bool exit);
442     }
443 }
444