From 4ebc33174c02e1c9f5693b5ef38ecfe3292c687f Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Fri, 11 Aug 2017 00:39:04 -0700 Subject: Move to .NET Core 2.0 --- src/WixToolset.Data/SourceLineNumber.cs | 205 ++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 src/WixToolset.Data/SourceLineNumber.cs (limited to 'src/WixToolset.Data/SourceLineNumber.cs') diff --git a/src/WixToolset.Data/SourceLineNumber.cs b/src/WixToolset.Data/SourceLineNumber.cs new file mode 100644 index 00000000..87a36132 --- /dev/null +++ b/src/WixToolset.Data/SourceLineNumber.cs @@ -0,0 +1,205 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Data +{ + using System; + using System.IO; + using System.Text; + using System.Xml; + using System.Xml.Linq; + + /// + /// Represents file name and line number for source file + /// + public sealed class SourceLineNumber + { + /// + /// Constructor for a source with no line information. + /// + /// File name of the source. + public SourceLineNumber(string fileName) + { + this.FileName = fileName; + } + + /// + /// Constructor for a source with line information. + /// + /// File name of the source. + /// Line number of the source. + public SourceLineNumber(string fileName, int lineNumber) + { + this.FileName = fileName; + this.LineNumber = lineNumber; + } + + /// + /// Gets the file name of the source. + /// + /// File name for the source. + public string FileName { get; private set; } + + /// + /// Gets or sets the line number of the source. + /// + /// Line number of the source. + public int? LineNumber { get; set; } + + /// + /// Gets or sets the parent source line number that included this source line number. + /// + public SourceLineNumber Parent { get; set; } + + /// + /// Gets the file name and line information. + /// + /// File name and line information. + public string QualifiedFileName + { + get + { + return this.LineNumber.HasValue ? String.Concat(this.FileName, "*", this.LineNumber) : this.FileName; + } + } + + /// + /// Creates a source line number from an encoded string. + /// + /// Encoded string to parse. + public static SourceLineNumber CreateFromEncoded(string encodedSourceLineNumbers) + { + string[] linesSplit = encodedSourceLineNumbers.Split('|'); + + SourceLineNumber first = null; + SourceLineNumber parent = null; + for (int i = 0; i < linesSplit.Length; ++i) + { + string[] filenameSplit = linesSplit[i].Split('*'); + SourceLineNumber source; + + if (2 == filenameSplit.Length) + { + source = new SourceLineNumber(filenameSplit[0], Convert.ToInt32(filenameSplit[1])); + } + else + { + source = new SourceLineNumber(filenameSplit[0]); + } + + if (null != parent) + { + parent.Parent = source; + } + + parent = source; + if (null == first) + { + first = parent; + } + } + + return first; + } + + /// + /// Creates a source line number from a URI. + /// + /// Uri to convert into source line number + public static SourceLineNumber CreateFromUri(string uri) + { + if (String.IsNullOrEmpty(uri)) + { + return null; + } + + // make the local path look like a normal local path + string localPath = new Uri(uri).LocalPath; + localPath = localPath.TrimStart(Path.AltDirectorySeparatorChar).Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); + + return new SourceLineNumber(localPath); + } + + /// + /// Creates a source line number from an XObject. + /// + /// XML node to create source line number from. + /// Optional line number offset into XML file not already included in the line information. + public static SourceLineNumber CreateFromXObject(XObject node, int offset = 0) + { + string uri = node.BaseUri; + IXmlLineInfo lineInfo = node as IXmlLineInfo; + + SourceLineNumber result = CreateFromUri(uri); + if (null != result && null != lineInfo) + { + result.LineNumber = lineInfo.LineNumber + offset; + } + + return result; + } + + /// + /// Get the source line information for the current element. Typically this information + /// is set by the precompiler for each element that it encounters. + /// + /// Element to get source line information for. + /// + /// The source line number used to author the element being processed or + /// null if the preprocessor did not process the element or the node is + /// not an element. + /// + public static SourceLineNumber GetFromXAnnotation(XObject node) + { + return node.Annotation(); + } + + /// + /// Returns the SourceLineNumber and parents encoded as a string. + /// + public string GetEncoded() + { + StringBuilder sb = new StringBuilder(this.QualifiedFileName); + + for (SourceLineNumber source = this.Parent; null != source; source = source.Parent) + { + sb.Append("|"); + sb.Append(source.QualifiedFileName); + } + + return sb.ToString(); + } + + /// + /// Determines if two SourceLineNumbers are equivalent. + /// + /// Object to compare. + /// True if SourceLineNumbers are equivalent. + public override bool Equals(object obj) + { + SourceLineNumber other = obj as SourceLineNumber; + return null != other && + this.LineNumber.HasValue == other.LineNumber.HasValue && + (!this.LineNumber.HasValue || this.LineNumber == other.LineNumber) && + this.FileName.Equals(other.FileName, StringComparison.OrdinalIgnoreCase) && + (null == this.Parent && null == other.Parent || this.Parent.Equals(other.Parent)); + } + + /// + /// Serves as a hash code for a particular type. + /// + /// The hash code. + public override int GetHashCode() + { + return this.GetEncoded().GetHashCode(); + } + + /// + /// Shows a string representation of a source line number. + /// + /// String representation of a source line number. + public override string ToString() + { + return this.LineNumber.HasValue && !String.IsNullOrEmpty(this.FileName) ? String.Concat(this.FileName, "(", this.LineNumber, ")") : this.FileName ?? String.Empty; + } + } +} -- cgit v1.2.3-55-g6feb