@joebigelow / wix / commits / d98126dc

Minor project cleanup

Rob Mensching committed Oct 18, 2018 at 11:21 UTC d98126dc766b9b063d2d26ced62553d4a5a218b5
3 files changed +35 -620
WixToolset.Core.sln
+34
@@ -8,8 +8,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Core.WindowsInst
8 EndProject
9 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Core.Burn", "src\WixToolset.Core.Burn\WixToolset.Core.Burn.csproj", "{BC19D30D-C1B6-46DF-95B3-8EDF688E0FEC}"
10 EndProject
11 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{1284331E-BC6C-426D-AAAF-140C0174F875}"
12 +EndProject
13 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Example.Extension", "src\test\Example.Extension\Example.Extension.csproj", "{C66C2503-C671-4230-8B48-1D93A8532A28}"
14 +EndProject
15 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolsetTest.CoreIntegration", "src\test\WixToolsetTest.CoreIntegration\WixToolsetTest.CoreIntegration.csproj", "{E8A08E86-1780-4ED4-8F63-AB2B52C1C16B}"
16 EndProject
17 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Core.TestPackage", "src\WixToolset.Core.TestPackage\WixToolset.Core.TestPackage.csproj", "{853716DB-C02C-41BD-91BC-79CDC0C17D10}"
18 +EndProject
19 Global
20 GlobalSection(SolutionConfigurationPlatforms) = preSolution
21 Debug|Any CPU = Debug|Any CPU
@@ -56,6 +62,18 @@ Global
62 {BC19D30D-C1B6-46DF-95B3-8EDF688E0FEC}.Release|x64.Build.0 = Release|Any CPU
63 {BC19D30D-C1B6-46DF-95B3-8EDF688E0FEC}.Release|x86.ActiveCfg = Release|Any CPU
64 {BC19D30D-C1B6-46DF-95B3-8EDF688E0FEC}.Release|x86.Build.0 = Release|Any CPU
65 + {C66C2503-C671-4230-8B48-1D93A8532A28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
66 + {C66C2503-C671-4230-8B48-1D93A8532A28}.Debug|Any CPU.Build.0 = Debug|Any CPU
67 + {C66C2503-C671-4230-8B48-1D93A8532A28}.Debug|x64.ActiveCfg = Debug|Any CPU
68 + {C66C2503-C671-4230-8B48-1D93A8532A28}.Debug|x64.Build.0 = Debug|Any CPU
69 + {C66C2503-C671-4230-8B48-1D93A8532A28}.Debug|x86.ActiveCfg = Debug|Any CPU
70 + {C66C2503-C671-4230-8B48-1D93A8532A28}.Debug|x86.Build.0 = Debug|Any CPU
71 + {C66C2503-C671-4230-8B48-1D93A8532A28}.Release|Any CPU.ActiveCfg = Release|Any CPU
72 + {C66C2503-C671-4230-8B48-1D93A8532A28}.Release|Any CPU.Build.0 = Release|Any CPU
73 + {C66C2503-C671-4230-8B48-1D93A8532A28}.Release|x64.ActiveCfg = Release|Any CPU
74 + {C66C2503-C671-4230-8B48-1D93A8532A28}.Release|x64.Build.0 = Release|Any CPU
75 + {C66C2503-C671-4230-8B48-1D93A8532A28}.Release|x86.ActiveCfg = Release|Any CPU
76 + {C66C2503-C671-4230-8B48-1D93A8532A28}.Release|x86.Build.0 = Release|Any CPU
77 {E8A08E86-1780-4ED4-8F63-AB2B52C1C16B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
78 {E8A08E86-1780-4ED4-8F63-AB2B52C1C16B}.Debug|Any CPU.Build.0 = Debug|Any CPU
79 {E8A08E86-1780-4ED4-8F63-AB2B52C1C16B}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -68,10 +86,26 @@ Global
86 {E8A08E86-1780-4ED4-8F63-AB2B52C1C16B}.Release|x64.Build.0 = Release|Any CPU
87 {E8A08E86-1780-4ED4-8F63-AB2B52C1C16B}.Release|x86.ActiveCfg = Release|Any CPU
88 {E8A08E86-1780-4ED4-8F63-AB2B52C1C16B}.Release|x86.Build.0 = Release|Any CPU
89 + {853716DB-C02C-41BD-91BC-79CDC0C17D10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
90 + {853716DB-C02C-41BD-91BC-79CDC0C17D10}.Debug|Any CPU.Build.0 = Debug|Any CPU
91 + {853716DB-C02C-41BD-91BC-79CDC0C17D10}.Debug|x64.ActiveCfg = Debug|Any CPU
92 + {853716DB-C02C-41BD-91BC-79CDC0C17D10}.Debug|x64.Build.0 = Debug|Any CPU
93 + {853716DB-C02C-41BD-91BC-79CDC0C17D10}.Debug|x86.ActiveCfg = Debug|Any CPU
94 + {853716DB-C02C-41BD-91BC-79CDC0C17D10}.Debug|x86.Build.0 = Debug|Any CPU
95 + {853716DB-C02C-41BD-91BC-79CDC0C17D10}.Release|Any CPU.ActiveCfg = Release|Any CPU
96 + {853716DB-C02C-41BD-91BC-79CDC0C17D10}.Release|Any CPU.Build.0 = Release|Any CPU
97 + {853716DB-C02C-41BD-91BC-79CDC0C17D10}.Release|x64.ActiveCfg = Release|Any CPU
98 + {853716DB-C02C-41BD-91BC-79CDC0C17D10}.Release|x64.Build.0 = Release|Any CPU
99 + {853716DB-C02C-41BD-91BC-79CDC0C17D10}.Release|x86.ActiveCfg = Release|Any CPU
100 + {853716DB-C02C-41BD-91BC-79CDC0C17D10}.Release|x86.Build.0 = Release|Any CPU
101 EndGlobalSection
102 GlobalSection(SolutionProperties) = preSolution
103 HideSolutionNode = FALSE
104 EndGlobalSection
105 + GlobalSection(NestedProjects) = preSolution
106 + {C66C2503-C671-4230-8B48-1D93A8532A28} = {1284331E-BC6C-426D-AAAF-140C0174F875}
107 + {E8A08E86-1780-4ED4-8F63-AB2B52C1C16B} = {1284331E-BC6C-426D-AAAF-140C0174F875}
108 + EndGlobalSection
109 GlobalSection(ExtensibilityGlobals) = postSolution
110 SolutionGuid = {BB8820D5-723D-426D-B4A0-4D221603C5FA}
111 EndGlobalSection
src/WixToolset.Core.TestPackage/WixRunnerResult.cs
+1 -1
@@ -15,7 +15,7 @@ namespace WixToolset.Core.TestPackage
15
16 public WixRunnerResult AssertSuccess()
17 {
18 - Assert.True(0 == this.ExitCode, $"MSBuild failed unexpectedly. Output:\r\n{String.Join("\r\n", this.Messages.Select(m => m.ToString()).ToArray())}");
18 + Assert.True(0 == this.ExitCode, $"\r\n\r\nWixRunner failed with exit code: {this.ExitCode}\r\n Output: {String.Join("\r\n ", this.Messages.Select(m => m.ToString()).ToArray())}\r\n");
19 return this;
20 }
21 }
src/WixToolset.Core/Converter.cs deleted
-619
@@ -1,619 +0,0 @@
1 -// 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.
2 -
3 -namespace WixToolset.Core
4 -{
5 - using System;
6 - using System.Collections.Generic;
7 - using System.Globalization;
8 - using System.IO;
9 - using System.Linq;
10 - using System.Xml;
11 - using System.Xml.Linq;
12 - using WixToolset.Data;
13 - using WixToolset.Extensibility.Services;
14 -
15 - /// <summary>
16 - /// WiX source code converter.
17 - /// </summary>
18 - internal class Converter
19 - {
20 - private const string XDocumentNewLine = "\n"; // XDocument normlizes "\r\n" to just "\n".
21 - private static readonly XNamespace WixNamespace = "http://wixtoolset.org/schemas/v4/wxs";
22 -
23 - private static readonly XName FileElementName = WixNamespace + "File";
24 - private static readonly XName ExePackageElementName = WixNamespace + "ExePackage";
25 - private static readonly XName MsiPackageElementName = WixNamespace + "MsiPackage";
26 - private static readonly XName MspPackageElementName = WixNamespace + "MspPackage";
27 - private static readonly XName MsuPackageElementName = WixNamespace + "MsuPackage";
28 - private static readonly XName PayloadElementName = WixNamespace + "Payload";
29 - private static readonly XName WixElementWithoutNamespaceName = XNamespace.None + "Wix";
30 -
31 - private static readonly Dictionary<string, XNamespace> OldToNewNamespaceMapping = new Dictionary<string, XNamespace>()
32 - {
33 - { "http://schemas.microsoft.com/wix/BalExtension", "http://wixtoolset.org/schemas/v4/wxs/bal" },
34 - { "http://schemas.microsoft.com/wix/ComPlusExtension", "http://wixtoolset.org/schemas/v4/wxs/complus" },
35 - { "http://schemas.microsoft.com/wix/DependencyExtension", "http://wixtoolset.org/schemas/v4/wxs/dependency" },
36 - { "http://schemas.microsoft.com/wix/DifxAppExtension", "http://wixtoolset.org/schemas/v4/wxs/difxapp" },
37 - { "http://schemas.microsoft.com/wix/FirewallExtension", "http://wixtoolset.org/schemas/v4/wxs/firewall" },
38 - { "http://schemas.microsoft.com/wix/GamingExtension", "http://wixtoolset.org/schemas/v4/wxs/gaming" },
39 - { "http://schemas.microsoft.com/wix/IIsExtension", "http://wixtoolset.org/schemas/v4/wxs/iis" },
40 - { "http://schemas.microsoft.com/wix/MsmqExtension", "http://wixtoolset.org/schemas/v4/wxs/msmq" },
41 - { "http://schemas.microsoft.com/wix/NetFxExtension", "http://wixtoolset.org/schemas/v4/wxs/netfx" },
42 - { "http://schemas.microsoft.com/wix/PSExtension", "http://wixtoolset.org/schemas/v4/wxs/powershell" },
43 - { "http://schemas.microsoft.com/wix/SqlExtension", "http://wixtoolset.org/schemas/v4/wxs/sql" },
44 - { "http://schemas.microsoft.com/wix/TagExtension", "http://wixtoolset.org/schemas/v4/wxs/tag" },
45 - { "http://schemas.microsoft.com/wix/UtilExtension", "http://wixtoolset.org/schemas/v4/wxs/util" },
46 - { "http://schemas.microsoft.com/wix/VSExtension", "http://wixtoolset.org/schemas/v4/wxs/vs" },
47 - { "http://wixtoolset.org/schemas/thmutil/2010", "http://wixtoolset.org/schemas/v4/thmutil" },
48 - { "http://schemas.microsoft.com/wix/2009/Lux", "http://wixtoolset.org/schemas/v4/lux" },
49 - { "http://schemas.microsoft.com/wix/2006/wi", "http://wixtoolset.org/schemas/v4/wxs" },
50 - { "http://schemas.microsoft.com/wix/2006/localization", "http://wixtoolset.org/schemas/v4/wxl" },
51 - { "http://schemas.microsoft.com/wix/2006/libraries", "http://wixtoolset.org/schemas/v4/wixlib" },
52 - { "http://schemas.microsoft.com/wix/2006/objects", "http://wixtoolset.org/schemas/v4/wixobj" },
53 - { "http://schemas.microsoft.com/wix/2006/outputs", "http://wixtoolset.org/schemas/v4/wixout" },
54 - { "http://schemas.microsoft.com/wix/2007/pdbs", "http://wixtoolset.org/schemas/v4/wixpdb" },
55 - { "http://schemas.microsoft.com/wix/2003/04/actions", "http://wixtoolset.org/schemas/v4/wi/actions" },
56 - { "http://schemas.microsoft.com/wix/2006/tables", "http://wixtoolset.org/schemas/v4/wi/tables" },
57 - { "http://schemas.microsoft.com/wix/2006/WixUnit", "http://wixtoolset.org/schemas/v4/wixunit" },
58 - };
59 -
60 - private Dictionary<XName, Action<XElement>> ConvertElementMapping;
61 -
62 - /// <summary>
63 - /// Instantiate a new Converter class.
64 - /// </summary>
65 - /// <param name="indentationAmount">Indentation value to use when validating leading whitespace.</param>
66 - /// <param name="errorsAsWarnings">Test errors to display as warnings.</param>
67 - /// <param name="ignoreErrors">Test errors to ignore.</param>
68 - internal Converter(IMessaging messaging, int indentationAmount, IEnumerable<string> errorsAsWarnings = null, IEnumerable<string> ignoreErrors = null)
69 - {
70 - this.ConvertElementMapping = new Dictionary<XName, Action<XElement>>()
71 - {
72 - { FileElementName, this.ConvertFileElement },
73 - { ExePackageElementName, this.ConvertSuppressSignatureValidation },
74 - { MsiPackageElementName, this.ConvertSuppressSignatureValidation },
75 - { MspPackageElementName, this.ConvertSuppressSignatureValidation },
76 - { MsuPackageElementName, this.ConvertSuppressSignatureValidation },
77 - { PayloadElementName, this.ConvertSuppressSignatureValidation },
78 - { WixElementWithoutNamespaceName, this.ConvertWixElementWithoutNamespace },
79 - };
80 -
81 - this.Messaging = messaging;
82 -
83 - this.IndentationAmount = indentationAmount;
84 -
85 - this.ErrorsAsWarnings = new HashSet<ConverterTestType>(this.YieldConverterTypes(errorsAsWarnings));
86 -
87 - this.IgnoreErrors = new HashSet<ConverterTestType>(this.YieldConverterTypes(ignoreErrors));
88 - }
89 -
90 - private int Errors { get; set; }
91 -
92 - private HashSet<ConverterTestType> ErrorsAsWarnings { get; set; }
93 -
94 - private HashSet<ConverterTestType> IgnoreErrors { get; set; }
95 -
96 - private IMessaging Messaging { get; }
97 -
98 - private int IndentationAmount { get; set; }
99 -
100 - private string SourceFile { get; set; }
101 -
102 - /// <summary>
103 - /// Convert a file.
104 - /// </summary>
105 - /// <param name="sourceFile">The file to convert.</param>
106 - /// <param name="saveConvertedFile">Option to save the converted errors that are found.</param>
107 - /// <returns>The number of errors found.</returns>
108 - public int ConvertFile(string sourceFile, bool saveConvertedFile)
109 - {
110 - XDocument document;
111 -
112 - // Set the instance info.
113 - this.Errors = 0;
114 - this.SourceFile = sourceFile;
115 -
116 - try
117 - {
118 - document = XDocument.Load(this.SourceFile, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
119 - }
120 - catch (XmlException e)
121 - {
122 - this.OnError(ConverterTestType.XmlException, (XObject)null, "The xml is invalid. Detail: '{0}'", e.Message);
123 -
124 - return this.Errors;
125 - }
126 -
127 - this.ConvertDocument(document);
128 -
129 - // Fix errors if requested and necessary.
130 - if (saveConvertedFile && 0 < this.Errors)
131 - {
132 - try
133 - {
134 - using (StreamWriter writer = File.CreateText(this.SourceFile))
135 - {
136 - document.Save(writer, SaveOptions.DisableFormatting | SaveOptions.OmitDuplicateNamespaces);
137 - }
138 - }
139 - catch (UnauthorizedAccessException)
140 - {
141 - this.OnError(ConverterTestType.UnauthorizedAccessException, (XObject)null, "Could not write to file.");
142 - }
143 - }
144 -
145 - return this.Errors;
146 - }
147 -
148 - /// <summary>
149 - /// Convert a document.
150 - /// </summary>
151 - /// <param name="document">The document to convert.</param>
152 - /// <returns>The number of errors found.</returns>
153 - public int ConvertDocument(XDocument document)
154 - {
155 - XDeclaration declaration = document.Declaration;
156 -
157 - // Convert the declaration.
158 - if (null != declaration)
159 - {
160 - if (!String.Equals("utf-8", declaration.Encoding, StringComparison.OrdinalIgnoreCase))
161 - {
162 - if (this.OnError(ConverterTestType.DeclarationEncodingWrong, document.Root, "The XML declaration encoding is not properly set to 'utf-8'."))
163 - {
164 - declaration.Encoding = "utf-8";
165 - }
166 - }
167 - }
168 - else // missing declaration
169 - {
170 - if (this.OnError(ConverterTestType.DeclarationMissing, (XNode)null, "This file is missing an XML declaration on the first line."))
171 - {
172 - document.Declaration = new XDeclaration("1.0", "utf-8", null);
173 - document.Root.AddBeforeSelf(new XText(XDocumentNewLine));
174 - }
175 - }
176 -
177 - // Start converting the nodes at the top.
178 - this.ConvertNode(document.Root, 0);
179 -
180 - return this.Errors;
181 - }
182 -
183 - /// <summary>
184 - /// Convert a single xml node.
185 - /// </summary>
186 - /// <param name="node">The node to convert.</param>
187 - /// <param name="level">The depth level of the node.</param>
188 - /// <returns>The converted node.</returns>
189 - private void ConvertNode(XNode node, int level)
190 - {
191 - // Convert this node's whitespace.
192 - if ((XmlNodeType.Comment == node.NodeType && 0 > ((XComment)node).Value.IndexOf(XDocumentNewLine, StringComparison.Ordinal)) ||
193 - XmlNodeType.CDATA == node.NodeType || XmlNodeType.Element == node.NodeType || XmlNodeType.ProcessingInstruction == node.NodeType)
194 - {
195 - this.ConvertWhitespace(node, level);
196 - }
197 -
198 - // Convert this node if it is an element.
199 - XElement element = node as XElement;
200 -
201 - if (null != element)
202 - {
203 - this.ConvertElement(element);
204 -
205 - // Convert all children of this element.
206 - IEnumerable<XNode> children = element.Nodes().ToList();
207 -
208 - foreach (XNode child in children)
209 - {
210 - this.ConvertNode(child, level + 1);
211 - }
212 - }
213 - }
214 -
215 - private void ConvertElement(XElement element)
216 - {
217 - // Gather any deprecated namespaces, then update this element tree based on those deprecations.
218 - Dictionary<XNamespace, XNamespace> deprecatedToUpdatedNamespaces = new Dictionary<XNamespace, XNamespace>();
219 -
220 - foreach (XAttribute declaration in element.Attributes().Where(a => a.IsNamespaceDeclaration))
221 - {
222 - XNamespace ns;
223 -
224 - if (Converter.OldToNewNamespaceMapping.TryGetValue(declaration.Value, out ns))
225 - {
226 - if (this.OnError(ConverterTestType.XmlnsValueWrong, declaration, "The namespace '{0}' is out of date. It must be '{1}'.", declaration.Value, ns.NamespaceName))
227 - {
228 - deprecatedToUpdatedNamespaces.Add(declaration.Value, ns);
229 - }
230 - }
231 - }
232 -
233 - if (deprecatedToUpdatedNamespaces.Any())
234 - {
235 - Converter.UpdateElementsWithDeprecatedNamespaces(element.DescendantsAndSelf(), deprecatedToUpdatedNamespaces);
236 - }
237 -
238 - // Convert the node in much greater detail.
239 - Action<XElement> convert;
240 -
241 - if (this.ConvertElementMapping.TryGetValue(element.Name, out convert))
242 - {
243 - convert(element);
244 - }
245 - }
246 -
247 - private void ConvertFileElement(XElement element)
248 - {
249 - if (null == element.Attribute("Id"))
250 - {
251 - XAttribute attribute = element.Attribute("Name");
252 -
253 - if (null == attribute)
254 - {
255 - attribute = element.Attribute("Source");
256 - }
257 -
258 - if (null != attribute)
259 - {
260 - string name = Path.GetFileName(attribute.Value);
261 -
262 - if (this.OnError(ConverterTestType.AssignAnonymousFileId, element, "The file id is being updated to '{0}' to ensure it remains the same as the default", name))
263 - {
264 - IEnumerable<XAttribute> attributes = element.Attributes().ToList();
265 - element.RemoveAttributes();
266 - element.Add(new XAttribute("Id", Common.GetIdentifierFromName(name)));
267 - element.Add(attributes);
268 - }
269 - }
270 - }
271 - }
272 -
273 - private void ConvertSuppressSignatureValidation(XElement element)
274 - {
275 - XAttribute suppressSignatureValidation = element.Attribute("SuppressSignatureValidation");
276 -
277 - if (null != suppressSignatureValidation)
278 - {
279 - if (this.OnError(ConverterTestType.SuppressSignatureValidationDeprecated, element, "The chain package element contains deprecated '{0}' attribute. Use the 'EnableSignatureValidation' instead.", suppressSignatureValidation))
280 - {
281 - if ("no" == suppressSignatureValidation.Value)
282 - {
283 - element.Add(new XAttribute("EnableSignatureValidation", "yes"));
284 - }
285 - }
286 -
287 - suppressSignatureValidation.Remove();
288 - }
289 - }
290 -
291 - /// <summary>
292 - /// Converts a Wix element.
293 - /// </summary>
294 - /// <param name="element">The Wix element to convert.</param>
295 - /// <returns>The converted element.</returns>
296 - private void ConvertWixElementWithoutNamespace(XElement element)
297 - {
298 - if (this.OnError(ConverterTestType.XmlnsMissing, element, "The xmlns attribute is missing. It must be present with a value of '{0}'.", WixNamespace.NamespaceName))
299 - {
300 - element.Name = WixNamespace.GetName(element.Name.LocalName);
301 -
302 - element.Add(new XAttribute("xmlns", WixNamespace.NamespaceName)); // set the default namespace.
303 -
304 - foreach (XElement elementWithoutNamespace in element.Elements().Where(e => XNamespace.None == e.Name.Namespace))
305 - {
306 - elementWithoutNamespace.Name = WixNamespace.GetName(elementWithoutNamespace.Name.LocalName);
307 - }
308 - }
309 - }
310 -
311 - /// <summary>
312 - /// Convert the whitespace adjacent to a node.
313 - /// </summary>
314 - /// <param name="node">The node to convert.</param>
315 - /// <param name="level">The depth level of the node.</param>
316 - private void ConvertWhitespace(XNode node, int level)
317 - {
318 - // Fix the whitespace before this node.
319 - XText whitespace = node.PreviousNode as XText;
320 -
321 - if (null != whitespace)
322 - {
323 - if (XmlNodeType.CDATA == node.NodeType)
324 - {
325 - if (this.OnError(ConverterTestType.WhitespacePrecedingCDATAWrong, node, "There should be no whitespace preceding a CDATA node."))
326 - {
327 - whitespace.Remove();
328 - }
329 - }
330 - else
331 - {
332 - if (!Converter.IsLegalWhitespace(this.IndentationAmount, level, whitespace.Value))
333 - {
334 - if (this.OnError(ConverterTestType.WhitespacePrecedingNodeWrong, node, "The whitespace preceding this node is incorrect."))
335 - {
336 - Converter.FixWhitespace(this.IndentationAmount, level, whitespace);
337 - }
338 - }
339 - }
340 - }
341 -
342 - // Fix the whitespace after CDATA nodes.
343 - XCData cdata = node as XCData;
344 -
345 - if (null != cdata)
346 - {
347 - whitespace = cdata.NextNode as XText;
348 -
349 - if (null != whitespace)
350 - {
351 - if (this.OnError(ConverterTestType.WhitespaceFollowingCDATAWrong, node, "There should be no whitespace following a CDATA node."))
352 - {
353 - whitespace.Remove();
354 - }
355 - }
356 - }
357 - else
358 - {
359 - // Fix the whitespace inside and after this node (except for Error which may contain just whitespace).
360 - XElement element = node as XElement;
361 -
362 - if (null != element && "Error" != element.Name.LocalName)
363 - {
364 - if (!element.HasElements && !element.IsEmpty && String.IsNullOrEmpty(element.Value.Trim()))
365 - {
366 - if (this.OnError(ConverterTestType.NotEmptyElement, element, "This should be an empty element since it contains nothing but whitespace."))
367 - {
368 - element.RemoveNodes();
369 - }
370 - }
371 -
372 - whitespace = node.NextNode as XText;
373 -
374 - if (null != whitespace)
375 - {
376 - if (!Converter.IsLegalWhitespace(this.IndentationAmount, level - 1, whitespace.Value))
377 - {
378 - if (this.OnError(ConverterTestType.WhitespacePrecedingEndElementWrong, whitespace, "The whitespace preceding this end element is incorrect."))
379 - {
380 - Converter.FixWhitespace(this.IndentationAmount, level - 1, whitespace);
381 - }
382 - }
383 - }
384 - }
385 - }
386 - }
387 -
388 - private IEnumerable<ConverterTestType> YieldConverterTypes(IEnumerable<string> types)
389 - {
390 - if (null != types)
391 - {
392 - foreach (string type in types)
393 - {
394 - ConverterTestType itt;
395 -
396 - if (Enum.TryParse<ConverterTestType>(type, true, out itt))
397 - {
398 - yield return itt;
399 - }
400 - else // not a known ConverterTestType
401 - {
402 - this.OnError(ConverterTestType.ConverterTestTypeUnknown, (XObject)null, "Unknown error type: '{0}'.", type);
403 - }
404 - }
405 - }
406 - }
407 -
408 - private static void UpdateElementsWithDeprecatedNamespaces(IEnumerable<XElement> elements, Dictionary<XNamespace, XNamespace> deprecatedToUpdatedNamespaces)
409 - {
410 - foreach (XElement element in elements)
411 - {
412 - XNamespace ns;
413 -
414 - if (deprecatedToUpdatedNamespaces.TryGetValue(element.Name.Namespace, out ns))
415 - {
416 - element.Name = ns.GetName(element.Name.LocalName);
417 - }
418 -
419 - // Remove all the attributes and add them back to with their namespace updated (as necessary).
420 - IEnumerable<XAttribute> attributes = element.Attributes().ToList();
421 - element.RemoveAttributes();
422 -
423 - foreach (XAttribute attribute in attributes)
424 - {
425 - XAttribute convertedAttribute = attribute;
426 -
427 - if (attribute.IsNamespaceDeclaration)
428 - {
429 - if (deprecatedToUpdatedNamespaces.TryGetValue(attribute.Value, out ns))
430 - {
431 - convertedAttribute = ("xmlns" == attribute.Name.LocalName) ? new XAttribute(attribute.Name.LocalName, ns.NamespaceName) : new XAttribute(XNamespace.Xmlns + attribute.Name.LocalName, ns.NamespaceName);
432 - }
433 - }
434 - else if (deprecatedToUpdatedNamespaces.TryGetValue(attribute.Name.Namespace, out ns))
435 - {
436 - convertedAttribute = new XAttribute(ns.GetName(attribute.Name.LocalName), attribute.Value);
437 - }
438 -
439 - element.Add(convertedAttribute);
440 - }
441 - }
442 - }
443 -
444 - /// <summary>
445 - /// Determine if the whitespace preceding a node is appropriate for its depth level.
446 - /// </summary>
447 - /// <param name="indentationAmount">Indentation value to use when validating leading whitespace.</param>
448 - /// <param name="level">The depth level that should match this whitespace.</param>
449 - /// <param name="whitespace">The whitespace to validate.</param>
450 - /// <returns>true if the whitespace is legal; false otherwise.</returns>
451 - private static bool IsLegalWhitespace(int indentationAmount, int level, string whitespace)
452 - {
453 - // strip off leading newlines; there can be an arbitrary number of these
454 - while (whitespace.StartsWith(XDocumentNewLine, StringComparison.Ordinal))
455 - {
456 - whitespace = whitespace.Substring(XDocumentNewLine.Length);
457 - }
458 -
459 - // check the length
460 - if (whitespace.Length != level * indentationAmount)
461 - {
462 - return false;
463 - }
464 -
465 - // check the spaces
466 - foreach (char character in whitespace)
467 - {
468 - if (' ' != character)
469 - {
470 - return false;
471 - }
472 - }
473 -
474 - return true;
475 - }
476 -
477 - /// <summary>
478 - /// Fix the whitespace in a Whitespace node.
479 - /// </summary>
480 - /// <param name="indentationAmount">Indentation value to use when validating leading whitespace.</param>
481 - /// <param name="level">The depth level of the desired whitespace.</param>
482 - /// <param name="whitespace">The whitespace node to fix.</param>
483 - private static void FixWhitespace(int indentationAmount, int level, XText whitespace)
484 - {
485 - int newLineCount = 0;
486 -
487 - for (int i = 0; i + 1 < whitespace.Value.Length; ++i)
488 - {
489 - if (XDocumentNewLine == whitespace.Value.Substring(i, 2))
490 - {
491 - ++i; // skip an extra character
492 - ++newLineCount;
493 - }
494 - }
495 -
496 - if (0 == newLineCount)
497 - {
498 - newLineCount = 1;
499 - }
500 -
501 - // reset the whitespace value
502 - whitespace.Value = String.Empty;
503 -
504 - // add the correct number of newlines
505 - for (int i = 0; i < newLineCount; ++i)
506 - {
507 - whitespace.Value = String.Concat(whitespace.Value, XDocumentNewLine);
508 - }
509 -
510 - // add the correct number of spaces based on configured indentation amount
511 - whitespace.Value = String.Concat(whitespace.Value, new string(' ', level * indentationAmount));
512 - }
513 -
514 - /// <summary>
515 - /// Output an error message to the console.
516 - /// </summary>
517 - /// <param name="converterTestType">The type of converter test.</param>
518 - /// <param name="node">The node that caused the error.</param>
519 - /// <param name="message">Detailed error message.</param>
520 - /// <param name="args">Additional formatted string arguments.</param>
521 - /// <returns>Returns true indicating that action should be taken on this error, and false if it should be ignored.</returns>
522 - private bool OnError(ConverterTestType converterTestType, XObject node, string message, params object[] args)
523 - {
524 - if (this.IgnoreErrors.Contains(converterTestType)) // ignore the error
525 - {
526 - return false;
527 - }
528 -
529 - // Increase the error count.
530 - this.Errors++;
531 -
532 - SourceLineNumber sourceLine = (null == node) ? new SourceLineNumber(this.SourceFile ?? "wixcop.exe") : new SourceLineNumber(this.SourceFile, ((IXmlLineInfo)node).LineNumber);
533 - bool warning = this.ErrorsAsWarnings.Contains(converterTestType);
534 - string display = String.Format(CultureInfo.CurrentCulture, message, args);
535 -
536 - var msg = new Message(sourceLine, warning ? MessageLevel.Warning : MessageLevel.Error, (int)converterTestType, "{0} ({1})", display, converterTestType.ToString());
537 -
538 - this.Messaging.Write(msg);
539 -
540 - return true;
541 - }
542 -
543 - /// <summary>
544 - /// Converter test types. These are used to condition error messages down to warnings.
545 - /// </summary>
546 - private enum ConverterTestType
547 - {
548 - /// <summary>
549 - /// Internal-only: displayed when a string cannot be converted to an ConverterTestType.
550 - /// </summary>
551 - ConverterTestTypeUnknown,
552 -
553 - /// <summary>
554 - /// Displayed when an XML loading exception has occurred.
555 - /// </summary>
556 - XmlException,
557 -
558 - /// <summary>
559 - /// Displayed when a file cannot be accessed; typically when trying to save back a fixed file.
560 - /// </summary>
561 - UnauthorizedAccessException,
562 -
563 - /// <summary>
564 - /// Displayed when the encoding attribute in the XML declaration is not 'UTF-8'.
565 - /// </summary>
566 - DeclarationEncodingWrong,
567 -
568 - /// <summary>
569 - /// Displayed when the XML declaration is missing from the source file.
570 - /// </summary>
571 - DeclarationMissing,
572 -
573 - /// <summary>
574 - /// Displayed when the whitespace preceding a CDATA node is wrong.
575 - /// </summary>
576 - WhitespacePrecedingCDATAWrong,
577 -
578 - /// <summary>
579 - /// Displayed when the whitespace preceding a node is wrong.
580 - /// </summary>
581 - WhitespacePrecedingNodeWrong,
582 -
583 - /// <summary>
584 - /// Displayed when an element is not empty as it should be.
585 - /// </summary>
586 - NotEmptyElement,
587 -
588 - /// <summary>
589 - /// Displayed when the whitespace following a CDATA node is wrong.
590 - /// </summary>
591 - WhitespaceFollowingCDATAWrong,
592 -
593 - /// <summary>
594 - /// Displayed when the whitespace preceding an end element is wrong.
595 - /// </summary>
596 - WhitespacePrecedingEndElementWrong,
597 -
598 - /// <summary>
599 - /// Displayed when the xmlns attribute is missing from the document element.
600 - /// </summary>
601 - XmlnsMissing,
602 -
603 - /// <summary>
604 - /// Displayed when the xmlns attribute on the document element is wrong.
605 - /// </summary>
606 - XmlnsValueWrong,
607 -
608 - /// <summary>
609 - /// Assign an identifier to a File element when on Id attribute is specified.
610 - /// </summary>
611 - AssignAnonymousFileId,
612 -
613 - /// <summary>
614 - /// SuppressSignatureValidation attribute is deprecated and replaced with EnableSignatureValidation.
615 - /// </summary>
616 - SuppressSignatureValidationDeprecated,
617 - }
618 - }
619 -}