/// <summary> /// 返回指定的 <see cref="ISourceLocatable"/> 是否完全包含在当前范围中。 /// </summary> /// <param name="thisObj">当前范围。</param> /// <param name="locatable">要检查的范围。</param> /// <returns>如果指定的范围完全包含在当前范围中,则为 <c>true</c>;否则为 <c>false</c>。 /// 对于未知的范围,也会返回 <c>false</c>。</returns> /// <exception cref="ArgumentNullException"><paramref name="thisObj"/> 或 /// <paramref name="locatable"/> 为 <c>null</c>。</exception> /// <overloads> /// <summary> /// 返回指定的范围或位置是否完全包含在当前范围中。 /// </summary> /// </overloads> public static bool Contains(this ISourceLocatable thisObj, ISourceLocatable locatable) { CommonExceptions.CheckArgumentNull(thisObj, "thisObj"); CommonExceptions.CheckArgumentNull(locatable, "locatable"); Contract.EndContractBlock(); return (!thisObj.IsUnknown()) && thisObj.Start <= locatable.Start && thisObj.End >= locatable.End; }
/// <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> /// <value>如果指定对象表示未知范围,则为 <c>true</c>;否则为 <c>false</c>。</value> public static bool IsUnknown(this ISourceLocatable locatable) { if (locatable == null) { throw CommonExceptions.ArgumentNull("locatable"); } Contract.EndContractBlock(); return(locatable.Start == SourcePosition.Unknown || locatable.End == SourcePosition.Unknown); }
/// <summary> /// 获取指定对象在源文件中的字符长度。 /// </summary> /// <value>指定对象在源文件中的字符长度。</value> public static int Length(this ISourceLocatable locatable) { if (locatable == null) { throw CommonExceptions.ArgumentNull("locatable"); } Contract.EndContractBlock(); return(locatable.IsUnknown() ? 0 : locatable.End.Index - locatable.Start.Index + 1); }
/// <summary> /// 使用指定的范围初始化 <see cref="SourceRange"/> 类的新实例。 /// </summary> /// <param name="range">要设置的范围。</param> /// <exception cref="ArgumentException"><paramref name="range"/> 表的不是有效的范围。</exception> public SourceRange(ISourceLocatable range) { CommonExceptions.CheckSourceLocatable(range, nameof(range)); Contract.EndContractBlock(); if (range != null) { start = range.Start; end = range.End; } }
/// <summary> /// 返回指定的索引是否完全包含在当前范围中。 /// </summary> /// <param name="thisObj">当前范围。</param> /// <param name="index">要检查的索引。</param> /// <returns>如果指定的索引包含在当前范围中,则为 <c>true</c>;否则为 <c>false</c>。 /// 对于未知的范围,也会返回 <c>false</c>。</returns> /// <exception cref="ArgumentNullException"><paramref name="thisObj"/> 为 <c>null</c>。</exception> public static bool Contains(this ISourceLocatable thisObj, int index) { CommonExceptions.CheckArgumentNull(thisObj, "thisObj"); Contract.EndContractBlock(); if (index < 0 || thisObj.IsUnknown()) { return(false); } return(thisObj.End.Index >= index && thisObj.Start.Index <= index); }
/// <summary> /// 返回指定的位置是否完全包含在当前范围中。 /// </summary> /// <param name="thisObj">当前范围。</param> /// <param name="location">要检查的位置。</param> /// <returns>如果指定的位置包含在当前范围中,则为 <c>true</c>;否则为 <c>false</c>。 /// 对于未知的范围,也会返回 <c>false</c>。</returns> /// <exception cref="ArgumentNullException"><paramref name="thisObj"/> 为 <c>null</c>。</exception> public static bool Contains(this ISourceLocatable thisObj, SourcePosition location) { CommonExceptions.CheckArgumentNull(thisObj, nameof(thisObj)); Contract.EndContractBlock(); if (location.IsUnknown || thisObj.IsUnknown()) { return(false); } return(thisObj.End.Index >= location.Index && thisObj.Start.Index <= location.Index); }
/// <summary> /// 使用指定的范围初始化 <see cref="SourceRange"/> 类的新实例。 /// </summary> /// <param name="range">要设置的范围。</param> /// <exception cref="ArgumentException"><paramref name="range"/> 表的不是有效的范围。</exception> public SourceRange(ISourceLocatable range) { CommonExceptions.CheckSourceLocatable(range, "range"); Contract.EndContractBlock(); if (range != null) { this.start = range.Start; this.end = range.End; } }
/// <summary> /// 使用指定的源文件名称和范围初始化 <see cref="SourceFileRange"/> 类的新实例。 /// </summary> /// <param name="fileName">源文件的名称。</param> /// <param name="range">要设置的范围。</param> /// <exception cref="ArgumentException"><paramref name="range"/> 表的不是有效的范围。</exception> public SourceFileRange(string fileName, ISourceLocatable range) { CommonExceptions.CheckSourceLocatable(range, "range"); Contract.EndContractBlock(); this.fileName = fileName; if (range != null) { this.start = range.Start; this.end = range.End; } }
/// <summary> /// 使用词法单元的相关信息初始化 <see cref="Token{T}"/> 类的新实例。 /// </summary> /// <param name="id">标识符。</param> /// <param name="text">文本。</param> /// <param name="range">位置范围。</param> public Token(T id, string text, ISourceLocatable range) { CommonExceptions.CheckSourceLocatable(range, nameof(range)); Contract.EndContractBlock(); if (range != null) { start = range.Start; end = range.End; } this.id = id; this.text = text; }
/// <summary> /// 返回指定的 <see cref="ISourceLocatable"/> 是否完全包含在当前范围中。 /// </summary> /// <param name="thisObj">当前范围。</param> /// <param name="locatable">要检查的范围。</param> /// <returns>如果指定的范围完全包含在当前范围中,则为 <c>true</c>;否则为 <c>false</c>。 /// 对于未知的范围,也会返回 <c>false</c>。</returns> /// <exception cref="ArgumentNullException"><paramref name="thisObj"/> 或 /// <paramref name="locatable"/> 为 <c>null</c>。</exception> /// <override> /// <summary> /// 返回指定的范围或位置是否完全包含在当前范围中。 /// </summary> /// </override> public static bool Contains(this ISourceLocatable thisObj, ISourceLocatable locatable) { if (thisObj == null) { throw CommonExceptions.ArgumentNull("thisObj"); } if (locatable == null) { throw CommonExceptions.ArgumentNull("locatable"); } Contract.EndContractBlock(); return((!thisObj.IsUnknown()) && thisObj.Start <= locatable.Start && thisObj.End >= locatable.End); }
/// <summary> /// 使用词法单元的相关信息初始化 <see cref="Token{T}"/> 类的新实例。 /// </summary> /// <param name="id">标识符。</param> /// <param name="text">文本。</param> /// <param name="range">位置范围。</param> /// <param name="value">词法单元的值。</param> public Token(T id, string text, ISourceLocatable range, object value) { CommonExceptions.CheckSourceLocatable(range, "range"); Contract.EndContractBlock(); if (range != null) { this.start = range.Start; this.end = range.End; } this.id = id; this.text = text; this.value = value; }
/// <summary> /// 返回当前范围与指定 <see cref="ISourceLocatable"/> 的重叠范围。 /// </summary> /// <param name="locatable">要检查的范围。</param> /// <returns>当前范围与指定范围重叠的部分。</returns> /// <exception cref="ArgumentNullException"><paramref name="locatable"/> 为 <c>null</c>。</exception> public SourceFileRange Overlap(ISourceLocatable locatable) { CommonExceptions.CheckArgumentNull(locatable, "locatable"); Contract.EndContractBlock(); SourcePosition maxStart = this.start > locatable.Start ? this.start : locatable.Start; SourcePosition minEnd = this.end < locatable.End ? this.end : locatable.End; if (maxStart == SourcePosition.Unknown || maxStart > minEnd) { maxStart = minEnd = SourcePosition.Unknown; } return(new SourceFileRange(this.fileName, maxStart, minEnd)); }
/// <summary> /// 返回当前范围与指定 <see cref="ISourceLocatable"/> 的重叠范围。 /// </summary> /// <param name="locatable">要检查的范围。</param> /// <returns>当前范围与指定范围重叠的部分。</returns> /// <exception cref="ArgumentNullException"><paramref name="locatable"/> 为 <c>null</c>。</exception> public SourceFileRange Overlap(ISourceLocatable locatable) { CommonExceptions.CheckArgumentNull(locatable, nameof(locatable)); Contract.EndContractBlock(); var maxStart = start > locatable.Start ? start : locatable.Start; var minEnd = end < locatable.End ? end : locatable.End; if (maxStart == SourcePosition.Unknown || maxStart > minEnd) { maxStart = minEnd = SourcePosition.Unknown; } return(new SourceFileRange(fileName, maxStart, minEnd)); }
/// <summary> /// 返回指定的位置是否完全包含在当前范围中。 /// </summary> /// <param name="thisObj">当前范围。</param> /// <param name="location">要检查的位置。</param> /// <returns>如果指定的位置包含在当前范围中,则为 <c>true</c>;否则为 <c>false</c>。 /// 对于未知的范围,也会返回 <c>false</c>。</returns> /// <exception cref="ArgumentNullException"><paramref name="thisObj"/> 为 <c>null</c>。</exception> public static bool Contains(this ISourceLocatable thisObj, SourcePosition location) { if (thisObj == null) { throw CommonExceptions.ArgumentNull("thisObj"); } Contract.EndContractBlock(); if (location.IsUnknown || thisObj.IsUnknown()) { return(false); } return(thisObj.End.Index >= location.Index && thisObj.Start.Index <= location.Index); }
/// <summary> /// 返回当前范围与指定 <see cref="ISourceLocatable"/> 的重叠范围,如果不存在则为 /// <see cref="SourceRange.Unknown"/>。 /// </summary> /// <param name="thisObj">当前范围。</param> /// <param name="locatable">要检查的范围。</param> /// <returns>当前范围与指定范围重叠的部分,如果不存在则为 /// <see cref="SourceRange.Unknown"/>。</returns> /// <exception cref="ArgumentNullException"><paramref name="thisObj"/> 或 /// <paramref name="locatable"/> 为 <c>null</c>。</exception>> public static SourceRange Overlap(this ISourceLocatable thisObj, ISourceLocatable locatable) { CommonExceptions.CheckArgumentNull(thisObj, "thisObj"); CommonExceptions.CheckArgumentNull(locatable, "locatable"); Contract.EndContractBlock(); SourcePosition maxStart = thisObj.Start > locatable.Start ? thisObj.Start : locatable.Start; SourcePosition minEnd = thisObj.End < locatable.End ? thisObj.End : locatable.End; if (maxStart == SourcePosition.Unknown || maxStart > minEnd) { return(SourceRange.Unknown); } return(new SourceRange(maxStart, minEnd)); }
/// <summary> /// 使用词法单元的相关信息初始化 <see cref="Token<T>"/> 类的新实例。 /// </summary> /// <param name="id">标识符。</param> /// <param name="text">文本。</param> /// <param name="range">位置范围。</param> public Token(T id, string text, ISourceLocatable range) { if (range != null) { if (range.Start > range.End) { throw ExceptionHelper.ReversedArgument("range.Start", "range.End"); } this.Start = range.Start; this.End = range.End; } this.Id = id; this.Text = text; }
/// <summary> /// 使用词法单元的相关信息初始化 <see cref="Token{T}"/> 类的新实例。 /// </summary> /// <param name="id">标识符。</param> /// <param name="text">文本。</param> /// <param name="range">位置范围。</param> /// <param name="value">词法单元的值。</param> public Token(T id, string text, ISourceLocatable range, object value) { if (range != null) { if (range.Start > range.End) { throw CommonExceptions.ReversedArgument("range.Start", "range.End"); } this.Start = range.Start; this.End = range.End; } this.Id = id; this.Text = text; this.Value = value; }
/// <summary> /// 返回当前范围与指定 <see cref="ISourceLocatable"/> 的重叠范围,如果不存在则为 /// <see cref="SourceRange.Unknown"/>。 /// </summary> /// <param name="locatable">要检查的范围。</param> /// <returns>当前范围与指定范围重叠的部分,如果不存在则为 /// <see cref="SourceRange.Unknown"/>。</returns> /// <exception cref="ArgumentNullException"><paramref name="locatable"/> 为 <c>null</c>。</exception> public SourceRange Overlap(ISourceLocatable locatable) { if (locatable == null) { throw CommonExceptions.ArgumentNull("locatable"); } Contract.EndContractBlock(); SourcePosition maxStart = this.start > locatable.Start ? this.start : locatable.Start; SourcePosition minEnd = this.end < locatable.End ? this.end : locatable.End; if (maxStart == SourcePosition.Unknown || maxStart > minEnd) { return(Unknown); } return(new SourceRange(maxStart, minEnd)); }
/// <summary> /// 使用指定的范围初始化 <see cref="SourceRange"/> 类的新实例。 /// </summary> /// <param name="range">要设置的范围。</param> /// <exception cref="ArgumentException"><paramref name="range"/> 表的不是有效的范围。</exception> public SourceRange(ISourceLocatable range) { if (range == null) { throw CommonExceptions.ArgumentNull("range"); } if (range.Start.IsUnknown != range.End.IsUnknown) { throw CommonExceptions.InvalidSourceRange(range.Start, range.End); } if (!range.Start.IsUnknown && range.Start > range.End) { throw CommonExceptions.ReversedArgument("locatable.Start", "locatable.End"); } Contract.EndContractBlock(); this.start = range.Start; this.end = range.End; }
/// <summary> /// 使用词法单元的相关信息初始化 <see cref="Token{T}"/> 类的新实例。 /// </summary> /// <param name="id">标识符。</param> /// <param name="text">文本。</param> /// <param name="range">位置范围。</param> public Token(T id, string text, ISourceLocatable range) { if (range != null && range.Start.IsUnknown != range.End.IsUnknown) { throw CommonExceptions.InvalidSourceRange(range.Start, range.End); } if (range != null && !range.Start.IsUnknown && range.Start > range.End) { throw CommonExceptions.ReversedArgument("range.Start", "range.End"); } Contract.EndContractBlock(); if (range != null) { this.Start = range.Start; this.End = range.End; } this.Id = id; this.Text = text; }
/// <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) { CommonExceptions.CheckArgumentNull(thisObj, "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="SourceException"/> 类的新实例。 /// </summary> /// <param name="message">解释异常原因的错误消息。</param> /// <param name="range">产生异常的源文件位置。</param> /// <param name="isWarning">异常表示的是否是警告。</param> /// <param name="innerException">导致当前异常的异常;如果未指定内部异常,则是一个 <c>null</c> 引用。</param> public SourceException(string message, ISourceLocatable range, bool isWarning, Exception innerException) : base(message, innerException) { if (range != null) { if (range.Start.IsUnknown != range.End.IsUnknown) { throw CommonExceptions.InvalidSourceRange(range.Start, range.End); } if (!range.Start.IsUnknown && range.Start > range.End) { throw CommonExceptions.ReversedArgument("range.Start", "range.End"); } this.start = range.Start; this.end = range.End; ISourceFileLocatable fileRange = range as ISourceFileLocatable; if (fileRange != null) { this.fileName = fileRange.FileName; } } this.isWarning = isWarning; }
/// <summary> /// 使用指定的错误消息、源文件位置和是否是警告初始化 <see cref="SourceException"/> 类的新实例。 /// </summary> /// <param name="message">解释异常原因的错误消息。</param> /// <param name="range">产生异常的源文件位置。</param> /// <param name="isWarning">异常表示的是否是警告。</param> public SourceException(string message, ISourceLocatable range, bool isWarning) : this(message, range, isWarning, null) { }
/// <summary> /// 使用指定的错误消息、源文件位置和对导致此异常的内部异常的引用初始化 /// <see cref="SourceException"/> 类的新实例。 /// </summary> /// <param name="message">解释异常原因的错误消息。</param> /// <param name="range">产生异常的源文件位置。</param> /// <param name="innerException">导致当前异常的异常;如果未指定内部异常,则是一个 <c>null</c> 引用。</param> public SourceException(string message, ISourceLocatable range, Exception innerException) : this(message, range, false, innerException) { }
/// <summary> /// 使用指定的源文件位置和是否是警告初始化 <see cref="SourceException"/> 类的新实例。 /// </summary> /// <param name="range">产生异常的源文件位置。</param> /// <param name="isWarning">异常表示的是否是警告。</param> public SourceException(ISourceLocatable range, bool isWarning) : this(null, range, isWarning, null) { }
/// <summary> /// 使用指定的源文件位置初始化 <see cref="SourceException"/> 类的新实例。 /// </summary> /// <param name="range">产生异常的源文件位置。</param> public SourceException(ISourceLocatable range) : this(null, range, false, null) { }
/// <summary> /// 获取指定对象是否表示未知范围。 /// </summary> /// <param name="locatable">要检查的对象。</param> /// <returns>如果指定对象表示未知范围,则为 <c>true</c>;否则为 <c>false</c>。</returns> public static bool IsUnknown(this ISourceLocatable locatable) { CommonExceptions.CheckArgumentNull(locatable, "locatable"); Contract.EndContractBlock(); return(locatable.Start == SourcePosition.Unknown || locatable.End == SourcePosition.Unknown); }
/// <summary> /// 使用指定的错误消息和源文件位置初始化 <see cref="SourceException"/> 类的新实例。 /// </summary> /// <param name="message">解释异常原因的错误消息。</param> /// <param name="range">产生异常的源文件位置。</param> public SourceException(string message, ISourceLocatable range) : this(message, range, false, null) { }
/// <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) { CommonExceptions.CheckArgumentNull(locatable, "locatable"); Contract.EndContractBlock(); return((!this.IsUnknown) && this.start <= locatable.End && this.end >= locatable.Start); }
/// <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) { CommonExceptions.CheckArgumentNull(locatable, nameof(locatable)); Contract.EndContractBlock(); return(!IsUnknown && start <= locatable.End && end >= locatable.Start); }
/// <summary> /// 返回当前范围与指定 <see cref="ISourceLocatable"/> 的重叠范围,如果不存在则为 /// <see cref="SourceRange.Unknown"/>。 /// </summary> /// <param name="thisObj">当前范围。</param> /// <param name="locatable">要检查的范围。</param> /// <returns>当前范围与指定范围重叠的部分,如果不存在则为 /// <see cref="SourceRange.Unknown"/>。</returns> /// <exception cref="ArgumentNullException"><paramref name="thisObj"/> 或 /// <paramref name="locatable"/> 为 <c>null</c>。</exception>> public static SourceRange Overlap(this ISourceLocatable thisObj, ISourceLocatable locatable) { CommonExceptions.CheckArgumentNull(thisObj, "thisObj"); CommonExceptions.CheckArgumentNull(locatable, "locatable"); Contract.EndContractBlock(); SourcePosition maxStart = thisObj.Start > locatable.Start ? thisObj.Start : locatable.Start; SourcePosition minEnd = thisObj.End < locatable.End ? thisObj.End : locatable.End; if (maxStart == SourcePosition.Unknown || maxStart > minEnd) { return SourceRange.Unknown; } return new SourceRange(maxStart, minEnd); }