Beispiel #1
0
        internal void InitChain(ExtensionChain chain, ChainedExtension next)
        {
            this.chain  = chain;
            nextInChain = next;

            InitializeChain(next);
        }
        internal static T CreateChain <T> (ChainedExtension next) where T : ChainedExtension, new()
        {
            var first = new T();

            first.nextInChain = ChainedExtension.FindNextImplementation <T> (next);
            return(first);
        }
Beispiel #3
0
        internal void AddExtension(ChainedExtension ext, ChainedExtension insertAfter = null, ChainedExtension insertBefore = null)
        {
            int index;

            if (insertBefore != null)
            {
                index = Array.IndexOf(extensions, insertBefore);
            }
            else if (insertAfter != null)
            {
                index = Array.IndexOf(extensions, insertAfter);
                if (index != -1)
                {
                    index++;
                }
            }
            else if (defaultInsertBefore != null)
            {
                index = Array.IndexOf(extensions, defaultInsertBefore);
            }
            else
            {
                index = extensions.Length;
            }

            Array.Resize(ref extensions, extensions.Length + 1);
            for (int n = extensions.Length - 1; n > index; n--)
            {
                extensions [n] = extensions [n - 1];
            }
            extensions [index] = ext;
            Rechain();
        }
Beispiel #4
0
        internal void RemoveExtension(ChainedExtension ext)
        {
            if (extensions == null)
            {
                return;
            }

            extensions = extensions.Where(e => e != ext).ToArray();
            Rechain();
        }
Beispiel #5
0
        public T GetExtension <T> () where T : ChainedExtension, new()
        {
            ChainedExtension e;

            if (!chains.TryGetValue(typeof(T), out e))
            {
                e = new T();
                e.InitChain(this, ChainedExtension.FindNextImplementation <T> (extensions[0]));
                chains [typeof(T)] = e;
            }
            return((T)e);
        }
Beispiel #6
0
            public void Update(ExtensionChain chain, Type type, int firstChainChangeIndex)
            {
                // We only want to update an extension if we insert somewhere before the extension we found.
                if (extensionIndex < firstChainChangeIndex)
                {
                    return;
                }

                // Maybe it would be useful to skip extensions until min(indices), as they've already been scanned
                // in a previous check
                var impl = ChainedExtension.FindNextImplementation(type, chain.extensions[0], out extensionIndex);

                Extension.InitChain(chain, impl);
            }
Beispiel #7
0
        internal static ChainedExtension FindNextImplementation(Type type, ChainedExtension next)
        {
            if (next == null)
            {
                return(null);
            }

            if (!type.IsInstanceOfType(next))
            {
                return(FindNextImplementation(type, next.nextInChain));
            }

            foreach (var m in type.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                MethodInfo method = m as MethodInfo;
                if (method == null)
                {
                    var prop = m as PropertyInfo;
                    if (prop != null)
                    {
                        method = prop.GetGetMethod();
                        if (method == null)
                        {
                            method = prop.GetSetMethod();
                        }
                    }
                }
                if (method != null && method.IsVirtual && method.Name != "InitializeChain")
                {
                    var tm = next.GetType().GetMethod(method.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, method.GetParameters().Select(p => p.ParameterType).ToArray(), null);
                    if (tm == null)
                    {
                        continue;
                    }
                    if (tm.DeclaringType != type)
                    {
                        return(next);
                    }
                }
            }

            // Serializable fields and properties
            if (next.GetType().GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Any(m => m.IsDefined(typeof(MonoDevelop.Core.Serialization.ItemPropertyAttribute))))
            {
                return(next);
            }

            return(FindNextImplementation(type, next.nextInChain));
        }
Beispiel #8
0
        void Rechain()
        {
            // Re-chain every extension
            for (int n = extensions.Length - 2; n >= 0; n--)
            {
                extensions [n].InitChain(this, extensions [n + 1]);
            }

            // The first extension object in type-specific chains is a placeholder extension used only to hold
            // a reference to the real first extension.
            foreach (var fex in chains)
            {
                fex.Value.InitChain(this, ChainedExtension.FindNextImplementation(fex.Key, extensions[0]));
            }
        }
Beispiel #9
0
        static ChainedExtension FindNextImplementation_Internal(Type type, ChainedExtension next, ref int position)
        {
            if (next == null)
            {
                return(null);
            }

            position++;
            if (!type.IsInstanceOfType(next))
            {
                return(FindNextImplementation_Internal(type, next.nextInChain, ref position));
            }

            // Maybe it would make sense to cache these, but not sure if we should.
            foreach (var method in type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                if (method != null && method.IsVirtual && method.Name != "InitializeChain")
                {
                    var paramArray     = method.GetParameters();
                    var paramTypeArray = new Type [paramArray.Length];
                    for (int i = 0; i < paramArray.Length; ++i)
                    {
                        paramTypeArray [i] = paramArray [i].ParameterType;
                    }

                    var tm = next.GetType().GetMethod(method.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, paramTypeArray, null);
                    if (tm == null)
                    {
                        continue;
                    }
                    if (tm.DeclaringType != type)
                    {
                        return(next);
                    }
                }
            }

            // Serializable fields and properties
            foreach (var m in next.GetType().GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                if (m.IsDefined(typeof(MonoDevelop.Core.Serialization.ItemPropertyAttribute)))
                {
                    return(next);
                }
            }

            return(FindNextImplementation_Internal(type, next.nextInChain, ref position));
        }
Beispiel #10
0
        internal void RemoveExtension(ChainedExtension ext)
        {
            if (extensions == null)
            {
                return;
            }

            int index = extensions.Length;

            extensions = extensions.Where((e, eindex) => {
                bool shouldRemove = e == ext;
                if (shouldRemove)
                {
                    index = eindex;
                }
                return(!shouldRemove);
            }).ToArray();

            Rechain(index);
        }
Beispiel #11
0
 internal protected override void InitializeChain(ChainedExtension next)
 {
     base.InitializeChain(next);
     this.next = FindNextImplementation <SolutionItemExtension> (next);
 }
 internal protected virtual void InitializeChain(ChainedExtension next)
 {
 }
 internal protected static T FindNextImplementation <T> (ChainedExtension next) where T : ChainedExtension
 {
     return((T)FindNextImplementation(typeof(T), next));
 }
Beispiel #14
0
 internal void RemoveExtension(ChainedExtension ext)
 {
     extensions = extensions.Where(e => e != ext).ToArray();
     Rechain();
 }
Beispiel #15
0
 internal protected override void InitializeChain(ChainedExtension next)
 {
     base.InitializeChain(next);
     this.next = FindNextImplementation <WorkspaceObjectExtension> (next);
 }
Beispiel #16
0
 internal static ChainedExtension FindNextImplementation(Type type, ChainedExtension next, out int position)
 {
     position = -1;
     return(FindNextImplementation_Internal(type, next, ref position));
 }
Beispiel #17
0
 protected internal override void InitializeChain(ChainedExtension next)
 {
     InitializedCount++;
     base.InitializeChain(next);
 }
Beispiel #18
0
 internal void AddExtension(ChainedExtension ext)
 {
     Array.Resize(ref extensions, extensions.Length + 1);
     extensions [extensions.Length - 1] = ext;
     Rechain();
 }
Beispiel #19
0
 public ChainedExtensionSentinel(ChainedExtension extension)
 {
     Extension = extension;
 }
Beispiel #20
0
 internal void SetDefaultInsertionPosition(ChainedExtension insertBefore)
 {
     defaultInsertBefore = insertBefore;
 }