292 lines
8.2 KiB
C#
292 lines
8.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using JD.Kernel.StaticHelpers;
|
|
|
|
namespace JD.Kernel.Structs
|
|
{
|
|
/// <summary>
|
|
/// A simple file location.
|
|
/// </summary>
|
|
[Serializable]
|
|
public struct FileLocation
|
|
{
|
|
#region Constants
|
|
|
|
/// <summary>
|
|
/// String that is used in canonical strings when the fileName is empty.
|
|
/// </summary>
|
|
internal const string UnknownFileName = "<Unknown FileName>";
|
|
|
|
#endregion
|
|
|
|
#region Variables
|
|
|
|
private string m_fileName;
|
|
private int m_lineNumber;
|
|
private int m_columnNumber;
|
|
private int m_endLineNumber;
|
|
private int m_endColumnNumber;
|
|
private AdditionalInfo m_additionalInfo;
|
|
|
|
#endregion
|
|
|
|
#region Constructor
|
|
|
|
/// <summary>
|
|
/// Constructor.
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
public FileLocation(string fileName)
|
|
: this(fileName, 0, 0)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Constructor.
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <param name="additionalInfo"></param>
|
|
public FileLocation(string fileName, object additionalInfo)
|
|
: this(fileName, 0, 0)
|
|
{
|
|
AddInfo(additionalInfo);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Constructor.
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <param name="line"></param>
|
|
/// <param name="column"></param>
|
|
public FileLocation(string fileName, int line, int column)
|
|
: this(fileName, line, column, line, column)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Constructor.
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <param name="line"></param>
|
|
/// <param name="column"></param>
|
|
/// <param name="endLine"></param>
|
|
/// <param name="endColumn"></param>
|
|
public FileLocation(string fileName, int line, int column, int endLine, int endColumn)
|
|
{
|
|
m_fileName = fileName;
|
|
m_lineNumber = line;
|
|
m_columnNumber = column;
|
|
m_endLineNumber = endLine;
|
|
m_endColumnNumber = endColumn;
|
|
m_additionalInfo = null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy constructor.
|
|
/// </summary>
|
|
/// <param name="src"></param>
|
|
public FileLocation(FileLocation src)
|
|
{
|
|
m_fileName = src.m_fileName;
|
|
m_lineNumber = src.m_lineNumber;
|
|
m_columnNumber = src.m_columnNumber;
|
|
m_endLineNumber = src.m_endLineNumber;
|
|
m_endColumnNumber = src.m_endColumnNumber;
|
|
m_additionalInfo = src.m_additionalInfo;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
|
|
/// <summary>
|
|
/// Default, empty, file location
|
|
/// </summary>
|
|
public static FileLocation Empty
|
|
{
|
|
get
|
|
{
|
|
return new FileLocation(string.Empty);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// FileName.
|
|
/// </summary>
|
|
public string FileName
|
|
{
|
|
get { return m_fileName; }
|
|
set { m_fileName = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Line number.
|
|
/// </summary>
|
|
public int LineNumber
|
|
{
|
|
get { return m_lineNumber; }
|
|
set
|
|
{
|
|
m_lineNumber = value;
|
|
if (EndLineNumber == 0)
|
|
{
|
|
EndLineNumber = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Column number.
|
|
/// </summary>
|
|
public int ColumnNumber
|
|
{
|
|
get { return m_columnNumber; }
|
|
set
|
|
{
|
|
m_columnNumber = value;
|
|
if (EndColumnNumber == 0)
|
|
{
|
|
EndColumnNumber = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// End line number.
|
|
/// </summary>
|
|
public int EndLineNumber
|
|
{
|
|
get { return m_endLineNumber; }
|
|
set { m_endLineNumber = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// End column number.
|
|
/// </summary>
|
|
public int EndColumnNumber
|
|
{
|
|
get { return m_endColumnNumber; }
|
|
set { m_endColumnNumber = value; }
|
|
}
|
|
|
|
public bool IsEmpty
|
|
{
|
|
get { return string.IsNullOrEmpty(m_fileName); }
|
|
}
|
|
|
|
public string AdditionalInfoDisplayString
|
|
{
|
|
get { return string.Join(", ", EnumerateAdditionalInfo()); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
#region Additional Info
|
|
|
|
/// <summary>
|
|
/// Retrieves additional info about this file location. <see cref="AddInfo"/>.
|
|
/// </summary>
|
|
/// <returns>The first info found of the given type, or null if no info is found of that type.</returns>
|
|
public TInfo GetInfo<TInfo>()
|
|
{
|
|
return EnumerateAdditionalInfo().OfType<TInfo>().FirstOrDefault();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds additional info that can be interpreted by views to provide more context to a file location.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// The info must be serializable.
|
|
/// </remarks>
|
|
/// <example>An actual item in a file, the position of the camera, etc...</example>
|
|
/// <param name="info"></param>
|
|
public void AddInfo(object info)
|
|
{
|
|
var newInfo = new AdditionalInfo(m_additionalInfo, info);
|
|
m_additionalInfo = newInfo;
|
|
}
|
|
|
|
private IEnumerable<object> EnumerateAdditionalInfo()
|
|
{
|
|
for (var node = m_additionalInfo; node != null; node = node.Next)
|
|
{
|
|
yield return node.Info;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Overriden.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override string ToString()
|
|
{
|
|
StringBuilder builder = new StringBuilder();
|
|
if (!string.IsNullOrEmpty(FileName) || LineNumber != 0)
|
|
{
|
|
builder.AppendFormat("{0}", string.IsNullOrEmpty(FileName) ? UnknownFileName : FileName);
|
|
if (LineNumber != 0)
|
|
{
|
|
if (ColumnNumber == 0)
|
|
{
|
|
if (EndLineNumber == LineNumber)
|
|
{
|
|
builder.AppendFormat("({0})", LineNumber);
|
|
}
|
|
else
|
|
{
|
|
builder.AppendFormat("({0}-{1})", LineNumber, EndLineNumber);
|
|
}
|
|
}
|
|
else if (EndLineNumber == LineNumber)
|
|
{
|
|
if (EndColumnNumber == ColumnNumber)
|
|
{
|
|
builder.AppendFormat("({0},{1})", LineNumber, ColumnNumber);
|
|
}
|
|
else
|
|
{
|
|
builder.AppendFormat("({0},{1}-{2})", LineNumber, ColumnNumber, EndColumnNumber);
|
|
}
|
|
}
|
|
else if (EndColumnNumber == ColumnNumber)
|
|
{
|
|
builder.AppendFormat("({0}-{1},{2})", LineNumber, EndLineNumber, ColumnNumber);
|
|
}
|
|
else
|
|
{
|
|
builder.AppendFormat("({0},{1},{2},{3})", LineNumber, ColumnNumber, EndLineNumber, EndColumnNumber);
|
|
}
|
|
}
|
|
}
|
|
|
|
return builder.ToString();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Inner Types
|
|
|
|
[Serializable]
|
|
private class AdditionalInfo
|
|
{
|
|
public readonly AdditionalInfo Next;
|
|
public readonly object Info;
|
|
|
|
public AdditionalInfo(AdditionalInfo next, object info)
|
|
{
|
|
Throw.IfNull(info, "info");
|
|
|
|
Next = next;
|
|
Info = info;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|