diff options
| author | Rob Mensching <rob@firegiant.com> | 2021-03-01 23:23:37 -0800 |
|---|---|---|
| committer | Rob Mensching <rob@firegiant.com> | 2021-03-02 01:54:57 -0800 |
| commit | 73bd35f56189da4e9f5aaf4625247078e0486887 (patch) | |
| tree | af8d1256055a54e15148063a0dac14ad4d4c1e5a | |
| parent | a96d1a916bfcf35f77d48f70215d62b298bfb933 (diff) | |
| download | wix-73bd35f56189da4e9f5aaf4625247078e0486887.tar.gz wix-73bd35f56189da4e9f5aaf4625247078e0486887.tar.bz2 wix-73bd35f56189da4e9f5aaf4625247078e0486887.zip | |
Optimize SourceLineNumber and add support for setting Parent
| -rw-r--r-- | src/WixToolset.Data/SourceLineNumber.cs | 123 |
1 files changed, 80 insertions, 43 deletions
diff --git a/src/WixToolset.Data/SourceLineNumber.cs b/src/WixToolset.Data/SourceLineNumber.cs index 8ec65201..970f17e7 100644 --- a/src/WixToolset.Data/SourceLineNumber.cs +++ b/src/WixToolset.Data/SourceLineNumber.cs | |||
| @@ -35,10 +35,34 @@ namespace WixToolset.Data | |||
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | /// <summary> | 37 | /// <summary> |
| 38 | /// Constructor for a source with a parent and no line information. | ||
| 39 | /// </summary> | ||
| 40 | /// <param name="fileName">File name of the source.</param> | ||
| 41 | /// <param name="parent">Parent of this source line number</param> | ||
| 42 | public SourceLineNumber(string fileName, SourceLineNumber parent) | ||
| 43 | { | ||
| 44 | this.FileName = fileName; | ||
| 45 | this.Parent = parent; | ||
| 46 | } | ||
| 47 | |||
| 48 | /// <summary> | ||
| 49 | /// Constructor for a source with a parent and line information. | ||
| 50 | /// </summary> | ||
| 51 | /// <param name="fileName">File name of the source.</param> | ||
| 52 | /// <param name="parent">Parent of this source line number</param> | ||
| 53 | /// <param name="lineNumber">Line number of the source.</param> | ||
| 54 | public SourceLineNumber(string fileName, SourceLineNumber parent, int lineNumber) | ||
| 55 | { | ||
| 56 | this.FileName = fileName; | ||
| 57 | this.Parent = parent; | ||
| 58 | this.LineNumber = lineNumber; | ||
| 59 | } | ||
| 60 | |||
| 61 | /// <summary> | ||
| 38 | /// Gets the file name of the source. | 62 | /// Gets the file name of the source. |
| 39 | /// </summary> | 63 | /// </summary> |
| 40 | /// <value>File name for the source.</value> | 64 | /// <value>File name for the source.</value> |
| 41 | public string FileName { get; private set; } | 65 | public string FileName { get; } |
| 42 | 66 | ||
| 43 | /// <summary> | 67 | /// <summary> |
| 44 | /// Gets or sets the line number of the source. | 68 | /// Gets or sets the line number of the source. |
| @@ -49,19 +73,13 @@ namespace WixToolset.Data | |||
| 49 | /// <summary> | 73 | /// <summary> |
| 50 | /// Gets or sets the parent source line number that included this source line number. | 74 | /// Gets or sets the parent source line number that included this source line number. |
| 51 | /// </summary> | 75 | /// </summary> |
| 52 | public SourceLineNumber Parent { get; set; } | 76 | public SourceLineNumber Parent { get; private set; } |
| 53 | 77 | ||
| 54 | /// <summary> | 78 | /// <summary> |
| 55 | /// Gets the file name and line information. | 79 | /// Gets the file name and line information. |
| 56 | /// </summary> | 80 | /// </summary> |
| 57 | /// <value>File name and line information.</value> | 81 | /// <value>File name and line information.</value> |
| 58 | public string QualifiedFileName | 82 | public string QualifiedFileName => this.LineNumber.HasValue ? String.Concat(this.FileName, "*", this.LineNumber) : this.FileName; |
| 59 | { | ||
| 60 | get | ||
| 61 | { | ||
| 62 | return this.LineNumber.HasValue ? String.Concat(this.FileName, "*", this.LineNumber) : this.FileName; | ||
| 63 | } | ||
| 64 | } | ||
| 65 | 83 | ||
| 66 | internal static SourceLineNumber Deserialize(JsonObject jsonObject) | 84 | internal static SourceLineNumber Deserialize(JsonObject jsonObject) |
| 67 | { | 85 | { |
| @@ -101,37 +119,46 @@ namespace WixToolset.Data | |||
| 101 | /// <param name="encodedSourceLineNumbers">Encoded string to parse.</param> | 119 | /// <param name="encodedSourceLineNumbers">Encoded string to parse.</param> |
| 102 | public static SourceLineNumber CreateFromEncoded(string encodedSourceLineNumbers) | 120 | public static SourceLineNumber CreateFromEncoded(string encodedSourceLineNumbers) |
| 103 | { | 121 | { |
| 104 | string[] linesSplit = encodedSourceLineNumbers.Split('|'); | 122 | var linesSplitIndex = encodedSourceLineNumbers.IndexOf('|'); |
| 105 | 123 | ||
| 106 | SourceLineNumber first = null; | 124 | // The most common case is that there is a single encoded line, |
| 107 | SourceLineNumber parent = null; | 125 | // so optimize for that case. |
| 108 | for (int i = 0; i < linesSplit.Length; ++i) | 126 | if (linesSplitIndex < 0) |
| 109 | { | 127 | { |
| 110 | string[] filenameSplit = linesSplit[i].Split('*'); | 128 | return DecodeSourceLineNumber(encodedSourceLineNumbers, 0, -1); |
| 111 | SourceLineNumber source; | 129 | } |
| 112 | 130 | else // decode the multiple lines. | |
| 113 | if (2 == filenameSplit.Length) | 131 | { |
| 114 | { | 132 | var startLine = 0; |
| 115 | source = new SourceLineNumber(filenameSplit[0], Convert.ToInt32(filenameSplit[1])); | ||
| 116 | } | ||
| 117 | else | ||
| 118 | { | ||
| 119 | source = new SourceLineNumber(filenameSplit[0]); | ||
| 120 | } | ||
| 121 | 133 | ||
| 122 | if (null != parent) | 134 | SourceLineNumber first = null; |
| 135 | SourceLineNumber parent = null; | ||
| 136 | while (startLine < encodedSourceLineNumbers.Length) | ||
| 123 | { | 137 | { |
| 124 | parent.Parent = source; | 138 | var source = DecodeSourceLineNumber(encodedSourceLineNumbers, startLine, linesSplitIndex - 1); |
| 139 | |||
| 140 | if (null != parent) | ||
| 141 | { | ||
| 142 | parent.Parent = source; | ||
| 143 | } | ||
| 144 | |||
| 145 | parent = source; | ||
| 146 | if (null == first) | ||
| 147 | { | ||
| 148 | first = parent; | ||
| 149 | } | ||
| 150 | |||
| 151 | if (linesSplitIndex < 0) | ||
| 152 | { | ||
| 153 | break; | ||
| 154 | } | ||
| 155 | |||
| 156 | startLine = linesSplitIndex + 1; | ||
| 157 | linesSplitIndex = encodedSourceLineNumbers.IndexOf('|', startLine); | ||
| 125 | } | 158 | } |
| 126 | 159 | ||
| 127 | parent = source; | 160 | return first; |
| 128 | if (null == first) | ||
| 129 | { | ||
| 130 | first = parent; | ||
| 131 | } | ||
| 132 | } | 161 | } |
| 133 | |||
| 134 | return first; | ||
| 135 | } | 162 | } |
| 136 | 163 | ||
| 137 | /// <summary> | 164 | /// <summary> |
| @@ -159,11 +186,8 @@ namespace WixToolset.Data | |||
| 159 | /// <param name="offset">Optional line number offset into XML file not already included in the line information.</param> | 186 | /// <param name="offset">Optional line number offset into XML file not already included in the line information.</param> |
| 160 | public static SourceLineNumber CreateFromXObject(XObject node, int offset = 0) | 187 | public static SourceLineNumber CreateFromXObject(XObject node, int offset = 0) |
| 161 | { | 188 | { |
| 162 | string uri = node.BaseUri; | 189 | var result = CreateFromUri(node.BaseUri); |
| 163 | IXmlLineInfo lineInfo = node as IXmlLineInfo; | 190 | if (null != result && node is IXmlLineInfo lineInfo) |
| 164 | |||
| 165 | SourceLineNumber result = CreateFromUri(uri); | ||
| 166 | if (null != result && null != lineInfo) | ||
| 167 | { | 191 | { |
| 168 | result.LineNumber = lineInfo.LineNumber + offset; | 192 | result.LineNumber = lineInfo.LineNumber + offset; |
| 169 | } | 193 | } |
| @@ -191,12 +215,12 @@ namespace WixToolset.Data | |||
| 191 | /// </summary> | 215 | /// </summary> |
| 192 | public string GetEncoded() | 216 | public string GetEncoded() |
| 193 | { | 217 | { |
| 194 | StringBuilder sb = new StringBuilder(this.QualifiedFileName); | 218 | var sb = new StringBuilder(this.QualifiedFileName); |
| 195 | 219 | ||
| 196 | for (SourceLineNumber source = this.Parent; null != source; source = source.Parent) | 220 | for (var parent = this.Parent; null != parent; parent = parent.Parent) |
| 197 | { | 221 | { |
| 198 | sb.Append("|"); | 222 | sb.Append("|"); |
| 199 | sb.Append(source.QualifiedFileName); | 223 | sb.Append(parent.QualifiedFileName); |
| 200 | } | 224 | } |
| 201 | 225 | ||
| 202 | return sb.ToString(); | 226 | return sb.ToString(); |
| @@ -209,8 +233,7 @@ namespace WixToolset.Data | |||
| 209 | /// <returns>True if SourceLineNumbers are equivalent.</returns> | 233 | /// <returns>True if SourceLineNumbers are equivalent.</returns> |
| 210 | public override bool Equals(object obj) | 234 | public override bool Equals(object obj) |
| 211 | { | 235 | { |
| 212 | SourceLineNumber other = obj as SourceLineNumber; | 236 | return obj is SourceLineNumber other && |
| 213 | return null != other && | ||
| 214 | this.LineNumber.HasValue == other.LineNumber.HasValue && | 237 | this.LineNumber.HasValue == other.LineNumber.HasValue && |
| 215 | (!this.LineNumber.HasValue || this.LineNumber == other.LineNumber) && | 238 | (!this.LineNumber.HasValue || this.LineNumber == other.LineNumber) && |
| 216 | this.FileName.Equals(other.FileName, StringComparison.OrdinalIgnoreCase) && | 239 | this.FileName.Equals(other.FileName, StringComparison.OrdinalIgnoreCase) && |
| @@ -234,5 +257,19 @@ namespace WixToolset.Data | |||
| 234 | { | 257 | { |
| 235 | return this.LineNumber.HasValue && !String.IsNullOrEmpty(this.FileName) ? String.Concat(this.FileName, "(", this.LineNumber, ")") : this.FileName ?? String.Empty; | 258 | return this.LineNumber.HasValue && !String.IsNullOrEmpty(this.FileName) ? String.Concat(this.FileName, "(", this.LineNumber, ")") : this.FileName ?? String.Empty; |
| 236 | } | 259 | } |
| 260 | |||
| 261 | private static SourceLineNumber DecodeSourceLineNumber(string encoded, int startIndex, int endIndex) | ||
| 262 | { | ||
| 263 | if (endIndex < 0) | ||
| 264 | { | ||
| 265 | endIndex = encoded.Length - 1; | ||
| 266 | } | ||
| 267 | |||
| 268 | var count = endIndex - startIndex; | ||
| 269 | var filenameSplitIndex = encoded.LastIndexOf('*', endIndex - 1, count); | ||
| 270 | return (filenameSplitIndex < 0) ? new SourceLineNumber(encoded) : | ||
| 271 | new SourceLineNumber(encoded.Substring(startIndex, filenameSplitIndex - startIndex), | ||
| 272 | Convert.ToInt32(encoded.Substring(filenameSplitIndex + 1, endIndex - filenameSplitIndex))); | ||
| 273 | } | ||
| 237 | } | 274 | } |
| 238 | } | 275 | } |
