Update mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng/RelaxngPattern.cs
[mono.git] / mcs / class / Mono.CodeContracts / Mono.CodeContracts.Static.DataStructures / DecoratorHelper.cs
1 using System;
2 using System.Collections.Generic;
3
4 namespace Mono.CodeContracts.Static.DataStructures {
5         /// <summary>
6         /// This class is used with subroutines to substitute IStackInfo and IEdgeSubroutineAdapter to desired
7         /// </summary>
8         static class DecoratorHelper {
9                 private static readonly List<object> ContextAdapters = new List<object> ();
10
11                 private static object Last
12                 {
13                         get { return ContextAdapters [ContextAdapters.Count - 1]; }
14                 }
15
16                 public static void Push<T> (T @this) where T : class
17                 {
18                         ContextAdapters.Add (@this);
19                 }
20
21                 public static void Pop ()
22                 {
23                         ContextAdapters.RemoveAt (ContextAdapters.Count - 1);
24                 }
25
26                 public static T Dispatch<T> (T @this) where T : class
27                 {
28                         return FindAdaptorStartingAt (@this, 0);
29                 }
30
31                 private static T FindAdaptorStartingAt<T> (T @default, int startIndex)
32                         where T : class
33                 {
34                         List<object> list = ContextAdapters;
35                         for (int i = startIndex; i < list.Count; ++i) {
36                                 var obj = list [i] as T;
37                                 if (obj != null)
38                                         return obj;
39                         }
40                         return @default;
41                 }
42
43                 public static T Inner<T> (T @this) where T : class
44                 {
45                         for (int i = 0; i < ContextAdapters.Count; i++) {
46                                 if (ContextAdapters [i] == @this) {
47                                         ClearDuplicates (@this, i + 1);
48                                         T inner = FindAdaptorStartingAt (default(T), i + 1);
49                                         if (inner != null)
50                                                 return inner;
51
52                                         throw new InvalidOperationException ("No inner context found");
53                                 }
54                         }
55
56                         throw new InvalidOperationException ("@this is not current adaptor");
57                 }
58
59                 private static void ClearDuplicates (object @this, int @from)
60                 {
61                         for (int i = from; i < ContextAdapters.Count; i++) {
62                                 if (ContextAdapters [i] == @this)
63                                         ContextAdapters [i] = null;
64                         }
65                 }
66         }
67 }