/// <summary> /// 对状态进行排序。 /// </summary> /// <param name="comparer">比较状态时使用的比较器。</param> public void SortStates(IComparer <StateData> comparer) { if (comparer == null) { throw CommonExceptions.ArgumentNull("comparer"); } int[] indexs = new int[this.stateCount].Fill(i => i); int headCnt = this.contextCount * 2; Array.Sort(this.states, indexs, headCnt, this.stateCount - headCnt, comparer); int[] mapper = new int[indexs.Length]; for (int i = 0; i < indexs.Length; i++) { mapper[indexs[i]] = i; } for (int i = 0; i < this.stateCount; i++) { StateData state = this.states[i]; for (int j = 0; j < this.charClassCount; j++) { int next = state.Transitions[j]; if (next >= 0) { state.Transitions[j] = mapper[next]; } } } }
/// <summary> /// 返回指定的行列位置是否完全包含在当前范围中。 /// </summary> /// <param name="thisObj">当前范围。</param> /// <param name="line">要检查的行。</param> /// <param name="col">要检查的列。</param> /// <returns>如果指定的行列位置包含在当前范围中,则为 <c>true</c>;否则为 <c>false</c>。 /// 对于未知的范围,也会返回 <c>false</c>。</returns> /// <exception cref="ArgumentNullException"><paramref name="thisObj"/> 为 <c>null</c>。</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="line"/> 或 <paramref name="col"/> /// 小于 <c>0</c>。</exception> public static bool Contains(this ISourceLocatable thisObj, int line, int col) { if (thisObj == null) { throw CommonExceptions.ArgumentNull("thisObj"); } Contract.EndContractBlock(); if (line < 1 || col < 1 || thisObj.IsUnknown()) { return(false); } if (thisObj.Start.Line == thisObj.End.Line) { return(thisObj.Start.Line == line && thisObj.Start.Col <= col && thisObj.End.Col >= col); } if (thisObj.Start.Line == line) { return(thisObj.Start.Col <= col); } if (thisObj.End.Line == line) { return(thisObj.End.Col >= col); } return(true); }
/// <summary> /// 使用指定的 <see cref="IComparer{T}"/> 泛型接口,在排序 <see cref="IList{T}"/> 的某个元素范围中搜索键值。 /// </summary> /// <typeparam name="TElement">列表元素的类型。</typeparam> /// <typeparam name="TKey">要查找的键的类型。</typeparam> /// <param name="list">要搜索的从零开始的排序 <see cref="IList{T}"/>。</param> /// <param name="index">要搜索的范围的起始索引。</param> /// <param name="length">要搜索的范围的长度。</param> /// <param name="value">要搜索的键值。</param> /// <param name="keySelector">用于从元素中提取键的函数。</param> /// <param name="comparer">比较元素时要使用的 <see cref="IComparer{T}"/> 实现。</param> /// <returns>如果找到 <paramref name="value"/>,则为指定 <paramref name="list"/> /// 中的指定 <paramref name="value"/> 的索引。如果找不到 <paramref name="value"/> /// 且 <paramref name="value"/> 小于 <paramref name="list"/> 中的一个或多个元素, /// 则为一个负数,该负数是大于 <paramref name="value"/> 的第一个元素的索引的按位求补。 /// 如果找不到 <paramref name="value"/> 且 <paramref name="value"/> 大于 <paramref name="list"/> /// 中的任何元素,则为一个负数,该负数是(最后一个元素的索引加 1)的按位求补。</returns> /// <exception cref="ArgumentNullException"><paramref name="list"/> 为 <c>null</c>。</exception> /// <exception cref="ArgumentNullException"><paramref name="keySelector"/> 为 <c>null</c>。</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> 或 /// <paramref name="length"/> 小于 <c>0</c>。</exception> /// <exception cref="ArgumentException"><paramref name="index"/> 和 <paramref name="length"/> /// 不指定 <paramref name="list"/> 中的有效范围。</exception> /// <exception cref="InvalidOperationException"><paramref name="comparer"/> 为 <c>null</c>, /// 且 <typeparamref name="TKey"/> 类型没有实现 <see cref="IComparable{T}"/> 泛型接口。</exception> public static int BinarySearch <TElement, TKey>(this IList <TElement> list, int index, int length, TKey value, Func <TElement, TKey> keySelector, IComparer <TKey> comparer) { if (list == null) { throw CommonExceptions.ArgumentNull("list"); } if (keySelector == null) { throw CommonExceptions.ArgumentNull("keySelector"); } if (index < 0) { throw CommonExceptions.ArgumentNegative("index", index); } if (length < 0) { throw CommonExceptions.ArgumentNegative("length", length); } if (index + length > list.Count) { throw CommonExceptions.InvalidOffsetLength(); } Contract.Ensures((Contract.Result <int>() >= 0 && Contract.Result <int>() <= list.Count) || (Contract.Result <int>() < 0 && ~Contract.Result <int>() <= list.Count + 1)); return(BinarySearchInternal(list, index, length, value, keySelector, comparer)); }
/// <summary> /// 写入指定的 <see cref="decimal"/> 常量。 /// </summary> /// <param name="il">IL 指令生成器。</param> /// <param name="value">要写入的常量。</param> /// <exception cref="ArgumentNullException"><paramref name="il"/> 为 <c>null</c>。</exception> public static void EmitConstant(this ILGenerator il, decimal value) { if (il == null) { throw CommonExceptions.ArgumentNull("il"); } Contract.EndContractBlock(); if (decimal.Truncate(value) == value) { if (int.MinValue <= value && value <= int.MaxValue) { int intValue = decimal.ToInt32(value); il.EmitConstant(intValue); il.Emit(OpCodes.Newobj, decimalCtorInt); return; } if (long.MinValue <= value && value <= long.MaxValue) { long longValue = Decimal.ToInt64(value); il.EmitConstant(longValue); il.Emit(OpCodes.Newobj, decimalCtorLong); return; } } int[] bits = Decimal.GetBits(value); il.EmitConstant(bits[0]); il.EmitConstant(bits[1]); il.EmitConstant(bits[2]); il.EmitConstant((bits[3] & 0x80000000) != 0); il.EmitConstant((byte)(bits[3] >> 16)); il.Emit(OpCodes.Newobj, decimalCtorFull); }
/// <summary> /// 从特定的 <see cref="System.Array"/> 索引处开始, /// 将 <see cref="LabelCollection"/> 的元素复制到一个 <see cref="System.Array"/> 中。 /// </summary> /// <param name="array">作为从 <see cref="LabelCollection"/> /// 复制的元素的目标位置的一维 <see cref="System.Array"/>。 /// <see cref="System.Array"/> 必须具有从零开始的索引。</param> /// <param name="arrayIndex"><paramref name="array"/> 中从零开始的索引,在此处开始复制。</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="array"/> 为 <c>null</c>。</exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="arrayIndex"/> 小于零。</exception> /// <exception cref="System.ArgumentException"> /// <paramref name="array"/> 是多维的。</exception> /// <exception cref="System.ArgumentException">源 <see cref="LabelCollection"/> /// 中的元素数目大于从 <paramref name="arrayIndex"/> 到目标 <paramref name="array"/> /// 末尾之间的可用空间。</exception> public void CopyTo(string[] array, int arrayIndex) { if (array == null) { throw CommonExceptions.ArgumentNull("array"); } if (array.Rank != 1) { throw CommonExceptions.MultidimensionalArrayNotSupported("array"); } if (array.GetLowerBound(0) != 0) { throw CommonExceptions.ArrayNonZeroLowerBound("array"); } if (arrayIndex < 0) { throw CommonExceptions.ArgumentOutOfRange("arrayIndex", arrayIndex); } if (array.Length - arrayIndex < this.Count) { throw CommonExceptions.ArrayTooSmall("array"); } foreach (LexerContext context in this.contexts) { array[arrayIndex++] = context.Label; } }
/// <summary> /// 令位置前进指定字符串的一部分。 /// </summary> /// <param name="str">要前进的字符串。</param> /// <param name="index">要前进的字符的索引。</param> /// <param name="count">要前进的字符的长度。</param> /// <exception cref="ArgumentNullException"><paramref name="str"/> 为 <c>null</c>。</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> 或 /// <paramref name="count"/> 小于零。</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> 和 <paramref name="count"/> /// 不表示 <paramref name="str"/> 中的有效范围。</exception> public void Forward(string str, int index, int count) { if (str == null) { throw CommonExceptions.ArgumentNull("str"); } if (index < 0) { throw CommonExceptions.ArgumentNegative("index", index); } if (count < 0) { throw CommonExceptions.ArgumentNegative("count", count); } if (index + count > str.Length) { throw CommonExceptions.ArgumentOutOfRange("count", count); } Contract.EndContractBlock(); if (count == 1) { Forward(str[index]); } else if (count > 1) { ForwardInternal(str, index, count); } }
/// <summary> /// 用指定的序列化信息和上下文初始化 <see cref="JigsawPiece"/> 类的新实例。 /// </summary> /// <param name="info"><see cref="System.Runtime.Serialization.SerializationInfo"/> 对象, /// 包含序列化 <see cref="JigsawPiece"/> 所需的信息。</param> /// <param name="context"><see cref="System.Runtime.Serialization.StreamingContext"/> 对象, /// 该对象包含与 <see cref="JigsawPiece"/> 相关联的序列化流的源和目标。</param> /// <exception cref="System.ArgumentNullException">info 参数为 <c>null</c>。</exception> private JigsawPiece(SerializationInfo info, StreamingContext context) { if (info == null) { throw CommonExceptions.ArgumentNull("info"); } this.factory = ((JigsawSerializeContext)context.Context).Factory; this.shape = (Path)info.GetValue("Shape", typeof(Path)); this.pieceType = (JigsawPieceType)info.GetValue("Type", typeof(JigsawPieceType)); this.offset = (Vector2)info.GetValue("Offset", typeof(Vector2)); this.rotate = info.GetInt32("Rotate"); this.rotateRadian = (float)(this.rotate * Math.PI / 180); this.scale = info.GetSingle("Scale"); this.Next = (JigsawPiece)info.GetValue("Next", typeof(JigsawPiece)); this.Prev = (JigsawPiece)info.GetValue("Prev", typeof(JigsawPiece)); this.Frozen = info.GetBoolean("Frozen"); this.neighbors = (HashSet <JigsawPiece>)info.GetValue("Neighbors", typeof(HashSet <JigsawPiece>)); this.Visible = true; this.State = JigsawPieceState.None; // 重新填充路径。 this.originalPath = this.shape.GetGeometryGroup(factory); // 重新计算转换矩阵。 CalculateMatrix(); UpdatePath(); }
/// <summary> /// 修改当前集,使该集仅包含当前集或指定集合中存在的元素(但不可包含两者共有的元素)。 /// </summary> /// <param name="other">要与当前集进行比较的集合。</param> /// <exception cref="ArgumentNullException"><paramref name="other"/> 为 <c>null</c>。</exception> public override void SymmetricExceptWith(IEnumerable <char> other) { if (other == null) { throw CommonExceptions.ArgumentNull("other"); } Contract.EndContractBlock(); if (this.count == 0) { this.UnionWith(other); } else if (ReferenceEquals(this, other)) { this.Clear(); } else { CharSet otherSet = other as CharSet; if (otherSet == null || this.ignoreCase != otherSet.ignoreCase || !Equals(this.culture, otherSet.culture)) { otherSet = new CharSet(other, ignoreCase, culture); } // 针对 CharSet 的操作更快。 SymmetricExceptWith(otherSet); } }
/// <summary> /// 获取 <see cref="Type"/> 的完全限定名,包括 <see cref="Type"/> 的命名空间,但不包括程序集。 /// </summary> /// <param name="type">要获取完全限定名的类型。</param> /// <returns>获取 <see cref="Type"/> 的完全限定名,包括 <see cref="Type"/> 的命名空间,但不包括程序集; /// 如果当前实例表示泛型类型参数、数组类型、指针类型或基于类型参数的 byref 类型, /// 或表示不属于泛型类型定义但包含无法解析的类型参数的泛型类型,则返回 <c>null</c>。</returns> /// <exception cref="ArgumentNullException"><paramref name="type"/> 为 <c>null</c>。</exception> /// <remarks>与 <see cref="Type.FullName"/> 不同,即使如果当前 <see cref="Type"/> 表示泛型类型, /// <see cref="FullName"/> 返回的字符串中的类型实参也不会包含程序集、版本等信息。</remarks> public static string FullName(this Type type) { if (type == null) { throw CommonExceptions.ArgumentNull("type"); } Contract.EndContractBlock(); if (!type.IsGenericType || type.ContainsGenericParameters) { return(type.FullName); } StringBuilder text = new StringBuilder(type.GetGenericTypeDefinition().FullName); text.Append('['); Type[] args = type.GetGenericArguments(); for (int i = 0; i < args.Length; i++) { if (i > 0) { text.Append(','); } Contract.Assume(args[i] != null); text.Append(args[i].FullName()); } text.Append(']'); return(text.ToString()); }
/// <summary> /// 返回与特定区域性相关的文件名。 /// </summary> /// <param name="path">文件的路径。</param> /// <param name="fileName">文件的名称。</param> /// <param name="culture">要获取的文件的区域性信息。</param> /// <returns>与特定区域性相关的文件名,如果不存在则为 <c>null</c>。</returns> /// <remarks>与特定区域性相关的文件名,其形式为 path/culture.Name/fileName。</remarks> /// <exception cref="ArgumentNullException"><paramref name="path"/>、<paramref name="fileName"/> 或 /// <paramref name="culture"/> 为 <c>null</c>。</exception> /// <exception cref="ArgumentException"><paramref name="path"/> 或 <paramref name="fileName"/> /// 中包含一个或多个无效字符。</exception> public static string GetCultureSpecifiedFile(string path, string fileName, CultureInfo culture) { if (path == null) { throw CommonExceptions.ArgumentNull("path"); } if (fileName == null) { throw CommonExceptions.ArgumentNull("fileName"); } if (culture == null) { throw CommonExceptions.ArgumentNull("culture"); } Contract.EndContractBlock(); while (true) { string filePath = Path.Combine(path, culture.Name, fileName); if (File.Exists(filePath)) { return(filePath); } if (culture.Equals(CultureInfo.InvariantCulture)) { break; } culture = culture.Parent; } return(null); }
/// <summary> /// 确定当前集与指定的集合中是否包含相同的元素。 /// </summary> /// <param name="other">要与当前集进行比较的集合。</param> /// <returns>如果当前集等于 <paramref name="other"/>,则为 <c>true</c>; /// 否则为 <c>false</c>。</returns> /// <exception cref="ArgumentNullException"><paramref name="other"/> 为 <c>null</c>。</exception> public override bool SetEquals(IEnumerable <char> other) { if (other == null) { throw CommonExceptions.ArgumentNull("other"); } Contract.EndContractBlock(); CharSet otherSet = other as CharSet; if (otherSet != null && this.ignoreCase == otherSet.ignoreCase && Equals(this.culture, otherSet.culture)) { return(count == otherSet.count && this.ContainsAllElements(otherSet)); } ICollection <char> col = other as ICollection <char>; if (this.count == 0) { if (col == null) { return(!other.Any()); } if (col.Count > 0) { return(false); } } int sameCount, unfoundCount; CountElements(other, true, out sameCount, out unfoundCount); return(sameCount == count && unfoundCount == 0); }
/// <summary> /// 修改当前集,使该集仅包含指定集合中也存在的元素。 /// </summary> /// <param name="other">要与当前集进行比较的集合。</param> /// <exception cref="ArgumentNullException"><paramref name="other"/> 为 <c>null</c>。</exception> public override void IntersectWith(IEnumerable <char> other) { if (other == null) { throw CommonExceptions.ArgumentNull("other"); } Contract.EndContractBlock(); if (this.count <= 0 || ReferenceEquals(this, other)) { return; } CharSet otherSet = other as CharSet; if (otherSet != null && this.ignoreCase == otherSet.ignoreCase && Equals(this.culture, otherSet.culture)) { // 针对 CharSet 的操作更快。 IntersectWith(otherSet); } else { otherSet = new CharSet(other.Where(this.Contains), ignoreCase, culture); // 替换当前集合。 this.data = otherSet.data; this.count = otherSet.count; } }
/// <summary> /// 确定当前集是否为指定集合的超集。 /// </summary> /// <param name="other">要与当前集进行比较的集合。</param> /// <returns>如果当前集是 <paramref name="other"/> 的超集,则为 /// <c>true</c>;否则为 <c>false</c>。</returns> /// <exception cref="ArgumentNullException"><paramref name="other"/> 为 <c>null</c>。</exception> public override bool IsSupersetOf(IEnumerable <char> other) { if (other == null) { throw CommonExceptions.ArgumentNull("other"); } Contract.EndContractBlock(); ICollection <char> col = other as ICollection <char>; if (col != null) { if (col.Count == 0) { return(true); } if (this.count == 0) { return(false); } } CharSet otherSet = other as CharSet; if (otherSet == null || this.ignoreCase != otherSet.ignoreCase || !Equals(this.culture, otherSet.culture)) { return(other.All(this.Contains)); } return(otherSet.Count <= this.count && this.ContainsAllElements(otherSet)); }
public bool TryGetValue(TKey key, out TItem item) { if (key == null) { throw CommonExceptions.ArgumentNull("key"); } Contract.EndContractBlock(); if (this.dict != null) { return(this.dict.TryGetValue(key, out item)); } int cnt = this.Count; for (int i = 0; i < cnt; i++) { item = this.GetItemAt(i); TKey itemKey = this.GetKeyForItem(item); Contract.Assert(itemKey != null); if (this.comparer.Equals(itemKey, key)) { return(true); } } item = default(TItem); return(false); }
/// <summary> /// 替换指定索引处的元素。 /// </summary> /// <param name="index">待替换元素的从零开始的索引。</param> /// <param name="item">位于指定索引处的元素的新值。</param> /// <exception cref="ArgumentNullException"><paramref name="item"/> 为 <c>null</c>。</exception> protected override void SetItemAt(int index, TItem item) { if (item == null) { throw CommonExceptions.ArgumentNull("item"); } Contract.EndContractBlock(); TKey oldKey = this.GetKeyForItem(this.GetItemAt(index)); Contract.Assert(oldKey != null); TKey key = this.GetKeyForItem(item); Contract.Assert(key != null); if (this.dict != null) { if (this.comparer.Equals(oldKey, key)) { this.dict[key] = item; } else { this.dict.Remove(oldKey); this.dict.Add(key, item); } } base.SetItemAt(index, item); }
/// <summary> /// 使用指定的语法规则初始化 <see cref="Cyjb.Compilers.Lexers.LexerRule<T>"/> 类的新实例。 /// </summary> /// <param name="grammar">词法分析器使用的语法规则。</param> internal LexerRule(Grammar <T> grammar) { if (grammar == null) { throw CommonExceptions.ArgumentNull("grammar"); } this.contextCount = grammar.Contexts.Count; this.contexts = new Dictionary <string, int>(contextCount); int i = 0; foreach (string context in grammar.Contexts) { this.contexts.Add(context, i++); } this.symbolCount = grammar.Terminals.Count; this.symbols = new SymbolData <T> [this.symbolCount]; foreach (Terminal <T> sym in grammar.Terminals) { this.symbols[sym.Index] = new SymbolData <T>(sym.Id, sym.Action); } FillEOFActions(grammar); bool useTrailing; FillDfa(grammar, out useTrailing); if (useTrailing) { FillTrailing(grammar); } else { this.trailingType = TrailingType.None; } this.ContainsBeginningOfLineHeader = true; }
/// <summary> /// 基于所提供的参数,获取或设置子配置元素。 /// </summary> /// <param name="key">集合中包含的子配置元素的键。</param> /// <returns>子配置元素,如果不存在则返回 <c>null</c>。</returns> /// <overloads> /// <summary> /// 获取或设置此 <see cref="ConfigurationElementCollection{T}"/> 对象的属性、特性或子元素。 /// </summary> /// </overloads> public TElement this[TKey key] { get { return(BaseGet(key) as TElement); } set { if (value == null) { throw CommonExceptions.ArgumentNull("value"); } Contract.EndContractBlock(); ConfigurationElement item = BaseGet(key); if (item != null) { BaseRemove(key); } try { this.BaseAdd(value); } catch { // 出错了,撤销删除。 if (item != null) { this.BaseAdd(item); } throw; } } }
/// <summary> /// 将指定的常量写入 IL 中。一些常量(如自定义类)不能写入到 IL 中,此时需要使用闭包来实现。 /// </summary> /// <param name="il">IL 指令生成器。</param> /// <param name="value">要写入的常量。</param> /// <param name="type">要写入的常量的类型。</param> /// <returns>如果常量成功写入到 IL 中,则为 <c>true</c>;否则为 <c>false</c>。</returns> /// <exception cref="ArgumentNullException"><paramref name="il"/> 为 <c>null</c>。</exception> /// <remarks>如果 <paramref name="value"/> 为 <c>null</c>,那么会写入 <paramref name="type"/> 类型的默认值。</remarks> public static bool EmitConstant(this ILGenerator il, object value, Type type) { if (il == null) { throw CommonExceptions.ArgumentNull("il"); } Contract.EndContractBlock(); if (value == null) { il.EmitDefault(type ?? typeof(object)); return(true); } if (type == null) { type = value.GetType(); } if (il.EmitPrimitiveConstant(value, type)) { return(true); } Type typeValue = value as Type; if (typeValue != null && (typeValue.IsGenericParameter || typeValue.IsVisible)) { il.Emit(OpCodes.Ldtoken, type); il.Emit(OpCodes.Call, getTypeFromHandler); if (type != typeof(Type)) { il.Emit(OpCodes.Castclass, type); } return(true); } MethodBase method = value as MethodBase; if (method == null) { return(false); } Type declaringType = method.DeclaringType; if (declaringType != null && !declaringType.IsGenericParameter && !declaringType.IsVisible) { return(false); } il.Emit(OpCodes.Ldtoken, method); if (declaringType == null || !declaringType.IsGenericType) { il.Emit(OpCodes.Call, getMethodFromHandle); } else { il.Emit(OpCodes.Ldtoken, declaringType); il.Emit(OpCodes.Call, getMethodFromHandleWithType); } if (type != typeof(MethodBase)) { il.Emit(OpCodes.Castclass, type); } return(true); }
/// <summary> /// 修改当前集,使该集包含当前集和指定集合中同时存在的所有元素。 /// </summary> /// <param name="other">要与当前集进行比较的集合。</param> /// <exception cref="ArgumentNullException"><paramref name="other"/> 为 <c>null</c>。</exception> public override void UnionWith(IEnumerable <char> other) { if (other == null) { throw CommonExceptions.ArgumentNull("other"); } Contract.EndContractBlock(); if (ReferenceEquals(this, other)) { return; } CharSet otherSet = other as CharSet; if (otherSet != null && this.ignoreCase == otherSet.ignoreCase && Equals(this.culture, otherSet.culture)) { // 针对 CharSet 的操作更快。 this.UnionWith(otherSet); } else { foreach (char c in other) { this.AddItem(c); } } }
/// <summary> /// 将栈顶的对象从 <paramref name="inputType"/> 转换为 <paramref name="outputType"/>。 /// </summary> /// <param name="il">IL 指令生成器。</param> /// <param name="inputType">要转换的对象的类型。</param> /// <param name="outputType">要将输入对象转换到的类型。</param> /// <param name="isChecked">是否执行溢出检查。</param> /// <exception cref="ArgumentNullException"><paramref name="il"/> 为 <c>null</c>。</exception> /// <exception cref="ArgumentNullException"><paramref name="inputType"/> 为 <c>null</c>。</exception> /// <exception cref="ArgumentNullException"><paramref name="outputType"/> 为 <c>null</c>。</exception> public static void EmitConversion(this ILGenerator il, Type inputType, Type outputType, bool isChecked) { if (il == null) { throw CommonExceptions.ArgumentNull("il"); } if (inputType == null) { throw CommonExceptions.ArgumentNull("inputType"); } if (outputType == null) { throw CommonExceptions.ArgumentNull("outputType"); } Contract.EndContractBlock(); Conversion conversion = ConversionFactory.GetConversion(inputType, outputType); if (conversion == null) { throw CommonExceptions.InvalidCast(inputType, outputType); } if (conversion is FromNullableConversion) { il.EmitGetAddress(inputType); } conversion.Emit(il, inputType, outputType, isChecked); }
/// <summary> /// 加载指定索引的参数,并转换为指定类型。 /// </summary> /// <param name="il">IL 指令生成器。</param> /// <param name="index">要加载的参数索引。</param> /// <param name="paramType">要加载的参数类型。</param> /// <param name="targetType">要转换到的类型。</param> /// <param name="isChecked">是否执行溢出检查。</param> /// <remarks>会根据 <paramref name="index"/> 的值,选择最合适的 IL 指令。</remarks> /// <exception cref="ArgumentNullException"><paramref name="il"/> 为 <c>null</c>。</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> 小于 <c>0</c>。</exception> /// <exception cref="ArgumentNullException"><paramref name="targetType"/> 为 <c>null</c>。</exception> public static void EmitLoadArg(this ILGenerator il, int index, Type paramType, Type targetType, bool isChecked) { if (il == null) { throw CommonExceptions.ArgumentNull("il"); } if (index < 0) { throw CommonExceptions.ArgumentNegative("index", index); } if (targetType == null) { throw CommonExceptions.ArgumentNull("targetType"); } Contract.EndContractBlock(); if (paramType == targetType) { il.EmitLoadArg(index); return; } Converter converter = il.GetConversion(paramType, targetType); if (converter.PassByAddr) { il.EmitLoadArgAddress(index); } else { il.EmitLoadArg(index); } converter.Emit(isChecked); }
/// <summary> /// 基于参数类型,从给定的方法集中选择一个方法。 /// 允许通过指定 <see cref="BindingFlags.OptionalParamBinding"/> 来匹配可选参数。 /// </summary> /// <param name="bindingAttr"><see cref="System.Reflection.BindingFlags"/> 值的按位组合。</param> /// <param name="match">用于匹配的候选方法集。</param> /// <param name="types">用于定位匹配方法的参数类型。</param> /// <param name="modifiers">使绑定能够处理在其中修改了类型的参数签名的参数修饰符数组。</param> /// <returns>如果找到,则为匹配的方法;否则为 <c>null</c>。</returns> public override MethodBase SelectMethod(BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers) { if (match == null) { throw CommonExceptions.ArgumentNull("match"); } if (match.Length == 0) { throw CommonExceptions.CollectionEmpty("match"); } // 构造方法信息数组。 MatchInfo[] infos = new MatchInfo[match.Length]; MatchInfo info = null; int idx = 0; for (int i = 0; i < match.Length; i++) { if (match[i] != null) { info = new MatchInfo(match[i]); int len = info.Parameters.Length > types.Length ? info.Parameters.Length : types.Length; info.ParamOrder = info.ParamOrderRev = MethodExt.GetParamOrder(len); infos[idx++] = info; } } info = SelectMethod(bindingAttr, infos, idx, types); if (info == null) { return(null); } return(info.Method); }
/// <summary> /// 返回表示字符类的正则表达式。 /// </summary> /// <param name="pattern">正则表达式表示的字符类的模式。</param> /// <param name="options">解析模式使用的正则表达式选项。</param> /// <returns>表示字符类的正则表达式。</returns> public static Regex CharClassPattern(string pattern, RegexOptions options) { if (pattern == null) { throw CommonExceptions.ArgumentNull("pattern"); } return(new CharClassExp(RegexCharClass.ParsePattern(pattern, options).ToStringClass())); }
/// <summary> /// 返回表示字符类的正则表达式。 /// </summary> /// <param name="cc">正则表达式表示的字符类。</param> /// <returns>表示字符类的正则表达式。</returns> public static Regex CharClass(RegexCharClass cc) { if (cc == null) { throw CommonExceptions.ArgumentNull("cc"); } return(new CharClassExp(cc.ToStringClass())); }
/// <summary> /// 定义具有指定正则表达式和动作的终结符。 /// </summary> /// <param name="regex">终结符对应的正则表达式。</param> /// <param name="action">终结符的动作。</param> public void DefineSymbol(string regex, Action <ReaderController <T> > action) { if (regex == null) { throw CommonExceptions.ArgumentNull("regex"); } InternalDefineSymbol(regex, action); }
/// <summary> /// 返回指定源文件的允许拒绝的词法单元读取器。 /// </summary> /// <param name="source">要读取的源文件。</param> /// <returns>指定源文件的词法单元读取器。</returns> /// <overloads> /// <summary> /// 返回指定源文件的允许拒绝的词法单元读取器。 /// </summary> /// </overloads> public TokenReader <T> GetRejectableReader(string source) { if (source == null) { throw CommonExceptions.ArgumentNull("source"); } return(GetRejectableReader(new SourceReader(new StringReader(source)))); }
/// <summary> /// 返回指定的 <see cref="ISourceLocatable"/> 是否与当前范围存在重叠。 /// </summary> /// <param name="locatable">要检查的范围。</param> /// <returns>如果指定的范围与当前范围存在重叠,则为 <c>true</c>;否则为 <c>false</c>。 /// 对于未知的范围,也会返回 <c>false</c>。</returns> /// <exception cref="ArgumentNullException"><paramref name="locatable"/> 为 <c>null</c>。</exception> public bool OverlapsWith(ISourceLocatable locatable) { if (locatable == null) { throw CommonExceptions.ArgumentNull("locatable"); } Contract.EndContractBlock(); return((!this.IsUnknown) && this.start <= locatable.End && this.end >= locatable.Start); }
/// <summary> /// 为当前源文件位置附加源文件名。 /// </summary> /// <param name="fileName">源文件的名称。</param> /// <returns>表示指定源文件中的指定范围的实例。</returns> public SourceFileRange WithFile(string fileName) { if (fileName == null) { throw CommonExceptions.ArgumentNull("fileName"); } Contract.EndContractBlock(); return(new SourceFileRange(fileName, this.start, this.end)); }
public static Type GetNonNullableType(this Type type) { if (type == null) { throw CommonExceptions.ArgumentNull("type"); } Contract.Ensures(Contract.Result <Type>() != null); return(Nullable.GetUnderlyingType(type) ?? type); }
/// <summary> /// 获取指定字典的值集合。 /// </summary> /// <param name="dict">要获取值集合的字典。</param> /// <returns>指定字典的值集合。</returns> public static IEnumerable <TItem> GetDictValues <TKey, TItem>(IDictionary <TKey, TItem> dict) { if (dict == null) { throw CommonExceptions.ArgumentNull("dict"); } Contract.Ensures(Contract.Result <IEnumerable <TItem> >() != null); return(dict.Values); }