This commit is contained in:
Jelle Luteijn 2022-05-15 11:19:49 +02:00
parent 16e76d6b31
commit 484dbfc9d9
529 changed files with 113694 additions and 0 deletions

View file

@ -0,0 +1,348 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace AspClassic.Scripting.Utils;
internal static class ArrayUtils
{
internal sealed class FunctorComparer<T> : IComparer<T>
{
private readonly Comparison<T> _comparison;
public FunctorComparer(Comparison<T> comparison)
{
_comparison = comparison;
}
public int Compare(T x, T y)
{
return _comparison(x, y);
}
}
public static readonly string[] EmptyStrings = new string[0];
public static readonly object[] EmptyObjects = new object[0];
public static IComparer<T> ToComparer<T>(Comparison<T> comparison)
{
return new FunctorComparer<T>(comparison);
}
public static TOutput[] ConvertAll<TInput, TOutput>(TInput[] input, Converter<TInput, TOutput> conv)
{
return Array.ConvertAll(input, conv);
}
public static T[] FindAll<T>(T[] array, Predicate<T> match)
{
return Array.FindAll(array, match);
}
public static void PrintTable(StringBuilder output, string[,] table)
{
ContractUtils.RequiresNotNull(output, "output");
ContractUtils.RequiresNotNull(table, "table");
int num = 0;
for (int i = 0; i < table.GetLength(0); i++)
{
if (table[i, 0].Length > num)
{
num = table[i, 0].Length;
}
}
for (int j = 0; j < table.GetLength(0); j++)
{
output.Append(" ");
output.Append(table[j, 0]);
for (int k = table[j, 0].Length; k < num + 1; k++)
{
output.Append(' ');
}
output.AppendLine(table[j, 1]);
}
}
public static T[] Copy<T>(T[] array)
{
if (array.Length <= 0)
{
return array;
}
return (T[])array.Clone();
}
public static T[] MakeArray<T>(ICollection<T> list)
{
if (list.Count == 0)
{
return new T[0];
}
T[] array = new T[list.Count];
list.CopyTo(array, 0);
return array;
}
public static T[] MakeArray<T>(ICollection<T> elements, int reservedSlotsBefore, int reservedSlotsAfter)
{
if (reservedSlotsAfter < 0)
{
throw new ArgumentOutOfRangeException("reservedSlotsAfter");
}
if (reservedSlotsBefore < 0)
{
throw new ArgumentOutOfRangeException("reservedSlotsBefore");
}
if (elements == null)
{
return new T[reservedSlotsBefore + reservedSlotsAfter];
}
T[] array = new T[reservedSlotsBefore + elements.Count + reservedSlotsAfter];
elements.CopyTo(array, reservedSlotsBefore);
return array;
}
public static T[] RotateRight<T>(T[] array, int count)
{
ContractUtils.RequiresNotNull(array, "array");
if (count < 0 || count > array.Length)
{
throw new ArgumentOutOfRangeException("count");
}
T[] array2 = new T[array.Length];
int num = array.Length - count;
Array.Copy(array, 0, array2, count, num);
Array.Copy(array, num, array2, 0, count);
return array2;
}
public static T[] ShiftRight<T>(T[] array, int count)
{
ContractUtils.RequiresNotNull(array, "array");
if (count < 0)
{
throw new ArgumentOutOfRangeException("count");
}
T[] array2 = new T[array.Length + count];
Array.Copy(array, 0, array2, count, array.Length);
return array2;
}
public static T[] ShiftLeft<T>(T[] array, int count)
{
ContractUtils.RequiresNotNull(array, "array");
if (count < 0)
{
throw new ArgumentOutOfRangeException("count");
}
T[] array2 = new T[array.Length - count];
Array.Copy(array, count, array2, 0, array2.Length);
return array2;
}
public static T[] Insert<T>(T item, IList<T> list)
{
T[] array = new T[list.Count + 1];
array[0] = item;
list.CopyTo(array, 1);
return array;
}
public static T[] Insert<T>(T item1, T item2, IList<T> list)
{
T[] array = new T[list.Count + 2];
array[0] = item1;
array[1] = item2;
list.CopyTo(array, 2);
return array;
}
public static T[] Insert<T>(T item, T[] array)
{
T[] array2 = ShiftRight(array, 1);
array2[0] = item;
return array2;
}
public static T[] Insert<T>(T item1, T item2, T[] array)
{
T[] array2 = ShiftRight(array, 2);
array2[0] = item1;
array2[1] = item2;
return array2;
}
public static T[] Append<T>(T[] array, T item)
{
ContractUtils.RequiresNotNull(array, "array");
Array.Resize(ref array, array.Length + 1);
array[array.Length - 1] = item;
return array;
}
public static T[] AppendRange<T>(T[] array, IList<T> items)
{
return AppendRange(array, items, 0);
}
public static T[] AppendRange<T>(T[] array, IList<T> items, int additionalItemCount)
{
ContractUtils.RequiresNotNull(array, "array");
if (additionalItemCount < 0)
{
throw new ArgumentOutOfRangeException("additionalItemCount");
}
int num = array.Length;
Array.Resize(ref array, array.Length + items.Count + additionalItemCount);
int num2 = 0;
while (num2 < items.Count)
{
array[num] = items[num2];
num2++;
num++;
}
return array;
}
public static T[,] Concatenate<T>(T[,] array1, T[,] array2)
{
int length = array1.GetLength(1);
int length2 = array1.GetLength(0);
int length3 = array2.GetLength(0);
int num = length2 + length3;
T[,] array3 = new T[num, length];
for (int i = 0; i < length2; i++)
{
for (int j = 0; j < length; j++)
{
array3[i, j] = array1[i, j];
}
}
for (int k = 0; k < length3; k++)
{
for (int l = 0; l < length; l++)
{
array3[k + length2, l] = array2[k, l];
}
}
return array3;
}
public static void SwapLastTwo<T>(T[] array)
{
T val = array[array.Length - 1];
array[array.Length - 1] = array[array.Length - 2];
array[array.Length - 2] = val;
}
public static T[] RemoveFirst<T>(IList<T> list)
{
return ShiftLeft(MakeArray(list), 1);
}
public static T[] RemoveFirst<T>(T[] array)
{
return ShiftLeft(array, 1);
}
public static T[] RemoveLast<T>(T[] array)
{
ContractUtils.RequiresNotNull(array, "array");
Array.Resize(ref array, array.Length - 1);
return array;
}
public static T[] RemoveAt<T>(IList<T> list, int indexToRemove)
{
return RemoveAt(MakeArray(list), indexToRemove);
}
public static T[] RemoveAt<T>(T[] array, int indexToRemove)
{
ContractUtils.RequiresNotNull(array, "array");
ContractUtils.Requires(indexToRemove >= 0 && indexToRemove < array.Length, "index");
T[] array2 = new T[array.Length - 1];
if (indexToRemove > 0)
{
Array.Copy(array, 0, array2, 0, indexToRemove);
}
int num = array.Length - indexToRemove - 1;
if (num > 0)
{
Array.Copy(array, array.Length - num, array2, array2.Length - num, num);
}
return array2;
}
public static T[] InsertAt<T>(IList<T> list, int index, params T[] items)
{
return InsertAt(MakeArray(list), index, items);
}
public static T[] InsertAt<T>(T[] array, int index, params T[] items)
{
ContractUtils.RequiresNotNull(array, "array");
ContractUtils.RequiresNotNull(items, "items");
ContractUtils.Requires(index >= 0 && index <= array.Length, "index");
if (items.Length == 0)
{
return Copy(array);
}
T[] array2 = new T[array.Length + items.Length];
if (index > 0)
{
Array.Copy(array, 0, array2, 0, index);
}
Array.Copy(items, 0, array2, index, items.Length);
int num = array.Length - index;
if (num > 0)
{
Array.Copy(array, array.Length - num, array2, array2.Length - num, num);
}
return array2;
}
public static T[] ToArray<T>(ICollection<T> list)
{
if (!(list is T[] result))
{
T[] array = new T[list.Count];
int num = 0;
{
foreach (T item in list)
{
array[num++] = item;
}
return array;
}
}
return result;
}
public static bool ValueEquals<T>(this T[] array, T[] other)
{
if (other.Length != array.Length)
{
return false;
}
for (int i = 0; i < array.Length; i++)
{
if (!object.Equals(array[i], other[i]))
{
return false;
}
}
return true;
}
public static T[] Reverse<T>(this T[] array)
{
T[] array2 = new T[array.Length];
for (int i = 0; i < array.Length; i++)
{
array2[array.Length - i - 1] = array[i];
}
return array2;
}
}

View file

@ -0,0 +1,100 @@
using System;
using System.Reflection;
namespace AspClassic.Scripting.Utils;
[Serializable]
internal struct AssemblyQualifiedTypeName : IEquatable<AssemblyQualifiedTypeName>
{
public readonly string TypeName;
public readonly AssemblyName AssemblyName;
public AssemblyQualifiedTypeName(string typeName, AssemblyName assemblyName)
{
ContractUtils.RequiresNotNull(typeName, "typeName");
ContractUtils.RequiresNotNull(assemblyName, "assemblyName");
TypeName = typeName;
AssemblyName = assemblyName;
}
public AssemblyQualifiedTypeName(Type type)
{
TypeName = type.FullName;
AssemblyName = type.Assembly.GetName();
}
public AssemblyQualifiedTypeName(string assemblyQualifiedTypeName)
{
ContractUtils.RequiresNotNull(assemblyQualifiedTypeName, "assemblyQualifiedTypeName");
int num = assemblyQualifiedTypeName.IndexOf(",");
if (num != -1)
{
TypeName = assemblyQualifiedTypeName.Substring(0, num).Trim();
string text = assemblyQualifiedTypeName.Substring(num + 1).Trim();
if (TypeName.Length > 0 && text.Length > 0)
{
try
{
AssemblyName = new AssemblyName(text);
return;
}
catch (Exception ex)
{
throw new ArgumentException($"Invalid assembly qualified name '{assemblyQualifiedTypeName}': {ex.Message}", ex);
}
}
}
throw new ArgumentException($"Invalid assembly qualified name '{assemblyQualifiedTypeName}'");
}
internal static AssemblyQualifiedTypeName ParseArgument(string str, string argumentName)
{
try
{
return new AssemblyQualifiedTypeName(str);
}
catch (ArgumentException ex)
{
throw new ArgumentException(ex.Message, argumentName, ex.InnerException);
}
}
public bool Equals(AssemblyQualifiedTypeName other)
{
if (TypeName == other.TypeName)
{
return AssemblyName.FullName == other.AssemblyName.FullName;
}
return false;
}
public override bool Equals(object obj)
{
if (obj is AssemblyQualifiedTypeName)
{
return Equals((AssemblyQualifiedTypeName)obj);
}
return false;
}
public override int GetHashCode()
{
return TypeName.GetHashCode() ^ AssemblyName.FullName.GetHashCode();
}
public override string ToString()
{
return TypeName + ", " + AssemblyName.FullName;
}
public static bool operator ==(AssemblyQualifiedTypeName name, AssemblyQualifiedTypeName other)
{
return name.Equals(other);
}
public static bool operator !=(AssemblyQualifiedTypeName name, AssemblyQualifiedTypeName other)
{
return !name.Equals(other);
}
}

View file

@ -0,0 +1,42 @@
#define DEBUG
using System.Collections.Generic;
using System.Diagnostics;
namespace AspClassic.Scripting.Utils;
internal static class Assert
{
[Conditional("DEBUG")]
public static void NotNull(object var)
{
Debug.Assert(var != null);
}
[Conditional("DEBUG")]
public static void NotNull(object var1, object var2)
{
Debug.Assert(var1 != null && var2 != null);
}
[Conditional("DEBUG")]
public static void NotNull(object var1, object var2, object var3)
{
Debug.Assert(var1 != null && var2 != null && var3 != null);
}
[Conditional("DEBUG")]
public static void NotNullItems<T>(IEnumerable<T> items) where T : class
{
Debug.Assert(items != null);
foreach (T item in items)
{
Debug.Assert(item != null);
}
}
[Conditional("DEBUG")]
public static void NotEmpty(string str)
{
Debug.Assert(!string.IsNullOrEmpty(str));
}
}

View file

@ -0,0 +1,97 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace AspClassic.Scripting.Utils;
internal abstract class CheckedDictionaryEnumerator : IDictionaryEnumerator, IEnumerator<KeyValuePair<object, object>>, IDisposable, IEnumerator
{
private enum EnumeratorState
{
NotStarted,
Started,
Ended
}
private EnumeratorState _enumeratorState;
public DictionaryEntry Entry
{
get
{
CheckEnumeratorState();
return new DictionaryEntry(Key, Value);
}
}
public object Key
{
get
{
CheckEnumeratorState();
return GetKey();
}
}
public object Value
{
get
{
CheckEnumeratorState();
return GetValue();
}
}
public object Current => Entry;
KeyValuePair<object, object> IEnumerator<KeyValuePair<object, object>>.Current => new KeyValuePair<object, object>(Key, Value);
private void CheckEnumeratorState()
{
if (_enumeratorState == EnumeratorState.NotStarted)
{
throw Error.EnumerationNotStarted();
}
if (_enumeratorState == EnumeratorState.Ended)
{
throw Error.EnumerationFinished();
}
}
public bool MoveNext()
{
if (_enumeratorState == EnumeratorState.Ended)
{
throw Error.EnumerationFinished();
}
bool flag = DoMoveNext();
if (flag)
{
_enumeratorState = EnumeratorState.Started;
}
else
{
_enumeratorState = EnumeratorState.Ended;
}
return flag;
}
public void Reset()
{
DoReset();
_enumeratorState = EnumeratorState.NotStarted;
}
public void Dispose()
{
GC.SuppressFinalize(this);
}
protected abstract object GetKey();
protected abstract object GetValue();
protected abstract bool DoMoveNext();
protected abstract void DoReset();
}

View file

@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace AspClassic.Scripting.Utils;
internal static class CollectionExtensions
{
internal static ReadOnlyCollection<T> ToReadOnly<T>(this IEnumerable<T> enumerable)
{
if (enumerable == null)
{
return EmptyReadOnlyCollection<T>.Instance;
}
if (enumerable is ReadOnlyCollection<T> result)
{
return result;
}
if (enumerable is ICollection<T> collection)
{
int count = collection.Count;
if (count == 0)
{
return EmptyReadOnlyCollection<T>.Instance;
}
T[] array = new T[count];
collection.CopyTo(array, 0);
return new ReadOnlyCollection<T>(array);
}
return new ReadOnlyCollection<T>(new List<T>(enumerable).ToArray());
}
internal static T[] ToArray<T>(this IEnumerable<T> enumerable)
{
if (enumerable is ICollection<T> collection)
{
T[] array = new T[collection.Count];
collection.CopyTo(array, 0);
return array;
}
return new List<T>(enumerable).ToArray();
}
internal static bool Any<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
foreach (T item in source)
{
if (predicate(item))
{
return true;
}
}
return false;
}
internal static TSource Aggregate<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func)
{
using IEnumerator<TSource> enumerator = source.GetEnumerator();
if (!enumerator.MoveNext())
{
throw new ArgumentException("Collection is empty", "source");
}
TSource val = enumerator.Current;
while (enumerator.MoveNext())
{
val = func(val, enumerator.Current);
}
return val;
}
internal static T[] AddFirst<T>(this IList<T> list, T item)
{
T[] array = new T[list.Count + 1];
array[0] = item;
list.CopyTo(array, 1);
return array;
}
internal static bool TrueForAll<T>(this IEnumerable<T> collection, Predicate<T> predicate)
{
ContractUtils.RequiresNotNull(collection, "collection");
ContractUtils.RequiresNotNull(predicate, "predicate");
foreach (T item in collection)
{
if (!predicate(item))
{
return false;
}
}
return true;
}
}

View file

@ -0,0 +1,107 @@
using System;
using System.IO;
namespace AspClassic.Scripting.Utils;
public sealed class ConsoleInputStream : Stream
{
private const int MinimalBufferSize = 4096;
public static readonly ConsoleInputStream Instance = new ConsoleInputStream();
private readonly Stream _input;
private readonly object _lock = new object();
private readonly byte[] _buffer = new byte[4096];
private int _bufferPos;
private int _bufferSize;
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => false;
public override long Length
{
get
{
throw new NotSupportedException();
}
}
public override long Position
{
get
{
throw new NotSupportedException();
}
set
{
throw new NotSupportedException();
}
}
private ConsoleInputStream()
{
_input = Console.OpenStandardInput();
}
public override int Read(byte[] buffer, int offset, int count)
{
lock (_lock)
{
int num;
if (_bufferSize > 0)
{
num = Math.Min(count, _bufferSize);
Buffer.BlockCopy(_buffer, _bufferPos, buffer, offset, num);
_bufferPos += num;
_bufferSize -= num;
offset += num;
count -= num;
}
else
{
num = 0;
}
if (count > 0)
{
if (count < 4096)
{
int num2 = _input.Read(_buffer, 0, 4096);
int num3 = Math.Min(num2, count);
Buffer.BlockCopy(_buffer, 0, buffer, offset, num3);
_bufferSize = num2 - num3;
_bufferPos = num3;
return num + num3;
}
return num + _input.Read(buffer, offset, count);
}
return num;
}
}
public override void Flush()
{
throw new NotSupportedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
}

View file

@ -0,0 +1,8 @@
namespace AspClassic.Scripting.Utils;
public enum ConsoleStreamType
{
Input,
Output,
ErrorOutput
}

View file

@ -0,0 +1,113 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace AspClassic.Scripting.Utils;
internal static class ContractUtils
{
public static void RequiresNotNull(object value, string paramName)
{
if (value == null)
{
throw new ArgumentNullException(paramName);
}
}
public static void Requires(bool precondition)
{
if (!precondition)
{
throw new ArgumentException(Strings.MethodPreconditionViolated);
}
}
public static void Requires(bool precondition, string paramName)
{
if (!precondition)
{
throw new ArgumentException(Strings.InvalidArgumentValue, paramName);
}
}
public static void Requires(bool precondition, string paramName, string message)
{
if (!precondition)
{
throw new ArgumentException(message, paramName);
}
}
public static void RequiresNotEmpty(string str, string paramName)
{
RequiresNotNull(str, paramName);
if (str.Length == 0)
{
throw new ArgumentException(Strings.NonEmptyStringRequired, paramName);
}
}
public static void RequiresNotEmpty<T>(ICollection<T> collection, string paramName)
{
RequiresNotNull(collection, paramName);
if (collection.Count == 0)
{
throw new ArgumentException(Strings.NonEmptyCollectionRequired, paramName);
}
}
public static void RequiresArrayRange<T>(IList<T> array, int offset, int count, string offsetName, string countName)
{
RequiresArrayRange(array.Count, offset, count, offsetName, countName);
}
public static void RequiresArrayRange(int arraySize, int offset, int count, string offsetName, string countName)
{
if (count < 0)
{
throw new ArgumentOutOfRangeException(countName);
}
if (offset < 0 || arraySize - offset < count)
{
throw new ArgumentOutOfRangeException(offsetName);
}
}
public static void RequiresNotNullItems<T>(IList<T> array, string arrayName)
{
RequiresNotNull(array, arrayName);
for (int i = 0; i < array.Count; i++)
{
if (array[i] == null)
{
throw ExceptionUtils.MakeArgumentItemNullException(i, arrayName);
}
}
}
public static void RequiresNotNullItems<T>(IEnumerable<T> collection, string collectionName)
{
RequiresNotNull(collection, collectionName);
int num = 0;
foreach (T item in collection)
{
if (item == null)
{
throw ExceptionUtils.MakeArgumentItemNullException(num, collectionName);
}
num++;
}
}
public static void RequiresListRange(IList array, int offset, int count, string offsetName, string countName)
{
if (count < 0)
{
throw new ArgumentOutOfRangeException(countName);
}
if (offset < 0 || array.Count - offset < count)
{
throw new ArgumentOutOfRangeException(offsetName);
}
}
}

View file

@ -0,0 +1,49 @@
using System.Collections;
using System.Collections.Generic;
namespace AspClassic.Scripting.Utils;
internal class DictionaryUnionEnumerator : CheckedDictionaryEnumerator
{
private IList<IDictionaryEnumerator> _enums;
private int _current;
public DictionaryUnionEnumerator(IList<IDictionaryEnumerator> enums)
{
_enums = enums;
}
protected override object GetKey()
{
return _enums[_current].Key;
}
protected override object GetValue()
{
return _enums[_current].Value;
}
protected override bool DoMoveNext()
{
if (_current == _enums.Count)
{
return false;
}
if (_enums[_current].MoveNext())
{
return true;
}
_current++;
return DoMoveNext();
}
protected override void DoReset()
{
for (int i = 0; i < _enums.Count; i++)
{
_enums[i].Reset();
}
_current = 0;
}
}

View file

@ -0,0 +1,6 @@
namespace AspClassic.Scripting.Utils;
internal static class EmptyArray<T>
{
internal static T[] Instance = new T[0];
}

View file

@ -0,0 +1,8 @@
using System.Collections.ObjectModel;
namespace AspClassic.Scripting.Utils;
internal static class EmptyReadOnlyCollection<T>
{
internal static ReadOnlyCollection<T> Instance = new ReadOnlyCollection<T>(new T[0]);
}

View file

@ -0,0 +1,13 @@
namespace AspClassic.Scripting.Utils;
public static class EnumBounds
{
public static bool IsValid(this SourceCodeKind value)
{
if (value > SourceCodeKind.Unspecified)
{
return value <= SourceCodeKind.AutoDetect;
}
return false;
}
}

View file

@ -0,0 +1,11 @@
using System;
namespace AspClassic.Scripting.Utils;
internal static class ExceptionUtils
{
public static ArgumentNullException MakeArgumentItemNullException(int index, string arrayName)
{
return new ArgumentNullException($"{arrayName}[{index}]");
}
}

View file

@ -0,0 +1,16 @@
using System;
using System.Linq.Expressions;
namespace AspClassic.Scripting.Utils;
internal sealed class ExpressionUtils
{
internal static Expression Convert(Expression expression, Type type)
{
if (!(expression.Type != type))
{
return expression;
}
return Expression.Convert(expression, type);
}
}

View file

@ -0,0 +1,10 @@
using System.Runtime.InteropServices;
namespace AspClassic.Scripting.Utils;
internal static class NativeMethods
{
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool SetEnvironmentVariable(string name, string value);
}

View file

@ -0,0 +1,165 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace AspClassic.Scripting.Utils;
[Serializable]
internal sealed class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable
{
private sealed class ReadOnlyWrapper<T> : ICollection<T>, IEnumerable<T>, IEnumerable
{
private readonly ICollection<T> _collection;
public int Count => _collection.Count;
public bool IsReadOnly => true;
internal ReadOnlyWrapper(ICollection<T> collection)
{
_collection = collection;
}
public void Add(T item)
{
throw new NotSupportedException("Collection is read-only.");
}
public void Clear()
{
throw new NotSupportedException("Collection is read-only.");
}
public bool Contains(T item)
{
return _collection.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
_collection.CopyTo(array, arrayIndex);
}
public bool Remove(T item)
{
throw new NotSupportedException("Collection is read-only.");
}
public IEnumerator<T> GetEnumerator()
{
return _collection.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _collection.GetEnumerator();
}
}
private readonly IDictionary<TKey, TValue> _dict;
public ICollection<TKey> Keys
{
get
{
ICollection<TKey> keys = _dict.Keys;
if (!keys.IsReadOnly)
{
return new ReadOnlyWrapper<TKey>(keys);
}
return keys;
}
}
public ICollection<TValue> Values
{
get
{
ICollection<TValue> values = _dict.Values;
if (!values.IsReadOnly)
{
return new ReadOnlyWrapper<TValue>(values);
}
return values;
}
}
public TValue this[TKey key] => _dict[key];
TValue IDictionary<TKey, TValue>.this[TKey key]
{
get
{
return _dict[key];
}
set
{
throw new NotSupportedException("Collection is read-only.");
}
}
public int Count => _dict.Count;
public bool IsReadOnly => true;
public ReadOnlyDictionary(IDictionary<TKey, TValue> dict)
{
ReadOnlyDictionary<TKey, TValue> readOnlyDictionary = dict as ReadOnlyDictionary<TKey, TValue>;
_dict = ((readOnlyDictionary != null) ? readOnlyDictionary._dict : dict);
}
public bool ContainsKey(TKey key)
{
return _dict.ContainsKey(key);
}
public bool TryGetValue(TKey key, out TValue value)
{
return _dict.TryGetValue(key, out value);
}
void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
{
throw new NotSupportedException("Collection is read-only.");
}
bool IDictionary<TKey, TValue>.Remove(TKey key)
{
throw new NotSupportedException("Collection is read-only.");
}
public bool Contains(KeyValuePair<TKey, TValue> item)
{
return _dict.Contains(item);
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
_dict.CopyTo(array, arrayIndex);
}
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
{
throw new NotSupportedException("Collection is read-only.");
}
void ICollection<KeyValuePair<TKey, TValue>>.Clear()
{
throw new NotSupportedException("Collection is read-only.");
}
bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
{
throw new NotSupportedException("Collection is read-only.");
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return _dict.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _dict.GetEnumerator();
}
}

View file

@ -0,0 +1,91 @@
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Threading;
namespace AspClassic.Scripting.Utils;
internal static class ReflectionUtils
{
public const char GenericArityDelimiter = '`';
private static AssemblyBuilder _assembly;
private static ModuleBuilder _modBuilder;
private static int _typeCount;
private static readonly Type[] _DelegateCtorSignature = new Type[2]
{
typeof(object),
typeof(IntPtr)
};
private static TypeBuilder DefineDelegateType(string name)
{
if (_assembly == null)
{
Interlocked.CompareExchange(ref _assembly, AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("DynamicDelegates"), AssemblyBuilderAccess.Run), null);
lock (_assembly)
{
if (_modBuilder == null)
{
_modBuilder = _assembly.DefineDynamicModule("DynamicDelegates");
}
}
}
return _modBuilder.DefineType(name + Interlocked.Increment(ref _typeCount), TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.AutoClass, typeof(MulticastDelegate));
}
public static Type GetObjectCallSiteDelegateType(int paramCnt)
{
switch (paramCnt)
{
case 0:
return typeof(Func<CallSite, object, object>);
case 1:
return typeof(Func<CallSite, object, object, object>);
case 2:
return typeof(Func<CallSite, object, object, object, object>);
case 3:
return typeof(Func<CallSite, object, object, object, object, object>);
case 4:
return typeof(Func<CallSite, object, object, object, object, object, object>);
case 5:
return typeof(Func<CallSite, object, object, object, object, object, object, object>);
case 6:
return typeof(Func<CallSite, object, object, object, object, object, object, object, object>);
case 7:
return typeof(Func<CallSite, object, object, object, object, object, object, object, object, object>);
case 8:
return typeof(Func<CallSite, object, object, object, object, object, object, object, object, object, object>);
case 9:
return typeof(Func<CallSite, object, object, object, object, object, object, object, object, object, object, object>);
case 10:
return typeof(Func<CallSite, object, object, object, object, object, object, object, object, object, object, object, object>);
case 11:
return typeof(Func<CallSite, object, object, object, object, object, object, object, object, object, object, object, object, object>);
case 12:
return typeof(Func<CallSite, object, object, object, object, object, object, object, object, object, object, object, object, object, object>);
case 13:
return typeof(Func<CallSite, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object>);
case 14:
return typeof(Func<CallSite, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object>);
default:
{
Type[] array = new Type[paramCnt + 2];
array[0] = typeof(CallSite);
array[1] = typeof(object);
for (int i = 0; i < paramCnt; i++)
{
array[i + 2] = typeof(object);
}
TypeBuilder typeBuilder = DefineDelegateType("Delegate");
typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.RTSpecialName, CallingConventions.Standard, _DelegateCtorSignature).SetImplementationFlags(MethodImplAttributes.CodeTypeMask);
typeBuilder.DefineMethod("Invoke", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.VtableLayoutMask, typeof(object), array).SetImplementationFlags(MethodImplAttributes.CodeTypeMask);
return typeBuilder.CreateType();
}
}
}
}

View file

@ -0,0 +1,15 @@
using System;
using System.Text;
namespace AspClassic.Scripting.Utils;
internal static class StringUtils
{
public static Encoding DefaultEncoding => Encoding.Default;
public static string[] Split(string str, char[] separators, int maxComponents, StringSplitOptions options)
{
ContractUtils.RequiresNotNull(str, "str");
return str.Split(separators, maxComponents, options);
}
}