Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
[assembly: System.CLSCompliant(true)]
[assembly: System.Reflection.AssemblyTitle("System.ComponentModel.Composition")]
[assembly: System.Reflection.AssemblyCopyright("(c) Microsoft Corporation. All rights reserved.")]
[assembly: System.Reflection.AssemblyVersion(Consts.FxVersion)]
[assembly: System.Reflection.AssemblyKeyFile ("../ecma.pub")]
[assembly: System.Reflection.AssemblyDelaySign (true)]
//[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("System.ComponentModel.Composition.UnitTests")]
//[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("System.ComponentModel.Composition.UnitTestFramework")]

View File

@@ -0,0 +1,32 @@
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.Serialization;
namespace Microsoft.Internal
{
partial class Assumes
{
// The exception that is thrown when an internal assumption failed.
[Serializable]
[SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
private class InternalErrorException : Exception
{
public InternalErrorException(string message)
: base(string.Format(CultureInfo.CurrentCulture, Strings.InternalExceptionMessage, message))
{
}
#if !SILVERLIGHT
[System.Security.SecuritySafeCritical]
protected InternalErrorException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
#endif
}
}
}

View File

@@ -0,0 +1,102 @@
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.Serialization;
namespace Microsoft.Internal
{
internal static partial class Assumes
{
[DebuggerStepThrough]
internal static void NotNull<T>(T value)
where T : class
{
IsTrue(value != null);
}
[DebuggerStepThrough]
internal static void NotNull<T1, T2>(T1 value1, T2 value2)
where T1 : class
where T2 : class
{
NotNull(value1);
NotNull(value2);
}
[DebuggerStepThrough]
internal static void NotNull<T1, T2, T3>(T1 value1, T2 value2, T3 value3)
where T1 : class
where T2 : class
where T3 : class
{
NotNull(value1);
NotNull(value2);
NotNull(value3);
}
[DebuggerStepThrough]
internal static void NotNullOrEmpty<T>(T[] values)
{
Assumes.NotNull(values);
Assumes.IsTrue(values.Length > 0);
}
[DebuggerStepThrough]
internal static void NotNullOrEmpty(string value)
{
NotNull(value);
IsTrue(value.Length > 0);
}
[DebuggerStepThrough]
internal static void Null<T>(T value)
where T : class
{
IsTrue(value == null);
}
[DebuggerStepThrough]
internal static void IsFalse(bool condition)
{
if (condition)
{
Fail(null);
}
}
[DebuggerStepThrough]
internal static void IsTrue(bool condition)
{
if (!condition)
{
Fail(null);
}
}
[DebuggerStepThrough]
internal static void IsTrue(bool condition, [Localizable(false)]string message)
{
if (!condition)
{
Fail(message);
}
}
[DebuggerStepThrough]
internal static void Fail([Localizable(false)]string message)
{
throw new InternalErrorException(message);
}
[DebuggerStepThrough]
internal static T NotReachable<T>()
{
throw new InternalErrorException("Code path should never be reached!");
}
}
}

View File

@@ -0,0 +1,43 @@
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Microsoft.Internal
{
internal static class AttributeServices
{
public static T[] GetAttributes<T>(this ICustomAttributeProvider attributeProvider) where T : class
{
return (T[])attributeProvider.GetCustomAttributes(typeof(T), false);
}
public static T[] GetAttributes<T>(this ICustomAttributeProvider attributeProvider, bool inherit) where T : class
{
return (T[])attributeProvider.GetCustomAttributes(typeof(T), inherit);
}
public static T GetFirstAttribute<T>(this ICustomAttributeProvider attributeProvider) where T : class
{
return GetAttributes<T>(attributeProvider).FirstOrDefault();
}
public static T GetFirstAttribute<T>(this ICustomAttributeProvider attributeProvider, bool inherit) where T : class
{
return GetAttributes<T>(attributeProvider, inherit).FirstOrDefault();
}
public static bool IsAttributeDefined<T>(this ICustomAttributeProvider attributeProvider) where T : class
{
return attributeProvider.IsDefined(typeof(T), false);
}
public static bool IsAttributeDefined<T>(this ICustomAttributeProvider attributeProvider, bool inherit) where T : class
{
return attributeProvider.IsDefined(typeof(T), inherit);
}
}
}

View File

@@ -0,0 +1,145 @@
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
namespace Microsoft.Internal.Collections
{
internal static partial class CollectionServices
{
public static ICollection<object> GetCollectionWrapper(Type itemType, object collectionObject)
{
Assumes.NotNull(itemType, collectionObject);
if (itemType == typeof(object))
{
return (ICollection<object>)collectionObject;
}
// Most common .Net collections implement IList as well so for those
// cases we can optimize the wrapping instead of using reflection to create
// a generic type.
if (typeof(IList).IsAssignableFrom(collectionObject.GetType()))
{
return new CollectionOfObjectList((IList)collectionObject);
}
Type collectionType = typeof(CollectionOfObject<>).MakeGenericType(itemType);
return (ICollection<object>)Activator.CreateInstance(collectionType, collectionObject);
}
private class CollectionOfObjectList : ICollection<object>
{
private readonly IList _list;
public CollectionOfObjectList(IList list)
{
this._list = list;
}
public void Add(object item)
{
this._list.Add(item);
}
public void Clear()
{
this._list.Clear();
}
public bool Contains(object item)
{
return Assumes.NotReachable<bool>();
}
public void CopyTo(object[] array, int arrayIndex)
{
Assumes.NotReachable<object>();
}
public int Count
{
get { return Assumes.NotReachable<int>(); }
}
public bool IsReadOnly
{
get { return this._list.IsReadOnly; }
}
public bool Remove(object item)
{
return Assumes.NotReachable<bool>();
}
public IEnumerator<object> GetEnumerator()
{
return Assumes.NotReachable<IEnumerator<object>>();
}
IEnumerator IEnumerable.GetEnumerator()
{
return Assumes.NotReachable<IEnumerator>();
}
}
private class CollectionOfObject<T> : ICollection<object>
{
private readonly ICollection<T> _collectionOfT;
public CollectionOfObject(object collectionOfT)
{
this._collectionOfT = (ICollection<T>)collectionOfT;
}
public void Add(object item)
{
this._collectionOfT.Add((T) item);
}
public void Clear()
{
this._collectionOfT.Clear();
}
public bool Contains(object item)
{
return Assumes.NotReachable<bool>();
}
public void CopyTo(object[] array, int arrayIndex)
{
Assumes.NotReachable<object>();
}
public int Count
{
get { return Assumes.NotReachable<int>(); }
}
public bool IsReadOnly
{
get { return this._collectionOfT.IsReadOnly; }
}
public bool Remove(object item)
{
return Assumes.NotReachable<bool>();
}
public IEnumerator<object> GetEnumerator()
{
return Assumes.NotReachable<IEnumerator<object>>();
}
IEnumerator IEnumerable.GetEnumerator()
{
return Assumes.NotReachable<IEnumerator>();
}
}
}
}

View File

@@ -0,0 +1,181 @@
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
namespace Microsoft.Internal.Collections
{
internal static partial class CollectionServices
{
private static readonly Type StringType = typeof(string);
private static readonly Type IEnumerableType = typeof(IEnumerable);
private static readonly Type IEnumerableOfTType = typeof(IEnumerable<>);
private static readonly Type ICollectionOfTType = typeof(ICollection<>);
public static bool IsEnumerableOfT(Type type)
{
if (type.IsGenericType)
{
Type genericType = type.GetGenericTypeDefinition();
if (genericType == IEnumerableOfTType)
{
return true;
}
}
return false;
}
public static Type GetEnumerableElementType(Type type)
{
if (type == StringType || !IEnumerableType.IsAssignableFrom(type))
{
return null;
}
Type closedType;
if (ReflectionServices.TryGetGenericInterfaceType(type, IEnumerableOfTType, out closedType))
{
return closedType.GetGenericArguments()[0];
}
return null;
}
public static Type GetCollectionElementType(Type type)
{
Type closedType;
if (ReflectionServices.TryGetGenericInterfaceType(type, ICollectionOfTType, out closedType))
{
return closedType.GetGenericArguments()[0];
}
return null;
}
public static ReadOnlyCollection<T> ToReadOnlyCollection<T>(this IEnumerable<T> source)
{
Assumes.NotNull(source);
return new ReadOnlyCollection<T>(source.AsArray());
}
public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T> source) where T : class
{
Assumes.NotNull(source);
return source.Where(NotNull); // Use non-generic NotNull for performance reasons
}
private static bool NotNull(object element)
{
return element != null;
}
public static IEnumerable<T> ConcatAllowingNull<T>(this IEnumerable<T> source, IEnumerable<T> second)
{
if (second == null || !second.FastAny())
{
return source;
}
if (source == null || !source.FastAny())
{
return second;
}
return source.Concat(second);
}
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach(T t in source)
{
action.Invoke(t);
}
}
public static EnumerableCardinality GetCardinality<T>(this IEnumerable<T> source)
{
Assumes.NotNull(source);
// Cast to ICollection instead of ICollection<T> for performance reasons.
ICollection collection = source as ICollection;
if (collection != null)
{
switch (collection.Count)
{
case 0:
return EnumerableCardinality.Zero;
case 1:
return EnumerableCardinality.One;
default:
return EnumerableCardinality.TwoOrMore;
}
}
using (var enumerator = source.GetEnumerator())
{
if (!enumerator.MoveNext())
{
return EnumerableCardinality.Zero;
}
if (!enumerator.MoveNext())
{
return EnumerableCardinality.One;
}
return EnumerableCardinality.TwoOrMore;
}
}
public static bool FastAny<T>(this IEnumerable<T> source)
{
// Enumerable.Any<T> underneath doesn't cast to ICollection,
// like it does with many of the other LINQ methods.
// Below is significantly (4x) when mainly working with ICollection
// sources and a little slower if working with mainly IEnumerable<T>
// sources.
// Cast to ICollection instead of ICollection<T> for performance reasons.
ICollection collection = source as ICollection;
if (collection != null)
{
return collection.Count > 0;
}
return source.Any();
}
public static Stack<T> Copy<T>(this Stack<T> stack)
{
Assumes.NotNull(stack);
// Stack<T>.GetEnumerator walks from top to bottom
// of the stack, whereas Stack<T>(IEnumerable<T>)
// pushes to bottom from top, so we need to reverse
// the stack to get them in the right order.
return new Stack<T>(stack.Reverse());
}
public static T[] AsArray<T>(this IEnumerable<T> enumerable)
{
T[] array = enumerable as T[];
if (array != null)
{
return array;
}
return enumerable.ToArray();
}
}
}

View File

@@ -0,0 +1,116 @@
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------
#if !CLR40
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Internal;
using Microsoft.Internal.Collections;
namespace Microsoft.Internal.Collections
{
// This is a broken implementation of ConditionalWeakTable that allows us
// to compile and work on versions of .Net eariler then 4.0. This class is
// broken when there are circular dependencies between keys and values, which
// can only be fixed by using some specific CLR 4.0 features.
// For code samples of the broken behavior see ConditionalWeakTableTests.cs.
internal class ConditionalWeakTable<TKey, TValue>
where TKey : class
where TValue : class
{
private readonly Dictionary<object, TValue> _table;
private int _capacity = 4;
public ConditionalWeakTable()
{
this._table = new Dictionary<object, TValue>();
}
public void Add(TKey key, TValue value)
{
CleanupDeadReferences();
this._table.Add(CreateWeakKey(key), value);
}
public bool Remove(TKey key)
{
return this._table.Remove(key);
}
public bool TryGetValue(TKey key, out TValue value)
{
return this._table.TryGetValue(key, out value);
}
private void CleanupDeadReferences()
{
if (this._table.Count < _capacity)
{
return;
}
object[] deadKeys = this._table.Keys
.Where(weakRef => !((EquivalentWeakReference)weakRef).IsAlive).ToArray();
foreach (var deadKey in deadKeys)
{
this._table.Remove(deadKey);
}
if (this._table.Count >= _capacity)
{
_capacity *= 2;
}
}
private static object CreateWeakKey(TKey key)
{
return new EquivalentWeakReference(key);
}
private class EquivalentWeakReference
{
private readonly WeakReference _weakReference;
private readonly int _hashCode;
public EquivalentWeakReference(object obj)
{
this._hashCode = obj.GetHashCode();
this._weakReference = new WeakReference(obj);
}
public bool IsAlive
{
get
{
return this._weakReference.IsAlive;
}
}
public override bool Equals(object obj)
{
EquivalentWeakReference weakRef = obj as EquivalentWeakReference;
if (weakRef != null)
{
obj = weakRef._weakReference.Target;
}
if (obj == null)
{
return base.Equals(weakRef);
}
return object.Equals(this._weakReference.Target, obj);
}
public override int GetHashCode()
{
return this._hashCode;
}
}
}
}
#endif

View File

@@ -0,0 +1,14 @@
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------
using System;
namespace Microsoft.Internal.Collections
{
internal enum EnumerableCardinality : int
{
Zero = 0,
One = 1,
TwoOrMore = 2,
}
}

View File

@@ -0,0 +1,103 @@
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
namespace Microsoft.Internal.Collections
{
[DebuggerDisplay("Count = {Count}")]
[DebuggerTypeProxy(typeof(ReadOnlyDictionaryDebuggerProxy<,>))]
internal sealed partial class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
private readonly IDictionary<TKey, TValue> _innerDictionary;
public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
{
this._innerDictionary = dictionary ?? new Dictionary<TKey, TValue>(0);
}
public int Count
{
get { return this._innerDictionary.Count; }
}
public bool IsReadOnly
{
get { return true; }
}
public ICollection<TKey> Keys
{
get { return this._innerDictionary.Keys; }
}
public TValue this[TKey key]
{
get { return this._innerDictionary[key]; }
set { throw new NotSupportedException(Strings.NotSupportedReadOnlyDictionary); }
}
public ICollection<TValue> Values
{
get { return this._innerDictionary.Values; }
}
public bool Contains(KeyValuePair<TKey, TValue> item)
{
return this._innerDictionary.Contains(item);
}
public bool ContainsKey(TKey key)
{
return this._innerDictionary.ContainsKey(key);
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
this._innerDictionary.CopyTo(array, arrayIndex);
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return this._innerDictionary.GetEnumerator();
}
public bool TryGetValue(TKey key, out TValue value)
{
return this._innerDictionary.TryGetValue(key, out value);
}
IEnumerator IEnumerable.GetEnumerator()
{
return this._innerDictionary.GetEnumerator();
}
void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
{
throw new NotSupportedException(Strings.NotSupportedReadOnlyDictionary);
}
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
{
throw new NotSupportedException(Strings.NotSupportedReadOnlyDictionary);
}
void ICollection<KeyValuePair<TKey, TValue>>.Clear()
{
throw new NotSupportedException(Strings.NotSupportedReadOnlyDictionary);
}
bool IDictionary<TKey, TValue>.Remove(TKey key)
{
throw new NotSupportedException(Strings.NotSupportedReadOnlyDictionary);
}
bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
{
throw new NotSupportedException(Strings.NotSupportedReadOnlyDictionary);
}
}
}

View File

@@ -0,0 +1,32 @@
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace Microsoft.Internal.Collections
{
// NOTE: This type cannot be a nested proxy of ReadOnlyDictionary due to a bug
// in the Visual Studio Debugger which causes it to ignore nested generic proxies.
internal class ReadOnlyDictionaryDebuggerProxy<TKey, TValue>
{
private readonly ReadOnlyDictionary<TKey, TValue> _dictionary;
public ReadOnlyDictionaryDebuggerProxy(ReadOnlyDictionary<TKey, TValue> dictionary)
{
Requires.NotNull(dictionary, "dictionary");
_dictionary = dictionary;
}
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public KeyValuePair<TKey, TValue>[] Items
{
// NOTE: This shouldn't be cached, so that on every query of
// the current value of the underlying dictionary is respected.
get { return this._dictionary.ToArray(); }
}
}
}

View File

@@ -0,0 +1,92 @@
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Internal;
using Microsoft.Internal.Collections;
namespace Microsoft.Internal.Collections
{
internal class WeakReferenceCollection<T> where T : class
{
private readonly List<WeakReference> _items = new List<WeakReference>();
public void Add(T item)
{
// Only cleanup right before we need to reallocate space.
if (this._items.Capacity == this._items.Count)
{
this.CleanupDeadReferences();
}
this._items.Add(new WeakReference(item));
}
public void Remove(T item)
{
int index = IndexOf(item);
if (index != -1)
{
this._items.RemoveAt(index);
}
}
public bool Contains(T item)
{
return IndexOf(item) >= 0;
}
public void Clear()
{
this._items.Clear();
}
// Should be executed under at least a read lock.
private int IndexOf(T item)
{
int count = this._items.Count;
for (int i = 0; i < count; i++)
{
if (this._items[i].Target == item)
{
return i;
}
}
return -1;
}
// Should be executed under a write lock
private void CleanupDeadReferences()
{
int count = this._items.Count;
for (int i = count - 1; i >= 0; i--)
{
if (this._items[i].Target == null)
{
this._items.RemoveAt(i);
}
}
}
public List<T> AliveItemsToList()
{
List<T> aliveItems = new List<T>();
foreach (var weakItem in this._items)
{
T item = weakItem.Target as T;
if (item != null)
{
aliveItems.Add(item);
}
}
return aliveItems;
}
}
}

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Text;
using System.Threading;
using System.ComponentModel.Composition.Primitives;
namespace Microsoft.Internal
{
internal class ContractServices
{
public static T Cast<T>(object o)
{
return (T)o;
}
public static bool TryCast(Type contractType, object value, out object result)
{
if (value == null)
{
result = null;
return true;
}
if (contractType.IsInstanceOfType(value))
{
result = value;
return true;
}
// We couldn't cast see if a delegate works for us.
if (typeof(Delegate).IsAssignableFrom(contractType))
{
ExportedDelegate exportedDelegate = value as ExportedDelegate;
if (exportedDelegate != null)
{
result = exportedDelegate.CreateDelegate(contractType);
return (result != null);
}
}
result = null;
return false;
}
}
}

View File

@@ -0,0 +1,333 @@
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
namespace Microsoft.Internal
{
internal static class GenerationServices
{
// Type.GetTypeFromHandle
private static readonly MethodInfo _typeGetTypeFromHandleMethod = typeof(Type).GetMethod("GetTypeFromHandle");
// typeofs are pretty expensive, so we cache them statically
private static readonly Type TypeType = typeof(System.Type);
private static readonly Type StringType = typeof(System.String);
private static readonly Type CharType = typeof(System.Char);
private static readonly Type BooleanType = typeof(System.Boolean);
private static readonly Type ByteType = typeof(System.Byte);
private static readonly Type SByteType = typeof(System.SByte);
private static readonly Type Int16Type = typeof(System.Int16);
private static readonly Type UInt16Type = typeof(System.UInt16);
private static readonly Type Int32Type = typeof(System.Int32);
private static readonly Type UInt32Type = typeof(System.UInt32);
private static readonly Type Int64Type = typeof(System.Int64);
private static readonly Type UInt64Type = typeof(System.UInt64);
private static readonly Type DoubleType = typeof(System.Double);
private static readonly Type SingleType = typeof(System.Single);
private static readonly Type IEnumerableTypeofT = typeof(System.Collections.Generic.IEnumerable<>);
private static readonly Type IEnumerableType = typeof(System.Collections.IEnumerable);
private static readonly MethodInfo ExceptionGetData = typeof(Exception).GetProperty("Data").GetGetMethod();
private static readonly MethodInfo DictionaryAdd = typeof(IDictionary).GetMethod("Add");
private static readonly ConstructorInfo ObjectCtor = typeof(object).GetConstructor(Type.EmptyTypes);
public static ILGenerator CreateGeneratorForPublicConstructor(this TypeBuilder typeBuilder, Type[] ctrArgumentTypes)
{
ConstructorBuilder ctorBuilder = typeBuilder.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
ctrArgumentTypes);
ILGenerator ctorIL = ctorBuilder.GetILGenerator();
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Call, ObjectCtor);
return ctorIL;
}
/// Generates the code that loads the supplied value on the stack
/// This is not as simple as it seems, as different instructions need to be generated depending
/// on its type.
/// We support:
/// 1. All primitive types
/// 2. Strings
/// 3. Enums
/// 4. typeofs
/// 5. nulls
/// 6. Enumerables
/// 7. Delegates on static functions or any of the above
/// Everything else cannot be represented as literals
/// <param name="ilGenerator"></param>
/// <param name="item"></param>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public static void LoadValue(this ILGenerator ilGenerator, object value)
{
Assumes.NotNull(ilGenerator);
//
// Get nulls out of the way - they are basically typeless, so we just load null
//
if (value == null)
{
ilGenerator.LoadNull();
return;
}
//
// Prepare for literal loading - decide whether we should box, and handle enums properly
//
Type valueType = value.GetType();
object rawValue = value;
if (valueType.IsEnum)
{
// enums are special - we need to load the underlying constant on the stack
rawValue = Convert.ChangeType(value, Enum.GetUnderlyingType(valueType), null);
valueType = rawValue.GetType();
}
//
// Generate IL depending on the valueType - this is messier than it should ever be, but sadly necessary
//
if (valueType == GenerationServices.StringType)
{
// we need to check for strings before enumerables, because strings are IEnumerable<char>
ilGenerator.LoadString((string)rawValue);
}
else if (GenerationServices.TypeType.IsAssignableFrom(valueType))
{
ilGenerator.LoadTypeOf((Type)rawValue);
}
else if (GenerationServices.IEnumerableType.IsAssignableFrom(valueType))
{
// NOTE : strings and dictionaries are also enumerables, but we have already handled those
ilGenerator.LoadEnumerable((IEnumerable) rawValue);
}
else if (
(valueType == GenerationServices.CharType) ||
(valueType == GenerationServices.BooleanType) ||
(valueType == GenerationServices.ByteType) ||
(valueType == GenerationServices.SByteType) ||
(valueType == GenerationServices.Int16Type) ||
(valueType == GenerationServices.UInt16Type) ||
(valueType == GenerationServices.Int32Type)
)
{
// NOTE : Everything that is 32 bit or less uses ldc.i4. We need to pass int32, even if the actual types is shorter - this is IL memory model
// direct casting to (int) won't work, because the value is boxed, thus we need to use Convert.
// Sadly, this will not work for all cases - namely large uint32 - because they can't semantically fit into 32 signed bits
// We have a special case for that next
ilGenerator.LoadInt((int)Convert.ChangeType(rawValue, typeof(int), CultureInfo.InvariantCulture));
}
else if (valueType == GenerationServices.UInt32Type)
{
// NOTE : This one is a bit tricky. Ldc.I4 takes an Int32 as an argument, although it really treats it as a 32bit number
// That said, some UInt32 values are larger that Int32.MaxValue, so the Convert call above will fail, which is why
// we need to treat this case individually and cast to uint, and then - unchecked - to int.
ilGenerator.LoadInt(unchecked((int)((uint)rawValue)));
}
else if (valueType == GenerationServices.Int64Type)
{
ilGenerator.LoadLong((long)rawValue);
}
else if (valueType == GenerationServices.UInt64Type)
{
// NOTE : This one is a bit tricky. Ldc.I8 takes an Int64 as an argument, although it really treats it as a 64bit number
// That said, some UInt64 values are larger that Int64.MaxValue, so the direct case we use above (or Convert, for that matter)will fail, which is why
// we need to treat this case individually and cast to ulong, and then - unchecked - to long.
ilGenerator.LoadLong(unchecked((long)((ulong)rawValue)));
}
else if (valueType == GenerationServices.SingleType)
{
ilGenerator.LoadFloat((float)rawValue);
}
else if (valueType == GenerationServices.DoubleType)
{
ilGenerator.LoadDouble((double)rawValue);
}
else
{
throw new InvalidOperationException(
string.Format(CultureInfo.CurrentCulture, Strings.InvalidMetadataValue, value.GetType().FullName));
}
}
/// Generates the code that adds an object to a dictionary stored in a local variable
/// <param name="ilGenerator"></param>
/// <param name="dictionary"></param>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public static void AddItemToLocalDictionary(this ILGenerator ilGenerator, LocalBuilder dictionary, object key, object value)
{
Assumes.NotNull(ilGenerator);
Assumes.NotNull(dictionary);
Assumes.NotNull(key);
Assumes.NotNull(value);
ilGenerator.Emit(OpCodes.Ldloc, dictionary);
ilGenerator.LoadValue(key);
ilGenerator.LoadValue(value);
ilGenerator.Emit(OpCodes.Callvirt, DictionaryAdd);
}
/// Generates the code that adds an object from a local variable to a dictionary also stored in a local
/// <param name="ilGenerator"></param>
/// <param name="dictionary"></param>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public static void AddLocalToLocalDictionary(this ILGenerator ilGenerator, LocalBuilder dictionary, object key, LocalBuilder value)
{
Assumes.NotNull(ilGenerator);
Assumes.NotNull(dictionary);
Assumes.NotNull(key);
Assumes.NotNull(value);
ilGenerator.Emit(OpCodes.Ldloc, dictionary);
ilGenerator.LoadValue(key);
ilGenerator.Emit(OpCodes.Ldloc, value);
ilGenerator.Emit(OpCodes.Callvirt, DictionaryAdd);
}
/// Generates the code to get the type of an object and store it in a local
/// <param name="ilGenerator"></param>
/// <param name="dictionary"></param>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public static void GetExceptionDataAndStoreInLocal(this ILGenerator ilGenerator, LocalBuilder exception, LocalBuilder dataStore)
{
Assumes.NotNull(ilGenerator);
Assumes.NotNull(exception);
Assumes.NotNull(dataStore);
ilGenerator.Emit(OpCodes.Ldloc, exception);
ilGenerator.Emit(OpCodes.Callvirt, ExceptionGetData);
ilGenerator.Emit(OpCodes.Stloc, dataStore);
}
private static void LoadEnumerable(this ILGenerator ilGenerator, IEnumerable enumerable)
{
Assumes.NotNull(ilGenerator);
Assumes.NotNull(enumerable);
// We load enumerable as an array - this is the most compact and efficient way of representing it
Type elementType = null;
Type closedType = null;
if (ReflectionServices.TryGetGenericInterfaceType(enumerable.GetType(), GenerationServices.IEnumerableTypeofT, out closedType))
{
elementType = closedType.GetGenericArguments()[0];
}
else
{
elementType = typeof(object);
}
//
// elem[] array = new elem[<enumerable.Count()>]
//
Type generatedArrayType = elementType.MakeArrayType();
LocalBuilder generatedArrayLocal = ilGenerator.DeclareLocal(generatedArrayType);
ilGenerator.LoadInt(enumerable.Cast<object>().Count());
ilGenerator.Emit(OpCodes.Newarr, elementType);
ilGenerator.Emit(OpCodes.Stloc, generatedArrayLocal);
int index = 0;
foreach (object value in enumerable)
{
//
//array[<index>] = value;
//
ilGenerator.Emit(OpCodes.Ldloc, generatedArrayLocal);
ilGenerator.LoadInt(index);
ilGenerator.LoadValue(value);
if (GenerationServices.IsBoxingRequiredForValue(value) && !elementType.IsValueType)
{
ilGenerator.Emit(OpCodes.Box, value.GetType());
}
ilGenerator.Emit(OpCodes.Stelem, elementType);
index++;
}
ilGenerator.Emit(OpCodes.Ldloc, generatedArrayLocal);
}
private static bool IsBoxingRequiredForValue(object value)
{
if (value == null)
{
return false;
}
else
{
return value.GetType().IsValueType;
}
}
private static void LoadNull(this ILGenerator ilGenerator)
{
ilGenerator.Emit(OpCodes.Ldnull);
}
private static void LoadString(this ILGenerator ilGenerator, string s)
{
Assumes.NotNull(ilGenerator);
if (s == null)
{
ilGenerator.LoadNull();
}
else
{
ilGenerator.Emit(OpCodes.Ldstr, s);
}
}
private static void LoadInt(this ILGenerator ilGenerator, int value)
{
Assumes.NotNull(ilGenerator);
ilGenerator.Emit(OpCodes.Ldc_I4, value);
}
private static void LoadLong(this ILGenerator ilGenerator, long value)
{
Assumes.NotNull(ilGenerator);
ilGenerator.Emit(OpCodes.Ldc_I8, value);
}
private static void LoadFloat(this ILGenerator ilGenerator, float value)
{
Assumes.NotNull(ilGenerator);
ilGenerator.Emit(OpCodes.Ldc_R4, value);
}
private static void LoadDouble(this ILGenerator ilGenerator, double value)
{
Assumes.NotNull(ilGenerator);
ilGenerator.Emit(OpCodes.Ldc_R8, value);
}
private static void LoadTypeOf(this ILGenerator ilGenerator, Type type)
{
Assumes.NotNull(ilGenerator);
//typeofs() translate into ldtoken and Type::GetTypeFromHandle call
ilGenerator.Emit(OpCodes.Ldtoken, type);
ilGenerator.EmitCall(OpCodes.Call, GenerationServices._typeGetTypeFromHandleMethod, null);
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Text;
using System.Globalization;
namespace Microsoft.Internal
{
internal static class LazyServices
{
public static Lazy<T> AsLazy<T>(this T t)
where T : class
{
return new Lazy<T>(() => t, false);
}
public static T GetNotNullValue<T>(this Lazy<T> lazy, string argument)
where T : class
{
Assumes.NotNull(lazy);
T value = lazy.Value;
if (value == null)
{
throw new InvalidOperationException(
string.Format(CultureInfo.CurrentCulture, Strings.LazyServices_LazyResolvesToNull, typeof(T), argument));
}
return value;
}
}
}

View File

@@ -0,0 +1,32 @@
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Microsoft.Internal
{
internal struct ReadLock : IDisposable
{
private readonly Lock _lock;
private int _isDisposed;
public ReadLock(Lock @lock)
{
this._isDisposed = 0;
this._lock = @lock;
this._lock.EnterReadLock();
}
public void Dispose()
{
if (Interlocked.CompareExchange(ref this._isDisposed, 1, 0) == 0)
{
this._lock.ExitReadLock();
}
}
}
}

View File

@@ -0,0 +1,32 @@
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Microsoft.Internal
{
internal struct WriteLock : IDisposable
{
private readonly Lock _lock;
private int _isDisposed;
public WriteLock(Lock @lock)
{
this._isDisposed = 0;
this._lock = @lock;
this._lock.EnterWriteLock();
}
public void Dispose()
{
if (Interlocked.CompareExchange(ref this._isDisposed, 1, 0) == 0)
{
this._lock.ExitWriteLock();
}
}
}
}

View File

@@ -0,0 +1,79 @@
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Microsoft.Internal
{
internal sealed class Lock : IDisposable
{
#if (!SILVERLIGHT)
private ReaderWriterLockSlim _thisLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
private int _isDisposed = 0;
public void EnterReadLock()
{
this._thisLock.EnterReadLock();
}
public void EnterWriteLock()
{
this._thisLock.EnterWriteLock();
}
public void ExitReadLock()
{
this._thisLock.ExitReadLock();
}
public void ExitWriteLock()
{
this._thisLock.ExitWriteLock();
}
public void Dispose()
{
if (Interlocked.CompareExchange(ref this._isDisposed, 1, 0) == 0)
{
this._thisLock.Dispose();
}
}
#else
// ReaderWriterLockSlim is not yet implemented on SilverLight
// Satisfies our requirements until it is implemented
object _thisLock = new object();
public Lock()
{
}
public void EnterReadLock()
{
Monitor.Enter(this._thisLock);
}
public void EnterWriteLock()
{
Monitor.Enter(this._thisLock);
}
public void ExitReadLock()
{
Monitor.Exit(this._thisLock);
}
public void ExitWriteLock()
{
Monitor.Exit(this._thisLock);
}
public void Dispose()
{
}
#endif
}
}

View File

@@ -0,0 +1,114 @@
#if !SILVERLIGHT && CLR40
using System;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
namespace Microsoft.Internal
{
internal static class ReflectionInvoke
{
private static readonly ReflectionPermission _memberAccess = new ReflectionPermission(ReflectionPermissionFlag.MemberAccess);
private static readonly ReflectionPermission _restrictedMemberAccess = new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess);
public static object SafeCreateInstance(this Type type, params object[] arguments)
{
DemandMemberAccessIfNeeded(type);
return Activator.CreateInstance(type, arguments);
}
public static object SafeInvoke(this ConstructorInfo constructor, params object[] arguments)
{
DemandMemberAccessIfNeeded(constructor);
return constructor.Invoke(arguments);
}
public static object SafeInvoke(this MethodInfo method, object instance, params object[] arguments)
{
DemandMemberAccessIfNeeded(method);
return method.Invoke(instance, arguments);
}
public static object SafeGetValue(this FieldInfo field, object instance)
{
DemandMemberAccessIfNeeded(field);
return field.GetValue(instance);
}
public static void SafeSetValue(this FieldInfo field, object instance, object value)
{
DemandMemberAccessIfNeeded(field);
field.SetValue(instance, value);
}
public static void DemandMemberAccessIfNeeded(MethodInfo method)
{
if (!method.IsVisible())
{
DemandMemberAccess(method);
}
}
private static void DemandMemberAccessIfNeeded(FieldInfo field)
{
if (!field.IsVisible())
{
DemandMemberAccess(field);
}
}
public static void DemandMemberAccessIfNeeded(Type type)
{
// Consult UnderlyingSystemType this is the type that Activator.CreateInstance creates
if (!type.UnderlyingSystemType.IsVisible)
{
DemandMemberAccess(type);
}
}
private static void DemandMemberAccessIfNeeded(ConstructorInfo constructor)
{
if (!constructor.IsVisible())
{
DemandMemberAccess(constructor);
}
}
private static void DemandMemberAccess(MemberInfo target)
{
try
{
_memberAccess.Demand();
}
catch (SecurityException)
{ // The caller doesn't have member access, but let's see whether they have access to
// members of assemblies with less or equal permissions (this mimics Reflection's behavior)
DemandRestrictedMemberAccess(target);
}
}
private static void DemandRestrictedMemberAccess(MemberInfo target)
{
Assembly targetAssembly = target.Assembly();
PermissionSet targetGrantSet = UnsafePermissionSet(targetAssembly);
targetGrantSet.AddPermission(_restrictedMemberAccess);
targetGrantSet.Demand();
}
[SecuritySafeCritical] // PermissionSet is [SecurityCritical]
private static PermissionSet UnsafePermissionSet(Assembly assembly)
{
return assembly.PermissionSet;
}
}
}
#endif

View File

@@ -0,0 +1,122 @@
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
namespace Microsoft.Internal
{
internal static class ReflectionServices
{
public static Assembly Assembly(this MemberInfo member)
{
Type type = member as Type;
if (type != null)
{
return type.Assembly;
}
return member.DeclaringType.Assembly;
}
public static bool IsVisible(this ConstructorInfo constructor)
{
return constructor.DeclaringType.IsVisible && constructor.IsPublic;
}
public static bool IsVisible(this FieldInfo field)
{
return field.DeclaringType.IsVisible && field.IsPublic;
}
public static bool IsVisible(this MethodInfo method)
{
if (!method.DeclaringType.IsVisible)
return false;
if (!method.IsPublic)
return false;
if (method.IsGenericMethod)
{
// Check type arguments, for example if we're passed 'Activator.CreateInstance<SomeMefInternalType>()'
foreach (Type typeArgument in method.GetGenericArguments())
{
if (!typeArgument.IsVisible)
return false;
}
}
return true;
}
public static string GetDisplayName(Type declaringType, string name)
{
Assumes.NotNull(declaringType);
return declaringType.GetDisplayName() + "." + name;
}
public static string GetDisplayName(this MemberInfo member)
{
Assumes.NotNull(member);
switch (member.MemberType)
{
case MemberTypes.TypeInfo:
case MemberTypes.NestedType:
return ((Type)member).FullName;
}
return GetDisplayName(member.DeclaringType, member.Name);
}
internal static bool TryGetGenericInterfaceType(Type instanceType, Type targetOpenInterfaceType, out Type targetClosedInterfaceType)
{
// The interface must be open
Assumes.IsTrue(targetOpenInterfaceType.IsInterface);
Assumes.IsTrue(targetOpenInterfaceType.IsGenericTypeDefinition);
Assumes.IsTrue(!instanceType.IsGenericTypeDefinition);
// if instanceType is an interface, we must first check it directly
if (instanceType.IsInterface &&
instanceType.IsGenericType &&
instanceType.GetGenericTypeDefinition() == targetOpenInterfaceType)
{
targetClosedInterfaceType = instanceType;
return true;
}
try
{
// Purposefully not using FullName here because it results in a significantly
// more expensive implementation of GetInterface, this does mean that we're
// takign the chance that there aren't too many types which implement multiple
// interfaces by the same name...
Type targetInterface = instanceType.GetInterface(targetOpenInterfaceType.Name, false);
if (targetInterface != null &&
targetInterface.GetGenericTypeDefinition() == targetOpenInterfaceType)
{
targetClosedInterfaceType = targetInterface;
return true;
}
}
catch (AmbiguousMatchException)
{
// If there are multiple with the same name we should not pick any
}
targetClosedInterfaceType = null;
return false;
}
internal static IEnumerable<PropertyInfo> GetAllProperties(this Type type)
{
return type.GetInterfaces().Concat(new Type[] { type }).SelectMany(itf => itf.GetProperties());
}
}
}

View File

@@ -0,0 +1,102 @@
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Globalization;
using System.Reflection;
using System.ComponentModel.Composition;
using System.Text;
namespace Microsoft.Internal
{
internal static class Requires
{
[DebuggerStepThrough]
public static void NotNull<T>(T value, string parameterName)
where T : class
{
if (value == null)
{
throw new ArgumentNullException(parameterName);
}
}
[DebuggerStepThrough]
public static void NotNullOrEmpty(string value, string parameterName)
{
NotNull(value, parameterName);
if (value.Length == 0)
{
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.ArgumentException_EmptyString, parameterName), parameterName);
}
}
[DebuggerStepThrough]
public static void NotNullOrNullElements<T>(IEnumerable<T> values, string parameterName)
where T : class
{
NotNull(values, parameterName);
NotNullElements(values, parameterName);
}
[DebuggerStepThrough]
public static void NullOrNotNullElements<TKey, TValue>(IEnumerable<KeyValuePair<TKey, TValue>> values, string parameterName)
where TKey : class
where TValue : class
{
if (values != null)
{
NotNullElements(values, parameterName);
}
}
[DebuggerStepThrough]
public static void NullOrNotNullElements<T>(IEnumerable<T> values, string parameterName)
where T : class
{
if (values != null)
{
NotNullElements(values, parameterName);
}
}
private static void NotNullElements<T>(IEnumerable<T> values, string parameterName)
where T : class
{
foreach (T value in values)
{
if (value == null)
{
throw ExceptionBuilder.CreateContainsNullElement(parameterName);
}
}
}
private static void NotNullElements<TKey, TValue>(IEnumerable<KeyValuePair<TKey, TValue>> values, string parameterName)
where TKey : class
where TValue : class
{
foreach (KeyValuePair<TKey, TValue> value in values)
{
if ((value.Key == null) || (value.Value == null))
{
throw ExceptionBuilder.CreateContainsNullElement(parameterName);
}
}
}
[DebuggerStepThrough]
public static void IsInMembertypeSet(MemberTypes value, string parameterName, MemberTypes enumFlagSet)
{
if ((value & enumFlagSet) != value || // Ensure the member is in the set
(value & (value - 1)) != 0) // Ensure that there is only one flag in the value (i.e. value is a power of 2).
{
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.ArgumentOutOfRange_InvalidEnumInSet, parameterName, value, enumFlagSet.ToString()), parameterName);
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More