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
-}