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); }
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(); }
internal void RemoveExtension(ChainedExtension ext) { if (extensions == null) { return; } extensions = extensions.Where(e => e != ext).ToArray(); Rechain(); }
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); }
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); }
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)); }
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])); } }
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)); }
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); }
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)); }
internal void RemoveExtension(ChainedExtension ext) { extensions = extensions.Where(e => e != ext).ToArray(); Rechain(); }
internal protected override void InitializeChain(ChainedExtension next) { base.InitializeChain(next); this.next = FindNextImplementation <WorkspaceObjectExtension> (next); }
internal static ChainedExtension FindNextImplementation(Type type, ChainedExtension next, out int position) { position = -1; return(FindNextImplementation_Internal(type, next, ref position)); }
protected internal override void InitializeChain(ChainedExtension next) { InitializedCount++; base.InitializeChain(next); }
internal void AddExtension(ChainedExtension ext) { Array.Resize(ref extensions, extensions.Length + 1); extensions [extensions.Length - 1] = ext; Rechain(); }
public ChainedExtensionSentinel(ChainedExtension extension) { Extension = extension; }
internal void SetDefaultInsertionPosition(ChainedExtension insertBefore) { defaultInsertBefore = insertBefore; }