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 /src | |
parent | a96d1a916bfcf35f77d48f70215d62b298bfb933 (diff) | |
download | wix-73bd35f56189da4e9f5aaf4625247078e0486887.tar.gz wix-73bd35f56189da4e9f5aaf4625247078e0486887.tar.bz2 wix-73bd35f56189da4e9f5aaf4625247078e0486887.zip |
Optimize SourceLineNumber and add support for setting Parent
Diffstat (limited to 'src')
-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 | } |