You've already forked linux-packaging-mono
Imported Upstream version 5.4.0.167
Former-commit-id: 5624ac747d633e885131e8349322922b6a59baaa
This commit is contained in:
parent
e49d6f06c0
commit
536cd135cc
@@ -2,7 +2,8 @@
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\dir.props" />
|
||||
<PropertyGroup>
|
||||
<AssemblyVersion>4.2.0.0</AssemblyVersion>
|
||||
<AssemblyVersion>4.2.1.0</AssemblyVersion>
|
||||
<AssemblyKey>MSFT</AssemblyKey>
|
||||
<IsNETCoreApp>true</IsNETCoreApp>
|
||||
<IsUAP>true</IsUAP>
|
||||
</PropertyGroup>
|
||||
|
||||
8
external/corefx/src/System.Linq.Expressions/src/ILLinkTrim.xml
vendored
Normal file
8
external/corefx/src/System.Linq.Expressions/src/ILLinkTrim.xml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<linker>
|
||||
<assembly fullname="System.Linq.Expressions">
|
||||
<type fullname="System.Linq.Expressions.Interpreter.LightLambda">
|
||||
<!-- required by debugger -->
|
||||
<method name="get_DebugView" />
|
||||
</type>
|
||||
</assembly>
|
||||
</linker>
|
||||
@@ -307,9 +307,6 @@
|
||||
<data name="NotAMemberOfAnyType" xml:space="preserve">
|
||||
<value>'{0}' is not a member of any type</value>
|
||||
</data>
|
||||
<data name="ExpressionNotSupportedForType" xml:space="preserve">
|
||||
<value>The expression '{0}' is not supported for type '{1}'</value>
|
||||
</data>
|
||||
<data name="UnsupportedExpressionType" xml:space="preserve">
|
||||
<value>The expression type '{0}' is not supported</value>
|
||||
</data>
|
||||
@@ -355,12 +352,6 @@
|
||||
<data name="TypeNotIEnumerable" xml:space="preserve">
|
||||
<value>Type '{0}' is not IEnumerable</value>
|
||||
</data>
|
||||
<data name="UnexpectedCoalesceOperator" xml:space="preserve">
|
||||
<value>Unexpected coalesce operator.</value>
|
||||
</data>
|
||||
<data name="InvalidCast" xml:space="preserve">
|
||||
<value>Cannot cast from type '{0}' to type '{1}</value>
|
||||
</data>
|
||||
<data name="UnhandledBinary" xml:space="preserve">
|
||||
<value>Unhandled binary: {0}</value>
|
||||
</data>
|
||||
@@ -370,9 +361,6 @@
|
||||
<data name="UnhandledBindingType" xml:space="preserve">
|
||||
<value>Unhandled Binding Type: {0}</value>
|
||||
</data>
|
||||
<data name="UnhandledConvert" xml:space="preserve">
|
||||
<value>Unhandled convert: {0}</value>
|
||||
</data>
|
||||
<data name="UnhandledUnary" xml:space="preserve">
|
||||
<value>Unhandled unary: {0}</value>
|
||||
</data>
|
||||
@@ -436,9 +424,6 @@
|
||||
<data name="NonLocalJumpWithValue" xml:space="preserve">
|
||||
<value>Cannot jump to non-local label '{0}' with a value. Only jumps to labels defined in outer blocks can pass values.</value>
|
||||
</data>
|
||||
<data name="ExtensionNotReduced" xml:space="preserve">
|
||||
<value>Extension should have been reduced.</value>
|
||||
</data>
|
||||
<data name="CannotCompileConstant" xml:space="preserve">
|
||||
<value>CompileToMethod cannot compile constant '{0}' because it is a non-trivial value, such as a live object. Instead, create an expression tree that can construct this value.</value>
|
||||
</data>
|
||||
@@ -448,9 +433,6 @@
|
||||
<data name="InvalidLvalue" xml:space="preserve">
|
||||
<value>Invalid lvalue for assignment: {0}.</value>
|
||||
</data>
|
||||
<data name="UnknownLiftType" xml:space="preserve">
|
||||
<value>unknown lift type: '{0}'.</value>
|
||||
</data>
|
||||
<data name="UndefinedVariable" xml:space="preserve">
|
||||
<value>variable '{0}' of type '{1}' referenced from scope '{2}', but it is not defined</value>
|
||||
</data>
|
||||
@@ -529,9 +511,6 @@
|
||||
<data name="IncorrectNumberOfConstructorArguments" xml:space="preserve">
|
||||
<value>Incorrect number of arguments for constructor</value>
|
||||
</data>
|
||||
<data name="OperatorNotImplementedForType" xml:space="preserve">
|
||||
<value>The operator '{0}' is not implemented for type '{1}'</value>
|
||||
</data>
|
||||
<data name="NonStaticConstructorRequired" xml:space="preserve">
|
||||
<value>The constructor should not be static</value>
|
||||
</data>
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
|
||||
<Library Name="*System.Linq.Expressions*">
|
||||
<Assembly Name="System.Linq.Expressions">
|
||||
<TypeInstantiation Name="System.Linq.Expressions.ExpressionCreator" Arguments="System.Func{System.Boolean}" Dynamic="Required All" />
|
||||
<TypeInstantiation Name="System.Runtime.CompilerServices.CallSite" Arguments="System.Func{System.Runtime.CompilerServices.CallSite, System.Object, System.Int32}" Dynamic="Required All" />
|
||||
<Type Name="System.Runtime.CompilerServices.CallSiteOps" Dynamic="Required All" />
|
||||
<Type Name="System.Runtime.CompilerServices.RuntimeOps" Dynamic="Required All" />
|
||||
<Namespace Name="System.Linq.Expressions">
|
||||
<Type Name="Expression<TDelegate>">
|
||||
<GenericParameter Name="TDelegate" Dynamic="Public"/>
|
||||
@@ -114,6 +118,8 @@
|
||||
<Type Name="System.Linq.Expressions.ExpressionType" Serialize="Public"/>
|
||||
<!-- Every Expression<T> type must be visible to reflection -->
|
||||
<Type Name="System.Linq.Expressions.Expression<>" Activate="Public"/>
|
||||
<!-- CachedReflectionInfo.cs obtains MemberInfo's for many DynamicObject members -->
|
||||
<Type Name="System.Dynamic.DynamicObject" Dynamic="Required Public" />
|
||||
</Assembly>
|
||||
<Assembly Name="System.Private.CoreLib">
|
||||
<Namespace Name="System">
|
||||
@@ -136,6 +142,28 @@
|
||||
<Method Name="op_Implicit" Dynamic="Required"/>
|
||||
<Method Name="op_Explicit" Dynamic="Required"/>
|
||||
</Type>
|
||||
<Type Name="IDisposable">
|
||||
<Method Name="Dispose" Dynamic="Required"/>
|
||||
</Type>
|
||||
<Type Name="Math">
|
||||
<Method Name="Pow" Dynamic="Required"/>
|
||||
</Type>
|
||||
</Namespace>
|
||||
<Namespace Name="System.Collections">
|
||||
<Type Name="IEnumerator">
|
||||
<Method Name="MoveNext" Dynamic="Required"/>
|
||||
</Type>
|
||||
</Namespace>
|
||||
<Namespace Name="System.Collections.Generic">
|
||||
<Type Name="IEnumerable<>" Dynamic="Required">
|
||||
<Method Name="GetEnumerator" Dynamic="Required"/>
|
||||
</Type>
|
||||
<Type Name="IEnumerator<>">
|
||||
<Property Name="Current" Dynamic="Required"/>
|
||||
</Type>
|
||||
</Namespace>
|
||||
<Namespace Name="System.Runtime.CompilerServices">
|
||||
<Type Name="RuntimeWrappedException" Dynamic="Required All" Activate="Required All" />
|
||||
</Namespace>
|
||||
</Assembly>
|
||||
<Assembly Name="System.Runtime">
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
<Reference Include="System.Resources.ResourceManager" />
|
||||
<Reference Include="System.Runtime" />
|
||||
<Reference Include="System.Runtime.Extensions" />
|
||||
<Reference Include="System.Threading" />
|
||||
<Reference Include="System.Threading" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(CommonPath)\System\Collections\Generic\ArrayBuilder.cs">
|
||||
@@ -63,39 +63,8 @@
|
||||
<Compile Include="$(CommonPath)\System\Collections\Generic\LargeArrayBuilder.cs">
|
||||
<Link>Common\System\Collections\Generic\LargeArrayBuilder.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Dynamic\Utils\CacheDict.cs">
|
||||
<Link>Common\System\Dynamic\Utils\CacheDict.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Dynamic\Utils\ContractUtils.cs">
|
||||
<Link>Common\System\Dynamic\Utils\ContractUtils.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Dynamic\Utils\ContractUtils.RequiresArrayRange.cs">
|
||||
<Link>Common\System\Dynamic\Utils\ContractUtils.RequiresArrayRange.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Dynamic\Utils\Error.cs">
|
||||
<Link>Common\System\Dynamic\Utils\Error.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Dynamic\Utils\ExpressionUtils.cs">
|
||||
<Link>Common\System\Dynamic\Utils\ExpressionUtils.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Dynamic\Utils\Strings.cs">
|
||||
<Link>Common\System\Dynamic\Utils\Strings.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Dynamic\Utils\TypeExtensions.cs">
|
||||
<Link>Common\System\Dynamic\Utils\TypeExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Dynamic\Utils\TypeUtils.cs">
|
||||
<Link>Common\System\Dynamic\Utils\TypeUtils.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Linq\Expressions\Compiler\DelegateHelpers.cs">
|
||||
<Link>Common\System\Linq\Expressions\Compiler\DelegateHelpers.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Linq\Expressions\Compiler\DelegateHelpers.Generated.cs">
|
||||
<Link>Common\System\Linq\Expressions\Compiler\DelegateHelpers.Generated.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\NotImplemented.cs">
|
||||
<Link>Common\System\NotImplemented.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="System\Dynamic\Utils\CacheDict.cs" />
|
||||
<Compile Include="System\Dynamic\Utils\ContractUtils.cs" />
|
||||
<Compile Include="System\Dynamic\Utils\ExpressionUtils.cs" />
|
||||
<Compile Include="System\Dynamic\Utils\ExpressionVisitorUtils.cs" />
|
||||
<Compile Include="System\Dynamic\Utils\ListArgumentProvider.cs" />
|
||||
@@ -160,11 +129,9 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="System\Linq\Expressions\DynamicExpressionVisitor.cs" />
|
||||
<Compile Include="System\Linq\Expressions\DynamicExpression.cs" />
|
||||
<Compile Include="System\Linq\Expressions\Expression.netstandard.cs" />
|
||||
<Compile Include="System\Linq\Expressions\LambdaExpression.netstandard.cs" />
|
||||
<Compile Include="System\Linq\Expressions\ExpressionVisitor.netstandard.cs" />
|
||||
<Compile Include="System\Linq\Expressions\Compiler\TypeInfoExtensions.cs" />
|
||||
<Compile Include="System\Linq\Expressions\Compiler\DelegateHelpers.netstandard.cs" />
|
||||
<Compile Include="System\Linq\Expressions\Compiler\DelegateHelpers.cs" />
|
||||
<Compile Include="System\Linq\Expressions\Compiler\DelegateHelpers.Generated.cs" />
|
||||
<Compile Include="System\Runtime\CompilerServices\RuleCache.cs" />
|
||||
<Compile Include="System\Runtime\CompilerServices\CallSite.cs" />
|
||||
<Compile Include="System\Runtime\CompilerServices\CallSiteBinder.cs" />
|
||||
@@ -211,9 +178,7 @@
|
||||
<Compile Include="$(CommonPath)\System\Collections\Generic\ReferenceEqualityComparer.cs">
|
||||
<Link>Common\System\Collections\Generic\ReferenceEqualityComparer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Linq\Expressions\Compiler\AssemblyGen.cs">
|
||||
<Link>Common\System\Linq\Expressions\Compiler\AssemblyGen.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="System\Linq\Expressions\Compiler\AssemblyGen.cs" />
|
||||
<Compile Include="System\Dynamic\Utils\Helpers.cs" />
|
||||
<Compile Include="System\Linq\Expressions\Compiler\AnalyzedTree.cs" />
|
||||
<Compile Include="System\Linq\Expressions\Compiler\BoundConstants.cs" />
|
||||
@@ -245,9 +210,7 @@
|
||||
<Compile Include="System\Runtime\CompilerServices\RuntimeOps.RuntimeVariableList.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(IsInterpreting)' == 'true' Or '$(FeatureInterpret)' == 'true'">
|
||||
<Compile Include="$(CommonPath)\System\Dynamic\Utils\DelegateHelpers.cs">
|
||||
<Link>Common\System\Dynamic\Utils\DelegateHelpers.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="System\Dynamic\Utils\DelegateHelpers.cs" />
|
||||
<Compile Include="System\Linq\Expressions\Interpreter\AddInstruction.cs" />
|
||||
<Compile Include="System\Linq\Expressions\Interpreter\AndInstruction.cs" />
|
||||
<Compile Include="System\Linq\Expressions\Interpreter\ArrayOperations.cs" />
|
||||
@@ -293,10 +256,9 @@
|
||||
<Compile Include="System\Linq\Expressions\Interpreter\SubInstruction.cs" />
|
||||
<Compile Include="System\Linq\Expressions\Interpreter\TypeOperations.cs" />
|
||||
<Compile Include="System\Linq\Expressions\Interpreter\Utilities.cs" />
|
||||
<Compile Include="System\Linq\Expressions\Compiler\DelegateHelpers.Generated.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
|
||||
</ItemGroup>
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -6,7 +6,6 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Dynamic.Utils;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace System.Dynamic
|
||||
{
|
||||
|
||||
111
external/corefx/src/System.Linq.Expressions/src/System/Dynamic/Utils/CacheDict.cs
vendored
Normal file
111
external/corefx/src/System.Linq.Expressions/src/System/Dynamic/Utils/CacheDict.cs
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace System.Dynamic.Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a dictionary-like object used for caches which holds onto a maximum
|
||||
/// number of elements specified at construction time.
|
||||
/// </summary>
|
||||
internal sealed class CacheDict<TKey, TValue>
|
||||
{
|
||||
// cache size is always ^2.
|
||||
// items are placed at [hash ^ mask]
|
||||
// new item will displace previous one at the same location.
|
||||
private readonly int _mask;
|
||||
private readonly Entry[] _entries;
|
||||
|
||||
// class, to ensure atomic updates.
|
||||
private sealed class Entry
|
||||
{
|
||||
internal readonly int _hash;
|
||||
internal readonly TKey _key;
|
||||
internal readonly TValue _value;
|
||||
|
||||
internal Entry(int hash, TKey key, TValue value)
|
||||
{
|
||||
_hash = hash;
|
||||
_key = key;
|
||||
_value = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a dictionary-like object used for caches.
|
||||
/// </summary>
|
||||
/// <param name="size">The maximum number of elements to store will be this number aligned to next ^2.</param>
|
||||
internal CacheDict(int size)
|
||||
{
|
||||
int alignedSize = AlignSize(size);
|
||||
_mask = alignedSize - 1;
|
||||
_entries = new Entry[alignedSize];
|
||||
}
|
||||
|
||||
private static int AlignSize(int size)
|
||||
{
|
||||
Debug.Assert(size > 0);
|
||||
|
||||
size--;
|
||||
size |= size >> 1;
|
||||
size |= size >> 2;
|
||||
size |= size >> 4;
|
||||
size |= size >> 8;
|
||||
size |= size >> 16;
|
||||
size++;
|
||||
|
||||
Debug.Assert((size & (~size + 1)) == size, "aligned size should be a power of 2");
|
||||
return size;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get the value associated with 'key', returning true if it's found and
|
||||
/// false if it's not present.
|
||||
/// </summary>
|
||||
internal bool TryGetValue(TKey key, out TValue value)
|
||||
{
|
||||
int hash = key.GetHashCode();
|
||||
int idx = hash & _mask;
|
||||
|
||||
Entry entry = Volatile.Read(ref _entries[idx]);
|
||||
if (entry != null && entry._hash == hash && entry._key.Equals(key))
|
||||
{
|
||||
value = entry._value;
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default(TValue);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new element to the cache, possibly replacing some
|
||||
/// element that is already present.
|
||||
/// </summary>
|
||||
internal void Add(TKey key, TValue value)
|
||||
{
|
||||
int hash = key.GetHashCode();
|
||||
int idx = hash & _mask;
|
||||
|
||||
Entry entry = Volatile.Read(ref _entries[idx]);
|
||||
if (entry == null || entry._hash != hash || !entry._key.Equals(key))
|
||||
{
|
||||
Volatile.Write(ref _entries[idx], new Entry(hash, key, value));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value associated with the given key.
|
||||
/// </summary>
|
||||
internal TValue this[TKey key]
|
||||
{
|
||||
set
|
||||
{
|
||||
Add(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
170
external/corefx/src/System.Linq.Expressions/src/System/Dynamic/Utils/ContractUtils.cs
vendored
Normal file
170
external/corefx/src/System.Linq.Expressions/src/System/Dynamic/Utils/ContractUtils.cs
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Dynamic.Utils
|
||||
{
|
||||
internal static class ContractUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns an exception object to be thrown when code is supposed to be unreachable.
|
||||
/// </summary>
|
||||
[ExcludeFromCodeCoverage]
|
||||
public static Exception Unreachable
|
||||
{
|
||||
get
|
||||
{
|
||||
Debug.Assert(false, "Unreachable");
|
||||
return new InvalidOperationException("Code supposed to be unreachable");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requires the <paramref name="precondition"/> to be <c>true</c>.
|
||||
/// </summary>
|
||||
/// <param name="precondition">
|
||||
/// The precondition to check for being <c>true</c>.
|
||||
/// </param>
|
||||
/// <param name="paramName">
|
||||
/// The parameter name to use in the <see cref="ArgumentException.ParamName"/> property when an exception is thrown.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown if <paramref name="precondition"/> is <c>false</c>.
|
||||
/// </exception>
|
||||
public static void Requires(bool precondition, string paramName)
|
||||
{
|
||||
Debug.Assert(!string.IsNullOrEmpty(paramName));
|
||||
|
||||
if (!precondition)
|
||||
{
|
||||
throw Error.InvalidArgumentValue(paramName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requires the <paramref name="value"/> to be non-<c>null</c>.
|
||||
/// </summary>
|
||||
/// <param name="value">
|
||||
/// The value to check for being non-<c>null</c>.
|
||||
/// </param>
|
||||
/// <param name="paramName">
|
||||
/// The parameter name to use in the <see cref="ArgumentException.ParamName"/> property when an exception is thrown.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Thrown if <paramref name="value"/> is <c>null</c>.
|
||||
/// </exception>
|
||||
public static void RequiresNotNull(object value, string paramName)
|
||||
{
|
||||
Debug.Assert(!string.IsNullOrEmpty(paramName));
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException(paramName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requires the <paramref name="value"/> to be non-<c>null</c>.
|
||||
/// </summary>
|
||||
/// <param name="value">
|
||||
/// The value to check for being non-<c>null</c>.
|
||||
/// </param>
|
||||
/// <param name="paramName">
|
||||
/// The parameter name to use in the <see cref="ArgumentException.ParamName"/> property when an exception is thrown.
|
||||
/// </param>
|
||||
/// <param name="index">
|
||||
/// The index of the argument being checked for <c>null</c>.
|
||||
/// If an exception is thrown, this value is used in <see cref="ArgumentException.ParamName"/> if it's greater than or equal to 0.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Thrown if <paramref name="value"/> is <c>null</c>.
|
||||
/// </exception>
|
||||
public static void RequiresNotNull(object value, string paramName, int index)
|
||||
{
|
||||
Debug.Assert(!string.IsNullOrEmpty(paramName));
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException(GetParamName(paramName, index));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requires the <paramref name="collection"/> to be non-empty.
|
||||
/// </summary>
|
||||
/// <param name="collection">
|
||||
/// The collection to check for being non-empty.
|
||||
/// </param>
|
||||
/// <param name="paramName">
|
||||
/// The parameter name to use in the <see cref="ArgumentException.ParamName"/> property when an exception is thrown.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown if the <paramref name="collection"/> is empty.
|
||||
/// </exception>
|
||||
public static void RequiresNotEmpty<T>(ICollection<T> collection, string paramName)
|
||||
{
|
||||
RequiresNotNull(collection, paramName);
|
||||
if (collection.Count == 0)
|
||||
{
|
||||
throw Error.NonEmptyCollectionRequired(paramName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requires the <paramref name="array"/> and all its items to be non-<c>null</c>.
|
||||
/// </summary>
|
||||
/// <param name="array">
|
||||
/// The array to check for being non-<c>null</c> and containing non-<c>null</c> items.
|
||||
/// </param>
|
||||
/// <param name="arrayName">
|
||||
/// The parameter name to use in the <see cref="ArgumentException.ParamName"/> property when an exception is thrown.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Thrown if the <paramref name="array"/> or any of its items is <c>null</c>.
|
||||
/// </exception>
|
||||
public static void RequiresNotNullItems<T>(IList<T> array, string arrayName)
|
||||
{
|
||||
Debug.Assert(!string.IsNullOrEmpty(arrayName));
|
||||
RequiresNotNull(array, arrayName);
|
||||
|
||||
for (int i = 0, n = array.Count; i < n; i++)
|
||||
{
|
||||
if (array[i] == null)
|
||||
{
|
||||
throw new ArgumentNullException(GetParamName(arrayName, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
public static void AssertLockHeld(object lockObject)
|
||||
{
|
||||
Debug.Assert(Monitor.IsEntered(lockObject), "Expected lock is not held.");
|
||||
}
|
||||
|
||||
private static string GetParamName(string paramName, int index) => index >= 0 ? $"{paramName}[{index}]" : paramName;
|
||||
|
||||
/// <summary>
|
||||
/// Requires the range [offset, offset + count] to be a subset of [0, array.Count].
|
||||
/// </summary>
|
||||
/// <exception cref="ArgumentNullException">Array is <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Offset or count are out of range.</exception>
|
||||
public static void RequiresArrayRange<T>(IList<T> array, int offset, int count, string offsetName, string countName)
|
||||
{
|
||||
Debug.Assert(!string.IsNullOrEmpty(offsetName));
|
||||
Debug.Assert(!string.IsNullOrEmpty(countName));
|
||||
Debug.Assert(array != null);
|
||||
|
||||
if (count < 0)
|
||||
throw new ArgumentOutOfRangeException(countName);
|
||||
if (offset < 0 || array.Count - offset < count)
|
||||
throw new ArgumentOutOfRangeException(offsetName);
|
||||
}
|
||||
}
|
||||
}
|
||||
157
external/corefx/src/System.Linq.Expressions/src/System/Dynamic/Utils/DelegateHelpers.cs
vendored
Normal file
157
external/corefx/src/System.Linq.Expressions/src/System/Dynamic/Utils/DelegateHelpers.cs
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Reflection;
|
||||
|
||||
#if !FEATURE_DYNAMIC_DELEGATE
|
||||
using System.Reflection.Emit;
|
||||
#endif
|
||||
|
||||
namespace System.Dynamic.Utils
|
||||
{
|
||||
internal static class DelegateHelpers
|
||||
{
|
||||
internal static Delegate CreateObjectArrayDelegate(Type delegateType, Func<object[], object> handler)
|
||||
{
|
||||
#if !FEATURE_DYNAMIC_DELEGATE
|
||||
return CreateObjectArrayDelegateRefEmit(delegateType, handler);
|
||||
#else
|
||||
return Internal.Runtime.Augments.DynamicDelegateAugments.CreateObjectArrayDelegate(delegateType, handler);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if !FEATURE_DYNAMIC_DELEGATE
|
||||
|
||||
private static readonly MethodInfo s_FuncInvoke = typeof(Func<object[], object>).GetMethod("Invoke");
|
||||
private static readonly MethodInfo s_ArrayEmpty = typeof(Array).GetMethod(nameof(Array.Empty)).MakeGenericMethod(typeof(object));
|
||||
|
||||
// We will generate the following code:
|
||||
//
|
||||
// object ret;
|
||||
// object[] args = new object[parameterCount];
|
||||
// args[0] = param0;
|
||||
// args[1] = param1;
|
||||
// ...
|
||||
// try {
|
||||
// ret = handler.Invoke(args);
|
||||
// } finally {
|
||||
// param0 = (T0)args[0]; // only generated for each byref argument
|
||||
// }
|
||||
// return (TRet)ret;
|
||||
private static Delegate CreateObjectArrayDelegateRefEmit(Type delegateType, Func<object[], object> handler)
|
||||
{
|
||||
MethodInfo delegateInvokeMethod = delegateType.GetInvokeMethod();
|
||||
|
||||
Type returnType = delegateInvokeMethod.ReturnType;
|
||||
bool hasReturnValue = returnType != typeof(void);
|
||||
|
||||
ParameterInfo[] parameters = delegateInvokeMethod.GetParametersCached();
|
||||
Type[] paramTypes = new Type[parameters.Length + 1];
|
||||
paramTypes[0] = typeof(Func<object[], object>);
|
||||
for (int i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
paramTypes[i + 1] = parameters[i].ParameterType;
|
||||
}
|
||||
|
||||
DynamicMethod thunkMethod = new DynamicMethod("Thunk", returnType, paramTypes);
|
||||
ILGenerator ilgen = thunkMethod.GetILGenerator();
|
||||
|
||||
LocalBuilder argArray = ilgen.DeclareLocal(typeof(object[]));
|
||||
LocalBuilder retValue = ilgen.DeclareLocal(typeof(object));
|
||||
|
||||
// create the argument array
|
||||
if (parameters.Length == 0)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Call, s_ArrayEmpty);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldc_I4, parameters.Length);
|
||||
ilgen.Emit(OpCodes.Newarr, typeof(object));
|
||||
}
|
||||
ilgen.Emit(OpCodes.Stloc, argArray);
|
||||
|
||||
// populate object array
|
||||
bool hasRefArgs = false;
|
||||
for (int i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
bool paramIsByReference = parameters[i].ParameterType.IsByRef;
|
||||
Type paramType = parameters[i].ParameterType;
|
||||
if (paramIsByReference)
|
||||
paramType = paramType.GetElementType();
|
||||
|
||||
hasRefArgs = hasRefArgs || paramIsByReference;
|
||||
|
||||
ilgen.Emit(OpCodes.Ldloc, argArray);
|
||||
ilgen.Emit(OpCodes.Ldc_I4, i);
|
||||
ilgen.Emit(OpCodes.Ldarg, i + 1);
|
||||
|
||||
if (paramIsByReference)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldobj, paramType);
|
||||
}
|
||||
Type boxType = ConvertToBoxableType(paramType);
|
||||
ilgen.Emit(OpCodes.Box, boxType);
|
||||
ilgen.Emit(OpCodes.Stelem_Ref);
|
||||
}
|
||||
|
||||
if (hasRefArgs)
|
||||
{
|
||||
ilgen.BeginExceptionBlock();
|
||||
}
|
||||
|
||||
// load delegate
|
||||
ilgen.Emit(OpCodes.Ldarg_0);
|
||||
|
||||
// load array
|
||||
ilgen.Emit(OpCodes.Ldloc, argArray);
|
||||
|
||||
// invoke Invoke
|
||||
ilgen.Emit(OpCodes.Callvirt, s_FuncInvoke);
|
||||
ilgen.Emit(OpCodes.Stloc, retValue);
|
||||
|
||||
if (hasRefArgs)
|
||||
{
|
||||
// copy back ref/out args
|
||||
ilgen.BeginFinallyBlock();
|
||||
for (int i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
if (parameters[i].ParameterType.IsByRef)
|
||||
{
|
||||
Type byrefToType = parameters[i].ParameterType.GetElementType();
|
||||
|
||||
// update parameter
|
||||
ilgen.Emit(OpCodes.Ldarg, i + 1);
|
||||
ilgen.Emit(OpCodes.Ldloc, argArray);
|
||||
ilgen.Emit(OpCodes.Ldc_I4, i);
|
||||
ilgen.Emit(OpCodes.Ldelem_Ref);
|
||||
ilgen.Emit(OpCodes.Unbox_Any, byrefToType);
|
||||
ilgen.Emit(OpCodes.Stobj, byrefToType);
|
||||
}
|
||||
}
|
||||
ilgen.EndExceptionBlock();
|
||||
}
|
||||
|
||||
if (hasReturnValue)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldloc, retValue);
|
||||
ilgen.Emit(OpCodes.Unbox_Any, ConvertToBoxableType(returnType));
|
||||
}
|
||||
|
||||
ilgen.Emit(OpCodes.Ret);
|
||||
|
||||
// TODO: we need to cache these.
|
||||
return thunkMethod.CreateDelegate(delegateType, handler);
|
||||
}
|
||||
|
||||
private static Type ConvertToBoxableType(Type t)
|
||||
{
|
||||
return (t.IsPointer) ? typeof(IntPtr) : t;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,13 +2,17 @@
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Dynamic.Utils
|
||||
{
|
||||
internal static partial class ExpressionUtils
|
||||
internal static class ExpressionUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// See overload with <see cref="IArgumentProvider"/> for more information.
|
||||
@@ -29,5 +33,286 @@ namespace System.Dynamic.Utils
|
||||
// and return what is not guaranteed to be a read-only collection
|
||||
return (ReadOnlyCollection<ParameterExpression>)collection;
|
||||
}
|
||||
|
||||
public static ReadOnlyCollection<T> ReturnReadOnly<T>(ref IReadOnlyList<T> collection)
|
||||
{
|
||||
IReadOnlyList<T> value = collection;
|
||||
|
||||
// if it's already read-only just return it.
|
||||
ReadOnlyCollection<T> res = value as ReadOnlyCollection<T>;
|
||||
if (res != null)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
// otherwise make sure only read-only collection every gets exposed
|
||||
Interlocked.CompareExchange(ref collection, value.ToReadOnly(), value);
|
||||
|
||||
// and return it
|
||||
return (ReadOnlyCollection<T>)collection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper used for ensuring we only return 1 instance of a ReadOnlyCollection of T.
|
||||
///
|
||||
/// This is similar to the ReturnReadOnly of T. This version supports nodes which hold
|
||||
/// onto multiple Expressions where one is typed to object. That object field holds either
|
||||
/// an expression or a ReadOnlyCollection of Expressions. When it holds a ReadOnlyCollection
|
||||
/// the IList which backs it is a ListArgumentProvider which uses the Expression which
|
||||
/// implements IArgumentProvider to get 2nd and additional values. The ListArgumentProvider
|
||||
/// continues to hold onto the 1st expression.
|
||||
///
|
||||
/// This enables users to get the ReadOnlyCollection w/o it consuming more memory than if
|
||||
/// it was just an array. Meanwhile The DLR internally avoids accessing which would force
|
||||
/// the read-only collection to be created resulting in a typical memory savings.
|
||||
/// </summary>
|
||||
public static ReadOnlyCollection<Expression> ReturnReadOnly(IArgumentProvider provider, ref object collection)
|
||||
{
|
||||
Expression tObj = collection as Expression;
|
||||
if (tObj != null)
|
||||
{
|
||||
// otherwise make sure only one read-only collection ever gets exposed
|
||||
Interlocked.CompareExchange(
|
||||
ref collection,
|
||||
new ReadOnlyCollection<Expression>(new ListArgumentProvider(provider, tObj)),
|
||||
tObj
|
||||
);
|
||||
}
|
||||
|
||||
// and return what is not guaranteed to be a read-only collection
|
||||
return (ReadOnlyCollection<Expression>)collection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper which is used for specialized subtypes which use ReturnReadOnly(ref object, ...).
|
||||
/// This is the reverse version of ReturnReadOnly which takes an IArgumentProvider.
|
||||
///
|
||||
/// This is used to return the 1st argument. The 1st argument is typed as object and either
|
||||
/// contains a ReadOnlyCollection or the Expression. We check for the Expression and if it's
|
||||
/// present we return that, otherwise we return the 1st element of the ReadOnlyCollection.
|
||||
/// </summary>
|
||||
public static T ReturnObject<T>(object collectionOrT) where T : class
|
||||
{
|
||||
T t = collectionOrT as T;
|
||||
if (t != null)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
return ((ReadOnlyCollection<T>)collectionOrT)[0];
|
||||
}
|
||||
|
||||
public static void ValidateArgumentTypes(MethodBase method, ExpressionType nodeKind, ref ReadOnlyCollection<Expression> arguments, string methodParamName)
|
||||
{
|
||||
Debug.Assert(nodeKind == ExpressionType.Invoke || nodeKind == ExpressionType.Call || nodeKind == ExpressionType.Dynamic || nodeKind == ExpressionType.New);
|
||||
|
||||
ParameterInfo[] pis = GetParametersForValidation(method, nodeKind);
|
||||
|
||||
ValidateArgumentCount(method, nodeKind, arguments.Count, pis);
|
||||
|
||||
Expression[] newArgs = null;
|
||||
for (int i = 0, n = pis.Length; i < n; i++)
|
||||
{
|
||||
Expression arg = arguments[i];
|
||||
ParameterInfo pi = pis[i];
|
||||
arg = ValidateOneArgument(method, nodeKind, arg, pi, methodParamName, nameof(arguments), i);
|
||||
|
||||
if (newArgs == null && arg != arguments[i])
|
||||
{
|
||||
newArgs = new Expression[arguments.Count];
|
||||
for (int j = 0; j < i; j++)
|
||||
{
|
||||
newArgs[j] = arguments[j];
|
||||
}
|
||||
}
|
||||
if (newArgs != null)
|
||||
{
|
||||
newArgs[i] = arg;
|
||||
}
|
||||
}
|
||||
if (newArgs != null)
|
||||
{
|
||||
arguments = new TrueReadOnlyCollection<Expression>(newArgs);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ValidateArgumentCount(MethodBase method, ExpressionType nodeKind, int count, ParameterInfo[] pis)
|
||||
{
|
||||
if (pis.Length != count)
|
||||
{
|
||||
// Throw the right error for the node we were given
|
||||
switch (nodeKind)
|
||||
{
|
||||
case ExpressionType.New:
|
||||
throw Error.IncorrectNumberOfConstructorArguments();
|
||||
case ExpressionType.Invoke:
|
||||
throw Error.IncorrectNumberOfLambdaArguments();
|
||||
case ExpressionType.Dynamic:
|
||||
case ExpressionType.Call:
|
||||
throw Error.IncorrectNumberOfMethodCallArguments(method, nameof(method));
|
||||
default:
|
||||
throw ContractUtils.Unreachable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Expression ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arguments, ParameterInfo pi, string methodParamName, string argumentParamName, int index = -1)
|
||||
{
|
||||
RequiresCanRead(arguments, argumentParamName, index);
|
||||
Type pType = pi.ParameterType;
|
||||
if (pType.IsByRef)
|
||||
{
|
||||
pType = pType.GetElementType();
|
||||
}
|
||||
|
||||
TypeUtils.ValidateType(pType, methodParamName, allowByRef: true, allowPointer: true);
|
||||
if (!TypeUtils.AreReferenceAssignable(pType, arguments.Type))
|
||||
{
|
||||
if (!TryQuote(pType, ref arguments))
|
||||
{
|
||||
// Throw the right error for the node we were given
|
||||
switch (nodeKind)
|
||||
{
|
||||
case ExpressionType.New:
|
||||
throw Error.ExpressionTypeDoesNotMatchConstructorParameter(arguments.Type, pType, argumentParamName, index);
|
||||
case ExpressionType.Invoke:
|
||||
throw Error.ExpressionTypeDoesNotMatchParameter(arguments.Type, pType, argumentParamName, index);
|
||||
case ExpressionType.Dynamic:
|
||||
case ExpressionType.Call:
|
||||
throw Error.ExpressionTypeDoesNotMatchMethodParameter(arguments.Type, pType, method, argumentParamName, index);
|
||||
default:
|
||||
throw ContractUtils.Unreachable;
|
||||
}
|
||||
}
|
||||
}
|
||||
return arguments;
|
||||
}
|
||||
|
||||
public static void RequiresCanRead(Expression expression, string paramName)
|
||||
{
|
||||
RequiresCanRead(expression, paramName, -1);
|
||||
}
|
||||
|
||||
public static void RequiresCanRead(Expression expression, string paramName, int idx)
|
||||
{
|
||||
ContractUtils.RequiresNotNull(expression, paramName, idx);
|
||||
|
||||
// validate that we can read the node
|
||||
switch (expression.NodeType)
|
||||
{
|
||||
case ExpressionType.Index:
|
||||
IndexExpression index = (IndexExpression)expression;
|
||||
if (index.Indexer != null && !index.Indexer.CanRead)
|
||||
{
|
||||
throw Error.ExpressionMustBeReadable(paramName, idx);
|
||||
}
|
||||
break;
|
||||
case ExpressionType.MemberAccess:
|
||||
MemberExpression member = (MemberExpression)expression;
|
||||
PropertyInfo prop = member.Member as PropertyInfo;
|
||||
if (prop != null)
|
||||
{
|
||||
if (!prop.CanRead)
|
||||
{
|
||||
throw Error.ExpressionMustBeReadable(paramName, idx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Attempts to auto-quote the expression tree. Returns true if it succeeded, false otherwise.
|
||||
public static bool TryQuote(Type parameterType, ref Expression argument)
|
||||
{
|
||||
// We used to allow quoting of any expression, but the behavior of
|
||||
// quote (produce a new tree closed over parameter values), only
|
||||
// works consistently for lambdas
|
||||
Type quoteable = typeof(LambdaExpression);
|
||||
|
||||
if (TypeUtils.IsSameOrSubclass(quoteable, parameterType) && parameterType.IsInstanceOfType(argument))
|
||||
{
|
||||
argument = Expression.Quote(argument);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static ParameterInfo[] GetParametersForValidation(MethodBase method, ExpressionType nodeKind)
|
||||
{
|
||||
ParameterInfo[] pis = method.GetParametersCached();
|
||||
|
||||
if (nodeKind == ExpressionType.Dynamic)
|
||||
{
|
||||
pis = pis.RemoveFirst(); // ignore CallSite argument
|
||||
}
|
||||
return pis;
|
||||
}
|
||||
|
||||
internal static bool SameElements<T>(ICollection<T> replacement, IReadOnlyList<T> current) where T : class
|
||||
{
|
||||
Debug.Assert(current != null);
|
||||
if (replacement == current) // Relatively common case, so particularly useful to take the short-circuit.
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (replacement == null) // Treat null as empty.
|
||||
{
|
||||
return current.Count == 0;
|
||||
}
|
||||
|
||||
return SameElementsInCollection(replacement, current);
|
||||
}
|
||||
|
||||
internal static bool SameElements<T>(ref IEnumerable<T> replacement, IReadOnlyList<T> current) where T : class
|
||||
{
|
||||
Debug.Assert(current != null);
|
||||
if (replacement == current) // Relatively common case, so particularly useful to take the short-circuit.
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (replacement == null) // Treat null as empty.
|
||||
{
|
||||
return current.Count == 0;
|
||||
}
|
||||
|
||||
// Ensure arguments is safe to enumerate twice.
|
||||
// If we have to build a collection, build a TrueReadOnlyCollection<T>
|
||||
// so it won't be built a second time if used.
|
||||
ICollection<T> replacementCol = replacement as ICollection<T>;
|
||||
if (replacementCol == null)
|
||||
{
|
||||
replacement = replacementCol = replacement.ToReadOnly();
|
||||
}
|
||||
|
||||
return SameElementsInCollection(replacementCol, current);
|
||||
}
|
||||
|
||||
private static bool SameElementsInCollection<T>(ICollection<T> replacement, IReadOnlyList<T> current) where T : class
|
||||
{
|
||||
int count = current.Count;
|
||||
if (replacement.Count != count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count != 0)
|
||||
{
|
||||
int index = 0;
|
||||
foreach (T replacementObject in replacement)
|
||||
{
|
||||
if (replacementObject != current[index])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,29 +2,25 @@
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
|
||||
namespace System.Dynamic.Utils
|
||||
{
|
||||
// Extensions on System.Type and friends
|
||||
internal static partial class TypeExtensions
|
||||
internal static class TypeExtensions
|
||||
{
|
||||
private static readonly CacheDict<MethodBase, ParameterInfo[]> s_paramInfoCache = new CacheDict<MethodBase, ParameterInfo[]>(75);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the matching method if the parameter types are reference
|
||||
/// assignable from the provided type arguments, otherwise null.
|
||||
/// </summary>
|
||||
public static MethodInfo GetAnyStaticMethodValidated(this Type type, string name, Type[] types)
|
||||
{
|
||||
foreach (MethodInfo method in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly))
|
||||
{
|
||||
if (method.Name == name && method.MatchesArgumentTypes(types))
|
||||
{
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
Debug.Assert(types != null);
|
||||
MethodInfo method = type.GetMethod(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly, null, types, null);
|
||||
return method.MatchesArgumentTypes(types) ? method : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -38,7 +34,9 @@ namespace System.Dynamic.Utils
|
||||
/// </summary>
|
||||
private static bool MatchesArgumentTypes(this MethodInfo mi, Type[] argTypes)
|
||||
{
|
||||
if (mi == null || argTypes == null)
|
||||
Debug.Assert(argTypes != null);
|
||||
|
||||
if (mi == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -61,11 +59,37 @@ namespace System.Dynamic.Utils
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Type GetReturnType(this MethodBase mi)
|
||||
{
|
||||
return (mi.IsConstructor) ? mi.DeclaringType : ((MethodInfo)mi).ReturnType;
|
||||
}
|
||||
public static Type GetReturnType(this MethodBase mi) => mi.IsConstructor ? mi.DeclaringType : ((MethodInfo)mi).ReturnType;
|
||||
|
||||
public static TypeCode GetTypeCode(this Type type) => Type.GetTypeCode(type);
|
||||
internal static ParameterInfo[] GetParametersCached(this MethodBase method)
|
||||
{
|
||||
CacheDict<MethodBase, ParameterInfo[]> pic = s_paramInfoCache;
|
||||
if (!pic.TryGetValue(method, out ParameterInfo[] pis))
|
||||
{
|
||||
pis = method.GetParameters();
|
||||
|
||||
Type t = method.DeclaringType;
|
||||
if (t != null && t.CanCache())
|
||||
{
|
||||
pic[method] = pis;
|
||||
}
|
||||
}
|
||||
|
||||
return pis;
|
||||
}
|
||||
|
||||
#if FEATURE_COMPILE
|
||||
// Expression trees/compiler just use IsByRef, why do we need this?
|
||||
// (see LambdaCompiler.EmitArguments for usage in the compiler)
|
||||
internal static bool IsByRefParameter(this ParameterInfo pi)
|
||||
{
|
||||
// not using IsIn/IsOut properties as they are not available in Silverlight:
|
||||
if (pi.ParameterType.IsByRef)
|
||||
return true;
|
||||
|
||||
return (pi.Attributes & ParameterAttributes.Out) == ParameterAttributes.Out;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1 +1 @@
|
||||
7866f44723ea1ae12b3293a36f7dd1856eedb124
|
||||
60d45b933bc489e12a2bb109d4ae0f88f5a0cec6
|
||||
@@ -203,7 +203,7 @@ namespace System.Linq.Expressions
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return ReturnObject<Expression>(_arg0);
|
||||
case 0: return ExpressionUtils.ReturnObject<Expression>(_arg0);
|
||||
case 1: return _arg1;
|
||||
default: throw Error.ArgumentOutOfRange(nameof(index));
|
||||
}
|
||||
@@ -296,7 +296,7 @@ namespace System.Linq.Expressions
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return ReturnObject<Expression>(_arg0);
|
||||
case 0: return ExpressionUtils.ReturnObject<Expression>(_arg0);
|
||||
case 1: return _arg1;
|
||||
case 2: return _arg2;
|
||||
default: throw Error.ArgumentOutOfRange(nameof(index));
|
||||
@@ -370,7 +370,7 @@ namespace System.Linq.Expressions
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return ReturnObject<Expression>(_arg0);
|
||||
case 0: return ExpressionUtils.ReturnObject<Expression>(_arg0);
|
||||
case 1: return _arg1;
|
||||
case 2: return _arg2;
|
||||
case 3: return _arg3;
|
||||
@@ -413,7 +413,7 @@ namespace System.Linq.Expressions
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return ReturnObject<Expression>(_arg0);
|
||||
case 0: return ExpressionUtils.ReturnObject<Expression>(_arg0);
|
||||
case 1: return _arg1;
|
||||
case 2: return _arg2;
|
||||
case 3: return _arg3;
|
||||
@@ -501,7 +501,7 @@ namespace System.Linq.Expressions
|
||||
|
||||
internal override ReadOnlyCollection<Expression> GetOrMakeExpressions()
|
||||
{
|
||||
return ReturnReadOnly(ref _expressions);
|
||||
return ExpressionUtils.ReturnReadOnly(ref _expressions);
|
||||
}
|
||||
|
||||
internal override BlockExpression Rewrite(ReadOnlyCollection<ParameterExpression> variables, Expression[] args)
|
||||
@@ -527,7 +527,7 @@ namespace System.Linq.Expressions
|
||||
|
||||
internal override ReadOnlyCollection<ParameterExpression> GetOrMakeVariables()
|
||||
{
|
||||
return ReturnReadOnly(ref _variables);
|
||||
return ExpressionUtils.ReturnReadOnly(ref _variables);
|
||||
}
|
||||
|
||||
protected IReadOnlyList<ParameterExpression> VariablesList => _variables;
|
||||
@@ -577,7 +577,7 @@ namespace System.Linq.Expressions
|
||||
using (IEnumerator<Expression> en = expressions.GetEnumerator())
|
||||
{
|
||||
en.MoveNext();
|
||||
return ReturnObject<Expression>(_body) == en.Current;
|
||||
return ExpressionUtils.ReturnObject<Expression>(_body) == en.Current;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -588,7 +588,7 @@ namespace System.Linq.Expressions
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return ReturnObject<Expression>(_body);
|
||||
case 0: return ExpressionUtils.ReturnObject<Expression>(_body);
|
||||
default: throw Error.ArgumentOutOfRange(nameof(index));
|
||||
}
|
||||
}
|
||||
@@ -636,7 +636,7 @@ namespace System.Linq.Expressions
|
||||
|
||||
internal override ReadOnlyCollection<Expression> GetOrMakeExpressions()
|
||||
{
|
||||
return ReturnReadOnly(ref _body);
|
||||
return ExpressionUtils.ReturnReadOnly(ref _body);
|
||||
}
|
||||
|
||||
internal override BlockExpression Rewrite(ReadOnlyCollection<ParameterExpression> variables, Expression[] args)
|
||||
@@ -852,8 +852,8 @@ namespace System.Linq.Expressions
|
||||
/// <returns>The created <see cref="BlockExpression"/>.</returns>
|
||||
public static BlockExpression Block(Expression arg0, Expression arg1)
|
||||
{
|
||||
RequiresCanRead(arg0, nameof(arg0));
|
||||
RequiresCanRead(arg1, nameof(arg1));
|
||||
ExpressionUtils.RequiresCanRead(arg0, nameof(arg0));
|
||||
ExpressionUtils.RequiresCanRead(arg1, nameof(arg1));
|
||||
|
||||
return new Block2(arg0, arg1);
|
||||
}
|
||||
@@ -867,9 +867,9 @@ namespace System.Linq.Expressions
|
||||
/// <returns>The created <see cref="BlockExpression"/>.</returns>
|
||||
public static BlockExpression Block(Expression arg0, Expression arg1, Expression arg2)
|
||||
{
|
||||
RequiresCanRead(arg0, nameof(arg0));
|
||||
RequiresCanRead(arg1, nameof(arg1));
|
||||
RequiresCanRead(arg2, nameof(arg2));
|
||||
ExpressionUtils.RequiresCanRead(arg0, nameof(arg0));
|
||||
ExpressionUtils.RequiresCanRead(arg1, nameof(arg1));
|
||||
ExpressionUtils.RequiresCanRead(arg2, nameof(arg2));
|
||||
return new Block3(arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
@@ -883,10 +883,10 @@ namespace System.Linq.Expressions
|
||||
/// <returns>The created <see cref="BlockExpression"/>.</returns>
|
||||
public static BlockExpression Block(Expression arg0, Expression arg1, Expression arg2, Expression arg3)
|
||||
{
|
||||
RequiresCanRead(arg0, nameof(arg0));
|
||||
RequiresCanRead(arg1, nameof(arg1));
|
||||
RequiresCanRead(arg2, nameof(arg2));
|
||||
RequiresCanRead(arg3, nameof(arg3));
|
||||
ExpressionUtils.RequiresCanRead(arg0, nameof(arg0));
|
||||
ExpressionUtils.RequiresCanRead(arg1, nameof(arg1));
|
||||
ExpressionUtils.RequiresCanRead(arg2, nameof(arg2));
|
||||
ExpressionUtils.RequiresCanRead(arg3, nameof(arg3));
|
||||
return new Block4(arg0, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
@@ -901,11 +901,11 @@ namespace System.Linq.Expressions
|
||||
/// <returns>The created <see cref="BlockExpression"/>.</returns>
|
||||
public static BlockExpression Block(Expression arg0, Expression arg1, Expression arg2, Expression arg3, Expression arg4)
|
||||
{
|
||||
RequiresCanRead(arg0, nameof(arg0));
|
||||
RequiresCanRead(arg1, nameof(arg1));
|
||||
RequiresCanRead(arg2, nameof(arg2));
|
||||
RequiresCanRead(arg3, nameof(arg3));
|
||||
RequiresCanRead(arg4, nameof(arg4));
|
||||
ExpressionUtils.RequiresCanRead(arg0, nameof(arg0));
|
||||
ExpressionUtils.RequiresCanRead(arg1, nameof(arg1));
|
||||
ExpressionUtils.RequiresCanRead(arg2, nameof(arg2));
|
||||
ExpressionUtils.RequiresCanRead(arg3, nameof(arg3));
|
||||
ExpressionUtils.RequiresCanRead(arg4, nameof(arg4));
|
||||
|
||||
return new Block5(arg0, arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
@@ -140,24 +140,15 @@ namespace System.Linq.Expressions
|
||||
if (variable == null)
|
||||
{
|
||||
TypeUtils.ValidateType(type, nameof(type));
|
||||
if (type.IsByRef)
|
||||
{
|
||||
throw Error.TypeMustNotBeByRef(nameof(type));
|
||||
}
|
||||
|
||||
if (type.IsPointer)
|
||||
{
|
||||
throw Error.TypeMustNotBePointer(nameof(type));
|
||||
}
|
||||
}
|
||||
else if (variable.IsByRef)
|
||||
{
|
||||
throw Error.VariableMustNotBeByRef(variable, variable.Type, nameof(variable));
|
||||
}
|
||||
RequiresCanRead(body, nameof(body));
|
||||
ExpressionUtils.RequiresCanRead(body, nameof(body));
|
||||
if (filter != null)
|
||||
{
|
||||
RequiresCanRead(filter, nameof(filter));
|
||||
ExpressionUtils.RequiresCanRead(filter, nameof(filter));
|
||||
if (filter.Type != typeof(bool)) throw Error.ArgumentMustBeBoolean(nameof(filter));
|
||||
}
|
||||
|
||||
|
||||
@@ -10,11 +10,6 @@ namespace System.Linq.Expressions
|
||||
{
|
||||
internal static partial class CachedReflectionInfo
|
||||
{
|
||||
private static Type[] s_ArrayOfType_Bool;
|
||||
public static Type[] ArrayOfType_Bool =>
|
||||
s_ArrayOfType_Bool ??
|
||||
(s_ArrayOfType_Bool = new[] { typeof(bool) });
|
||||
|
||||
private static ConstructorInfo s_Nullable_Boolean_Ctor;
|
||||
|
||||
public static ConstructorInfo Nullable_Boolean_Ctor
|
||||
@@ -89,6 +84,11 @@ namespace System.Linq.Expressions
|
||||
s_String_op_Equality_String_String ??
|
||||
(s_String_op_Equality_String_String = typeof(string).GetMethod("op_Equality", new[] { typeof(string), typeof(string) }));
|
||||
|
||||
private static MethodInfo s_String_Equals_String_String;
|
||||
public static MethodInfo String_Equals_String_String =>
|
||||
s_String_Equals_String_String ??
|
||||
(s_String_Equals_String_String = typeof(string).GetMethod("Equals", new[] { typeof(string), typeof(string) }));
|
||||
|
||||
private static MethodInfo s_DictionaryOfStringInt32_Add_String_Int32;
|
||||
public static MethodInfo DictionaryOfStringInt32_Add_String_Int32 =>
|
||||
s_DictionaryOfStringInt32_Add_String_Int32 ??
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Dynamic.Utils;
|
||||
using System.Reflection;
|
||||
|
||||
namespace System.Linq.Expressions
|
||||
{
|
||||
|
||||
@@ -10,10 +10,5 @@ namespace System.Linq.Expressions.Compiler
|
||||
{
|
||||
internal readonly Dictionary<object, CompilerScope> Scopes = new Dictionary<object, CompilerScope>();
|
||||
internal readonly Dictionary<LambdaExpression, BoundConstants> Constants = new Dictionary<LambdaExpression, BoundConstants>();
|
||||
|
||||
// Created by VariableBinder
|
||||
internal AnalyzedTree()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
77
external/corefx/src/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/AssemblyGen.cs
vendored
Normal file
77
external/corefx/src/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/AssemblyGen.cs
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Dynamic.Utils;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Linq.Expressions.Compiler
|
||||
{
|
||||
internal sealed class AssemblyGen
|
||||
{
|
||||
private static AssemblyGen s_assembly;
|
||||
|
||||
private readonly ModuleBuilder _myModule;
|
||||
|
||||
private int _index;
|
||||
|
||||
private static AssemblyGen Assembly
|
||||
{
|
||||
get
|
||||
{
|
||||
if (s_assembly == null)
|
||||
{
|
||||
Interlocked.CompareExchange(ref s_assembly, new AssemblyGen(), comparand: null);
|
||||
}
|
||||
return s_assembly;
|
||||
}
|
||||
}
|
||||
|
||||
private AssemblyGen()
|
||||
{
|
||||
var name = new AssemblyName("Snippets");
|
||||
|
||||
// mark the assembly transparent so that it works in partial trust:
|
||||
CustomAttributeBuilder[] attributes = new[] {
|
||||
new CustomAttributeBuilder(typeof(SecurityTransparentAttribute).GetConstructor(Type.EmptyTypes), Array.Empty<object>())
|
||||
};
|
||||
|
||||
AssemblyBuilder myAssembly = AssemblyBuilder.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run, attributes);
|
||||
_myModule = myAssembly.DefineDynamicModule(name.Name);
|
||||
}
|
||||
|
||||
private TypeBuilder DefineType(string name, Type parent, TypeAttributes attr)
|
||||
{
|
||||
ContractUtils.RequiresNotNull(name, nameof(name));
|
||||
ContractUtils.RequiresNotNull(parent, nameof(parent));
|
||||
|
||||
StringBuilder sb = new StringBuilder(name);
|
||||
|
||||
int index = Interlocked.Increment(ref _index);
|
||||
sb.Append("$");
|
||||
sb.Append(index);
|
||||
|
||||
// An unhandled Exception: System.Runtime.InteropServices.COMException (0x80131130): Record not found on lookup.
|
||||
// is thrown if there is any of the characters []*&+,\ in the type name and a method defined on the type is called.
|
||||
sb.Replace('+', '_').Replace('[', '_').Replace(']', '_').Replace('*', '_').Replace('&', '_').Replace(',', '_').Replace('\\', '_');
|
||||
|
||||
name = sb.ToString();
|
||||
|
||||
return _myModule.DefineType(name, attr, parent);
|
||||
}
|
||||
|
||||
internal static TypeBuilder DefineDelegateType(string name)
|
||||
{
|
||||
return Assembly.DefineType(
|
||||
name,
|
||||
typeof(MulticastDelegate),
|
||||
TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.AnsiClass | TypeAttributes.AutoClass
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Dynamic.Utils;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user