diff options
author | Rob Mensching <rob@firegiant.com> | 2017-11-14 23:21:52 -0800 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2017-11-14 23:21:52 -0800 |
commit | aa6f15ec4998a77622fafe9c510b3b547c595679 (patch) | |
tree | 50249c24429424ee14531a2047954c9df1ee345a /src/WixToolset.Core | |
parent | b6bf1604c32259757f75b4c35444cfe4ecc21a86 (diff) | |
download | wix-aa6f15ec4998a77622fafe9c510b3b547c595679.tar.gz wix-aa6f15ec4998a77622fafe9c510b3b547c595679.tar.bz2 wix-aa6f15ec4998a77622fafe9c510b3b547c595679.zip |
Refactor CompilerCore to ParserHelper and other clean up
Diffstat (limited to 'src/WixToolset.Core')
18 files changed, 946 insertions, 742 deletions
diff --git a/src/WixToolset.Core/AppCommon.cs b/src/WixToolset.Core/AppCommon.cs index 5fde632a..7716155a 100644 --- a/src/WixToolset.Core/AppCommon.cs +++ b/src/WixToolset.Core/AppCommon.cs | |||
@@ -1,10 +1,9 @@ | |||
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. | 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 | 2 | ||
3 | namespace WixToolset | 3 | namespace WixToolset.Core |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections.Specialized; | 6 | using System.Collections.Specialized; |
7 | using System.Configuration; | ||
8 | using System.Globalization; | 7 | using System.Globalization; |
9 | using System.IO; | 8 | using System.IO; |
10 | using System.Reflection; | 9 | using System.Reflection; |
diff --git a/src/WixToolset.Core/BinderCore.cs b/src/WixToolset.Core/BinderCore.cs deleted file mode 100644 index 84173b99..00000000 --- a/src/WixToolset.Core/BinderCore.cs +++ /dev/null | |||
@@ -1,44 +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 | ||
4 | { | ||
5 | using WixToolset.Data; | ||
6 | using WixToolset.Extensibility; | ||
7 | |||
8 | /// <summary> | ||
9 | /// Core class for the binder. | ||
10 | /// </summary> | ||
11 | internal class BinderCore : IBinderCore | ||
12 | { | ||
13 | public IBinderFileManagerCore FileManagerCore { get; set; } | ||
14 | |||
15 | /// <summary> | ||
16 | /// Gets whether the binder core encountered an error while processing. | ||
17 | /// </summary> | ||
18 | /// <value>Flag if core encountered an error during processing.</value> | ||
19 | public bool EncounteredError | ||
20 | { | ||
21 | get { return Messaging.Instance.EncounteredError; } | ||
22 | } | ||
23 | |||
24 | /// <summary> | ||
25 | /// Generate an identifier by hashing data from the row. | ||
26 | /// </summary> | ||
27 | /// <param name="prefix">Three letter or less prefix for generated row identifier.</param> | ||
28 | /// <param name="args">Information to hash.</param> | ||
29 | /// <returns>The generated identifier.</returns> | ||
30 | public string CreateIdentifier(string prefix, params string[] args) | ||
31 | { | ||
32 | return Common.GenerateIdentifier(prefix, args); | ||
33 | } | ||
34 | |||
35 | /// <summary> | ||
36 | /// Sends a message to the message delegate if there is one. | ||
37 | /// </summary> | ||
38 | /// <param name="mea">Message event arguments.</param> | ||
39 | public void OnMessage(MessageEventArgs e) | ||
40 | { | ||
41 | Messaging.Instance.OnMessage(e); | ||
42 | } | ||
43 | } | ||
44 | } | ||
diff --git a/src/WixToolset.Core/Common.cs b/src/WixToolset.Core/Common.cs index 28e7ee7b..9a0d3aec 100644 --- a/src/WixToolset.Core/Common.cs +++ b/src/WixToolset.Core/Common.cs | |||
@@ -1,6 +1,6 @@ | |||
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. | 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 | 2 | ||
3 | namespace WixToolset | 3 | namespace WixToolset.Core |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Diagnostics; | 6 | using System.Diagnostics; |
@@ -13,6 +13,7 @@ namespace WixToolset | |||
13 | using System.Xml; | 13 | using System.Xml; |
14 | using System.Xml.Linq; | 14 | using System.Xml.Linq; |
15 | using WixToolset.Data; | 15 | using WixToolset.Data; |
16 | using WixToolset.Extensibility; | ||
16 | 17 | ||
17 | /// <summary> | 18 | /// <summary> |
18 | /// Common Wix utility methods and types. | 19 | /// Common Wix utility methods and types. |
@@ -766,8 +767,8 @@ namespace WixToolset | |||
766 | /// <returns>The attribute's YesNoType value.</returns> | 767 | /// <returns>The attribute's YesNoType value.</returns> |
767 | internal static string GetInnerText(XElement node) | 768 | internal static string GetInnerText(XElement node) |
768 | { | 769 | { |
769 | XText text = node.Nodes().Where(n => XmlNodeType.Text == n.NodeType || XmlNodeType.CDATA == n.NodeType).Cast<XText>().FirstOrDefault(); | 770 | var text = node.Nodes().Where(n => XmlNodeType.Text == n.NodeType || XmlNodeType.CDATA == n.NodeType).Cast<XText>().FirstOrDefault(); |
770 | return (null == text) ? null : text.Value; | 771 | return text?.Value; |
771 | } | 772 | } |
772 | 773 | ||
773 | /// <summary> | 774 | /// <summary> |
diff --git a/src/WixToolset.Core/Compiler.cs b/src/WixToolset.Core/Compiler.cs index 903aae61..4b1ef033 100644 --- a/src/WixToolset.Core/Compiler.cs +++ b/src/WixToolset.Core/Compiler.cs | |||
@@ -1,6 +1,6 @@ | |||
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. | 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 | 2 | ||
3 | namespace WixToolset | 3 | namespace WixToolset.Core |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections; | 6 | using System.Collections; |
@@ -11,7 +11,6 @@ namespace WixToolset | |||
11 | using System.IO; | 11 | using System.IO; |
12 | using System.Text.RegularExpressions; | 12 | using System.Text.RegularExpressions; |
13 | using System.Xml.Linq; | 13 | using System.Xml.Linq; |
14 | using WixToolset.Core; | ||
15 | using WixToolset.Core.Native; | 14 | using WixToolset.Core.Native; |
16 | using WixToolset.Data; | 15 | using WixToolset.Data; |
17 | using WixToolset.Data.Tuples; | 16 | using WixToolset.Data.Tuples; |
@@ -22,7 +21,6 @@ namespace WixToolset | |||
22 | /// <summary> | 21 | /// <summary> |
23 | /// Compiler of the WiX toolset. | 22 | /// Compiler of the WiX toolset. |
24 | /// </summary> | 23 | /// </summary> |
25 | [SuppressMessage("Microsoft.Naming", "CA1724:TypeNamesShouldNotMatchNamespaces")] | ||
26 | public sealed class Compiler | 24 | public sealed class Compiler |
27 | { | 25 | { |
28 | public const string UpgradeDetectedProperty = "WIX_UPGRADE_DETECTED"; | 26 | public const string UpgradeDetectedProperty = "WIX_UPGRADE_DETECTED"; |
@@ -40,7 +38,7 @@ namespace WixToolset | |||
40 | private const string BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER = "WixBundleOriginalSourceFolder"; | 38 | private const string BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER = "WixBundleOriginalSourceFolder"; |
41 | private const string BURN_BUNDLE_LAST_USED_SOURCE = "WixBundleLastUsedSource"; | 39 | private const string BURN_BUNDLE_LAST_USED_SOURCE = "WixBundleLastUsedSource"; |
42 | 40 | ||
43 | // if these are true you know you are building a module or product | 41 | // If these are true you know you are building a module or product |
44 | // but if they are false you cannot not be sure they will not end | 42 | // but if they are false you cannot not be sure they will not end |
45 | // up a product or module. Use these flags carefully. | 43 | // up a product or module. Use these flags carefully. |
46 | private bool compilingModule; | 44 | private bool compilingModule; |
@@ -123,16 +121,15 @@ namespace WixToolset | |||
123 | // Try to compile it. | 121 | // Try to compile it. |
124 | try | 122 | try |
125 | { | 123 | { |
126 | var creator = context.ServiceProvider.GetService<ITupleDefinitionCreator>(); | 124 | var parseHelper = context.ServiceProvider.GetService<IParseHelper>(); |
127 | 125 | ||
128 | this.Core = new CompilerCore(target, creator, extensionsByNamespace); | 126 | this.Core = new CompilerCore(target, parseHelper, extensionsByNamespace); |
129 | this.Core.CurrentPlatform = this.Context.Platform; | ||
130 | this.Core.ShowPedanticMessages = this.ShowPedanticMessages; | 127 | this.Core.ShowPedanticMessages = this.ShowPedanticMessages; |
131 | this.componentIdPlaceholdersResolver = new WixVariableResolver(); | 128 | this.componentIdPlaceholdersResolver = new WixVariableResolver(); |
132 | 129 | ||
133 | // parse the document | 130 | // parse the document |
134 | var source = context.Source; | 131 | var source = context.Source; |
135 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(source.Root); | 132 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(source.Root); |
136 | if ("Wix" == source.Root.Name.LocalName) | 133 | if ("Wix" == source.Root.Name.LocalName) |
137 | { | 134 | { |
138 | if (CompilerCore.WixNamespace == source.Root.Name.Namespace) | 135 | if (CompilerCore.WixNamespace == source.Root.Name.Namespace) |
diff --git a/src/WixToolset.Core/CompilerCore.cs b/src/WixToolset.Core/CompilerCore.cs index 46a2e435..26c19acc 100644 --- a/src/WixToolset.Core/CompilerCore.cs +++ b/src/WixToolset.Core/CompilerCore.cs | |||
@@ -1,6 +1,6 @@ | |||
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. | 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 | 2 | ||
3 | namespace WixToolset | 3 | namespace WixToolset.Core |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections; | 6 | using System.Collections; |
@@ -17,6 +17,7 @@ namespace WixToolset | |||
17 | using WixToolset.Data; | 17 | using WixToolset.Data; |
18 | using WixToolset.Data.Tuples; | 18 | using WixToolset.Data.Tuples; |
19 | using WixToolset.Extensibility; | 19 | using WixToolset.Extensibility; |
20 | using WixToolset.Extensibility.Services; | ||
20 | using Wix = WixToolset.Data.Serialize; | 21 | using Wix = WixToolset.Data.Serialize; |
21 | 22 | ||
22 | internal enum ValueListKind | 23 | internal enum ValueListKind |
@@ -40,7 +41,7 @@ namespace WixToolset | |||
40 | /// <summary> | 41 | /// <summary> |
41 | /// Core class for the compiler. | 42 | /// Core class for the compiler. |
42 | /// </summary> | 43 | /// </summary> |
43 | internal sealed class CompilerCore //: ICompilerCore | 44 | internal sealed class CompilerCore |
44 | { | 45 | { |
45 | internal static readonly XNamespace W3SchemaPrefix = "http://www.w3.org/"; | 46 | internal static readonly XNamespace W3SchemaPrefix = "http://www.w3.org/"; |
46 | internal static readonly XNamespace WixNamespace = "http://wixtoolset.org/schemas/v4/wxs"; | 47 | internal static readonly XNamespace WixNamespace = "http://wixtoolset.org/schemas/v4/wxs"; |
@@ -50,19 +51,6 @@ namespace WixToolset | |||
50 | private const string IllegalLongFilenameCharacters = @"[\\\?|><:/\*""]"; // illegal: \ ? | > < : / * " | 51 | private const string IllegalLongFilenameCharacters = @"[\\\?|><:/\*""]"; // illegal: \ ? | > < : / * " |
51 | private static readonly Regex IllegalLongFilename = new Regex(IllegalLongFilenameCharacters, RegexOptions.Compiled); | 52 | private static readonly Regex IllegalLongFilename = new Regex(IllegalLongFilenameCharacters, RegexOptions.Compiled); |
52 | 53 | ||
53 | private const string LegalLongFilenameCharacters = @"[^\\\?|><:/\*""]"; // opposite of illegal above. | ||
54 | private static readonly Regex LegalLongFilename = new Regex(String.Concat("^", LegalLongFilenameCharacters, @"{1,259}$"), RegexOptions.Compiled); | ||
55 | |||
56 | private const string LegalRelativeLongFilenameCharacters = @"[^\?|><:/\*""]"; // (like legal long, but we allow '\') illegal: ? | > < : / * " | ||
57 | private static readonly Regex LegalRelativeLongFilename = new Regex(String.Concat("^", LegalRelativeLongFilenameCharacters, @"{1,259}$"), RegexOptions.Compiled); | ||
58 | |||
59 | private const string LegalWildcardLongFilenameCharacters = @"[^\\|><:/""]"; // illegal: \ | > < : / " | ||
60 | private static readonly Regex LegalWildcardLongFilename = new Regex(String.Concat("^", LegalWildcardLongFilenameCharacters, @"{1,259}$")); | ||
61 | |||
62 | private static readonly Regex PutGuidHere = new Regex(@"PUT\-GUID\-(?:\d+\-)?HERE", RegexOptions.Singleline); | ||
63 | |||
64 | private static readonly Regex LegalIdentifierWithAccess = new Regex(@"^((?<access>public|internal|protected|private)\s+)?(?<id>[_A-Za-z][0-9A-Za-z_\.]*)$", RegexOptions.Compiled | RegexOptions.ExplicitCapture); | ||
65 | |||
66 | public const int DefaultMaximumUncompressedMediaSize = 200; // Default value is 200 MB | 54 | public const int DefaultMaximumUncompressedMediaSize = 200; // Default value is 200 MB |
67 | public const int MinValueOfMaxCabSizeForLargeFileSplitting = 20; // 20 MB | 55 | public const int MinValueOfMaxCabSizeForLargeFileSplitting = 20; // 20 MB |
68 | public const int MaxValueOfMaxCabSizeForLargeFileSplitting = 2 * 1024; // 2048 MB (i.e. 2 GB) | 56 | public const int MaxValueOfMaxCabSizeForLargeFileSplitting = 2 * 1024; // 2048 MB (i.e. 2 GB) |
@@ -141,7 +129,7 @@ namespace WixToolset | |||
141 | }); | 129 | }); |
142 | 130 | ||
143 | private Dictionary<XNamespace, ICompilerExtension> extensions; | 131 | private Dictionary<XNamespace, ICompilerExtension> extensions; |
144 | private ITupleDefinitionCreator creator; | 132 | private IParseHelper parseHelper; |
145 | private Intermediate intermediate; | 133 | private Intermediate intermediate; |
146 | 134 | ||
147 | private HashSet<string> activeSectionInlinedDirectoryIds; | 135 | private HashSet<string> activeSectionInlinedDirectoryIds; |
@@ -152,10 +140,10 @@ namespace WixToolset | |||
152 | /// </summary> | 140 | /// </summary> |
153 | /// <param name="intermediate">The Intermediate object representing compiled source document.</param> | 141 | /// <param name="intermediate">The Intermediate object representing compiled source document.</param> |
154 | /// <param name="extensions">The WiX extensions collection.</param> | 142 | /// <param name="extensions">The WiX extensions collection.</param> |
155 | internal CompilerCore(Intermediate intermediate, ITupleDefinitionCreator creator, Dictionary<XNamespace, ICompilerExtension> extensions) | 143 | internal CompilerCore(Intermediate intermediate, IParseHelper parseHelper, Dictionary<XNamespace, ICompilerExtension> extensions) |
156 | { | 144 | { |
157 | this.extensions = extensions; | 145 | this.extensions = extensions; |
158 | this.creator = creator; | 146 | this.parseHelper = parseHelper; |
159 | this.intermediate = intermediate; | 147 | this.intermediate = intermediate; |
160 | } | 148 | } |
161 | 149 | ||
@@ -166,12 +154,6 @@ namespace WixToolset | |||
166 | public IntermediateSection ActiveSection { get; private set; } | 154 | public IntermediateSection ActiveSection { get; private set; } |
167 | 155 | ||
168 | /// <summary> | 156 | /// <summary> |
169 | /// Gets or sets the platform which the compiler will use when defaulting 64-bit attributes and elements. | ||
170 | /// </summary> | ||
171 | /// <value>The platform which the compiler will use when defaulting 64-bit attributes and elements.</value> | ||
172 | public Platform CurrentPlatform { get; set; } | ||
173 | |||
174 | /// <summary> | ||
175 | /// Gets whether the compiler core encountered an error while processing. | 157 | /// Gets whether the compiler core encountered an error while processing. |
176 | /// </summary> | 158 | /// </summary> |
177 | /// <value>Flag if core encountered an error during processing.</value> | 159 | /// <value>Flag if core encountered an error during processing.</value> |
@@ -231,12 +213,7 @@ namespace WixToolset | |||
231 | /// <returns>true if the filename is ambiguous; false otherwise.</returns> | 213 | /// <returns>true if the filename is ambiguous; false otherwise.</returns> |
232 | public static bool IsAmbiguousFilename(string filename) | 214 | public static bool IsAmbiguousFilename(string filename) |
233 | { | 215 | { |
234 | if (null == filename || 0 == filename.Length) | 216 | return String.IsNullOrEmpty(filename) ? false : CompilerCore.AmbiguousFilename.IsMatch(filename); |
235 | { | ||
236 | return false; | ||
237 | } | ||
238 | |||
239 | return CompilerCore.AmbiguousFilename.IsMatch(filename); | ||
240 | } | 217 | } |
241 | 218 | ||
242 | /// <summary> | 219 | /// <summary> |
@@ -246,7 +223,7 @@ namespace WixToolset | |||
246 | /// <returns>true if the value is an identifier; false otherwise.</returns> | 223 | /// <returns>true if the value is an identifier; false otherwise.</returns> |
247 | public bool IsValidIdentifier(string value) | 224 | public bool IsValidIdentifier(string value) |
248 | { | 225 | { |
249 | return Common.IsIdentifier(value); | 226 | return this.parseHelper.IsValidIdentifier(value); |
250 | } | 227 | } |
251 | 228 | ||
252 | /// <summary> | 229 | /// <summary> |
@@ -256,14 +233,7 @@ namespace WixToolset | |||
256 | /// <returns>True if the identifier is a valid loc identifier.</returns> | 233 | /// <returns>True if the identifier is a valid loc identifier.</returns> |
257 | public bool IsValidLocIdentifier(string identifier) | 234 | public bool IsValidLocIdentifier(string identifier) |
258 | { | 235 | { |
259 | if (String.IsNullOrEmpty(identifier)) | 236 | return this.parseHelper.IsValidIdentifier(identifier); |
260 | { | ||
261 | return false; | ||
262 | } | ||
263 | |||
264 | Match match = Common.WixVariableRegex.Match(identifier); | ||
265 | |||
266 | return (match.Success && "loc" == match.Groups["namespace"].Value && 0 == match.Index && identifier.Length == match.Length); | ||
267 | } | 237 | } |
268 | 238 | ||
269 | /// <summary> | 239 | /// <summary> |
@@ -275,34 +245,7 @@ namespace WixToolset | |||
275 | /// <returns>True if the filename is a valid long filename</returns> | 245 | /// <returns>True if the filename is a valid long filename</returns> |
276 | public bool IsValidLongFilename(string filename, bool allowWildcards = false, bool allowRelative = false) | 246 | public bool IsValidLongFilename(string filename, bool allowWildcards = false, bool allowRelative = false) |
277 | { | 247 | { |
278 | if (String.IsNullOrEmpty(filename)) | 248 | return this.parseHelper.IsValidLongFilename(filename, allowWildcards, allowRelative); |
279 | { | ||
280 | return false; | ||
281 | } | ||
282 | |||
283 | // check for a non-period character (all periods is not legal) | ||
284 | bool nonPeriodFound = false; | ||
285 | foreach (char character in filename) | ||
286 | { | ||
287 | if ('.' != character) | ||
288 | { | ||
289 | nonPeriodFound = true; | ||
290 | break; | ||
291 | } | ||
292 | } | ||
293 | |||
294 | if (allowWildcards) | ||
295 | { | ||
296 | return (nonPeriodFound && CompilerCore.LegalWildcardLongFilename.IsMatch(filename)); | ||
297 | } | ||
298 | else if (allowRelative) | ||
299 | { | ||
300 | return (nonPeriodFound && CompilerCore.LegalRelativeLongFilename.IsMatch(filename)); | ||
301 | } | ||
302 | else | ||
303 | { | ||
304 | return (nonPeriodFound && CompilerCore.LegalLongFilename.IsMatch(filename)); | ||
305 | } | ||
306 | } | 249 | } |
307 | 250 | ||
308 | /// <summary> | 251 | /// <summary> |
@@ -313,7 +256,7 @@ namespace WixToolset | |||
313 | /// <returns>True if the filename is a valid short filename</returns> | 256 | /// <returns>True if the filename is a valid short filename</returns> |
314 | public bool IsValidShortFilename(string filename, bool allowWildcards) | 257 | public bool IsValidShortFilename(string filename, bool allowWildcards) |
315 | { | 258 | { |
316 | return Common.IsValidShortFilename(filename, allowWildcards); | 259 | return this.parseHelper.IsValidShortFilename(filename, allowWildcards); |
317 | } | 260 | } |
318 | 261 | ||
319 | /// <summary> | 262 | /// <summary> |
@@ -337,52 +280,7 @@ namespace WixToolset | |||
337 | /// <returns>The generated 8.3-compliant short file/directory name.</returns> | 280 | /// <returns>The generated 8.3-compliant short file/directory name.</returns> |
338 | public string CreateShortName(string longName, bool keepExtension, bool allowWildcards, params string[] args) | 281 | public string CreateShortName(string longName, bool keepExtension, bool allowWildcards, params string[] args) |
339 | { | 282 | { |
340 | // canonicalize the long name if its not a localization identifier (they are case-sensitive) | 283 | return this.parseHelper.CreateShortName(longName, keepExtension, allowWildcards, args); |
341 | if (!this.IsValidLocIdentifier(longName)) | ||
342 | { | ||
343 | longName = longName.ToLowerInvariant(); | ||
344 | } | ||
345 | |||
346 | // collect all the data | ||
347 | List<string> strings = new List<string>(1 + args.Length); | ||
348 | strings.Add(longName); | ||
349 | strings.AddRange(args); | ||
350 | |||
351 | // prepare for hashing | ||
352 | string stringData = String.Join("|", strings); | ||
353 | byte[] data = Encoding.UTF8.GetBytes(stringData); | ||
354 | |||
355 | // hash the data | ||
356 | byte[] hash; | ||
357 | using (SHA1 sha1 = new SHA1CryptoServiceProvider()) | ||
358 | { | ||
359 | hash = sha1.ComputeHash(data); | ||
360 | } | ||
361 | |||
362 | // generate the short file/directory name without an extension | ||
363 | StringBuilder shortName = new StringBuilder(Convert.ToBase64String(hash)); | ||
364 | shortName.Remove(8, shortName.Length - 8).Replace('+', '-').Replace('/', '_'); | ||
365 | |||
366 | if (keepExtension) | ||
367 | { | ||
368 | string extension = Path.GetExtension(longName); | ||
369 | |||
370 | if (4 < extension.Length) | ||
371 | { | ||
372 | extension = extension.Substring(0, 4); | ||
373 | } | ||
374 | |||
375 | shortName.Append(extension); | ||
376 | |||
377 | // check the generated short name to ensure its still legal (the extension may not be legal) | ||
378 | if (!this.IsValidShortFilename(shortName.ToString(), allowWildcards)) | ||
379 | { | ||
380 | // remove the extension (by truncating the generated file name back to the generated characters) | ||
381 | shortName.Length -= extension.Length; | ||
382 | } | ||
383 | } | ||
384 | |||
385 | return shortName.ToString().ToLowerInvariant(); | ||
386 | } | 284 | } |
387 | 285 | ||
388 | /// <summary> | 286 | /// <summary> |
@@ -422,8 +320,7 @@ namespace WixToolset | |||
422 | /// <returns>The node's inner text trimmed.</returns> | 320 | /// <returns>The node's inner text trimmed.</returns> |
423 | public string GetTrimmedInnerText(XElement element) | 321 | public string GetTrimmedInnerText(XElement element) |
424 | { | 322 | { |
425 | string value = Common.GetInnerText(element); | 323 | return this.parseHelper.GetTrimmedInnerText(element); |
426 | return (null == value) ? null : value.Trim(); | ||
427 | } | 324 | } |
428 | 325 | ||
429 | /// <summary> | 326 | /// <summary> |
@@ -431,23 +328,9 @@ namespace WixToolset | |||
431 | /// </summary> | 328 | /// </summary> |
432 | /// <param name="element">The element to ensure inner text is a condition.</param> | 329 | /// <param name="element">The element to ensure inner text is a condition.</param> |
433 | /// <returns>The value converted into a safe condition.</returns> | 330 | /// <returns>The value converted into a safe condition.</returns> |
434 | [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")] | ||
435 | public string GetConditionInnerText(XElement element) | 331 | public string GetConditionInnerText(XElement element) |
436 | { | 332 | { |
437 | string value = element.Value; | 333 | return this.parseHelper.GetConditionInnerText(element); |
438 | if (0 < value.Length) | ||
439 | { | ||
440 | value = value.Trim(); | ||
441 | value = value.Replace('\t', ' '); | ||
442 | value = value.Replace('\r', ' '); | ||
443 | value = value.Replace('\n', ' '); | ||
444 | } | ||
445 | else // return null for a non-existant condition | ||
446 | { | ||
447 | value = null; | ||
448 | } | ||
449 | |||
450 | return value; | ||
451 | } | 334 | } |
452 | 335 | ||
453 | /// <summary> | 336 | /// <summary> |
@@ -458,7 +341,7 @@ namespace WixToolset | |||
458 | /// <returns>The generated GUID for the given namespace and value.</returns> | 341 | /// <returns>The generated GUID for the given namespace and value.</returns> |
459 | public string CreateGuid(Guid namespaceGuid, string value) | 342 | public string CreateGuid(Guid namespaceGuid, string value) |
460 | { | 343 | { |
461 | return Uuid.NewUuid(namespaceGuid, value).ToString("B").ToUpperInvariant(); | 344 | return this.parseHelper.CreateGuid(namespaceGuid, value); |
462 | } | 345 | } |
463 | 346 | ||
464 | /// <summary> | 347 | /// <summary> |
@@ -510,46 +393,7 @@ namespace WixToolset | |||
510 | /// <returns>Identifier of the leaf directory created.</returns> | 393 | /// <returns>Identifier of the leaf directory created.</returns> |
511 | public string CreateDirectoryReferenceFromInlineSyntax(SourceLineNumber sourceLineNumbers, XAttribute attribute, string parentId) | 394 | public string CreateDirectoryReferenceFromInlineSyntax(SourceLineNumber sourceLineNumbers, XAttribute attribute, string parentId) |
512 | { | 395 | { |
513 | string id = null; | 396 | return this.parseHelper.CreateDirectoryReferenceFromInlineSyntax(this.ActiveSection, sourceLineNumbers, attribute, parentId); |
514 | string[] inlineSyntax = this.GetAttributeInlineDirectorySyntax(sourceLineNumbers, attribute, true); | ||
515 | |||
516 | if (null != inlineSyntax) | ||
517 | { | ||
518 | // Special case the single entry in the inline syntax since it is the most common case | ||
519 | // and needs no extra processing. It's just a reference to an existing directory. | ||
520 | if (1 == inlineSyntax.Length) | ||
521 | { | ||
522 | id = inlineSyntax[0]; | ||
523 | this.CreateSimpleReference(sourceLineNumbers, "Directory", id); | ||
524 | } | ||
525 | else // start creating rows for the entries in the inline syntax | ||
526 | { | ||
527 | id = parentId; | ||
528 | |||
529 | int pathStartsAt = 0; | ||
530 | if (inlineSyntax[0].EndsWith(":")) | ||
531 | { | ||
532 | // TODO: should overriding the parent identifier with a specific id be an error or a warning or just let it slide? | ||
533 | //if (null != parentId) | ||
534 | //{ | ||
535 | // this.core.OnMessage(WixErrors.Xxx(sourceLineNumbers)); | ||
536 | //} | ||
537 | |||
538 | id = inlineSyntax[0].TrimEnd(':'); | ||
539 | this.CreateSimpleReference(sourceLineNumbers, "Directory", id); | ||
540 | |||
541 | pathStartsAt = 1; | ||
542 | } | ||
543 | |||
544 | for (int i = pathStartsAt; i < inlineSyntax.Length; ++i) | ||
545 | { | ||
546 | Identifier inlineId = this.CreateDirectoryRow(sourceLineNumbers, null, id, inlineSyntax[i]); | ||
547 | id = inlineId.Id; | ||
548 | } | ||
549 | } | ||
550 | } | ||
551 | |||
552 | return id; | ||
553 | } | 397 | } |
554 | 398 | ||
555 | /// <summary> | 399 | /// <summary> |
@@ -575,59 +419,9 @@ namespace WixToolset | |||
575 | /// <param name="name">The registry entry name.</param> | 419 | /// <param name="name">The registry entry name.</param> |
576 | /// <param name="value">The registry entry value.</param> | 420 | /// <param name="value">The registry entry value.</param> |
577 | /// <param name="componentId">The component which will control installation/uninstallation of the registry entry.</param> | 421 | /// <param name="componentId">The component which will control installation/uninstallation of the registry entry.</param> |
578 | /// <param name="escapeLeadingHash">If true, "escape" leading '#' characters so the value is written as a REG_SZ.</param> | ||
579 | public Identifier CreateRegistryRow(SourceLineNumber sourceLineNumbers, int root, string key, string name, string value, string componentId, bool escapeLeadingHash) | ||
580 | { | ||
581 | Identifier id = null; | ||
582 | |||
583 | if (!this.EncounteredError) | ||
584 | { | ||
585 | if (-1 > root || 3 < root) | ||
586 | { | ||
587 | throw new ArgumentOutOfRangeException("root"); | ||
588 | } | ||
589 | |||
590 | if (null == key) | ||
591 | { | ||
592 | throw new ArgumentNullException("key"); | ||
593 | } | ||
594 | |||
595 | if (null == componentId) | ||
596 | { | ||
597 | throw new ArgumentNullException("componentId"); | ||
598 | } | ||
599 | |||
600 | // escape the leading '#' character for string registry values | ||
601 | if (escapeLeadingHash && null != value && value.StartsWith("#", StringComparison.Ordinal)) | ||
602 | { | ||
603 | value = String.Concat("#", value); | ||
604 | } | ||
605 | |||
606 | id = this.CreateIdentifier("reg", componentId, root.ToString(CultureInfo.InvariantCulture.NumberFormat), key.ToLowerInvariant(), (null != name ? name.ToLowerInvariant() : name)); | ||
607 | |||
608 | var row = this.CreateRow(sourceLineNumbers, TupleDefinitionType.Registry, id); | ||
609 | row.Set(1, root); | ||
610 | row.Set(2, key); | ||
611 | row.Set(3, name); | ||
612 | row.Set(4, value); | ||
613 | row.Set(5, componentId); | ||
614 | } | ||
615 | |||
616 | return id; | ||
617 | } | ||
618 | |||
619 | /// <summary> | ||
620 | /// Creates a Registry row in the active section. | ||
621 | /// </summary> | ||
622 | /// <param name="sourceLineNumbers">Source and line number of the current row.</param> | ||
623 | /// <param name="root">The registry entry root.</param> | ||
624 | /// <param name="key">The registry entry key.</param> | ||
625 | /// <param name="name">The registry entry name.</param> | ||
626 | /// <param name="value">The registry entry value.</param> | ||
627 | /// <param name="componentId">The component which will control installation/uninstallation of the registry entry.</param> | ||
628 | public Identifier CreateRegistryRow(SourceLineNumber sourceLineNumbers, int root, string key, string name, string value, string componentId) | 422 | public Identifier CreateRegistryRow(SourceLineNumber sourceLineNumbers, int root, string key, string name, string value, string componentId) |
629 | { | 423 | { |
630 | return this.CreateRegistryRow(sourceLineNumbers, root, key, name, value, componentId, true); | 424 | return this.parseHelper.CreateRegistryRow(this.ActiveSection, sourceLineNumbers, root, key, name, value, componentId, true); |
631 | } | 425 | } |
632 | 426 | ||
633 | /// <summary> | 427 | /// <summary> |
@@ -646,9 +440,7 @@ namespace WixToolset | |||
646 | // If this simple reference hasn't been added to the active section already, add it. | 440 | // If this simple reference hasn't been added to the active section already, add it. |
647 | if (this.activeSectionSimpleReferences.Add(id)) | 441 | if (this.activeSectionSimpleReferences.Add(id)) |
648 | { | 442 | { |
649 | var wixSimpleReferenceRow = (WixSimpleReferenceTuple)this.CreateRow(sourceLineNumbers, TupleDefinitionType.WixSimpleReference); | 443 | this.parseHelper.CreateSimpleReference(this.ActiveSection, sourceLineNumbers, tableName, primaryKeys); |
650 | wixSimpleReferenceRow.Table = tableName; | ||
651 | wixSimpleReferenceRow.PrimaryKeys = joinedKeys; | ||
652 | } | 444 | } |
653 | } | 445 | } |
654 | } | 446 | } |
@@ -665,21 +457,7 @@ namespace WixToolset | |||
665 | { | 457 | { |
666 | if (!this.EncounteredError) | 458 | if (!this.EncounteredError) |
667 | { | 459 | { |
668 | if (null == parentId || ComplexReferenceParentType.Unknown == parentType) | 460 | this.parseHelper.CreateWixGroupRow(this.ActiveSection, sourceLineNumbers, parentType, parentId, childType, childId); |
669 | { | ||
670 | return; | ||
671 | } | ||
672 | |||
673 | if (null == childId) | ||
674 | { | ||
675 | throw new ArgumentNullException("childId"); | ||
676 | } | ||
677 | |||
678 | var row = (WixGroupTuple)this.CreateRow(sourceLineNumbers, TupleDefinitionType.WixGroup); | ||
679 | row.ParentId = parentId; | ||
680 | row.ParentType = parentType; | ||
681 | row.ChildId = childId; | ||
682 | row.ChildType = childType; | ||
683 | } | 461 | } |
684 | } | 462 | } |
685 | 463 | ||
@@ -693,16 +471,7 @@ namespace WixToolset | |||
693 | { | 471 | { |
694 | if (!this.EncounteredError) | 472 | if (!this.EncounteredError) |
695 | { | 473 | { |
696 | var row = this.CreateRow(sourceLineNumbers, TupleDefinitionType.WixEnsureTable); | 474 | this.parseHelper.EnsureTable(this.ActiveSection, sourceLineNumbers, tableName); |
697 | row.Set(0, tableName); | ||
698 | |||
699 | // We don't add custom table definitions to the tableDefinitions collection, | ||
700 | // so if it's not in there, it better be a custom table. If the Id is just wrong, | ||
701 | // instead of a custom table, we get an unresolved reference at link time. | ||
702 | if (!this.creator.TryGetTupleDefinitionByName(tableName, out var ignored)) | ||
703 | { | ||
704 | this.CreateSimpleReference(sourceLineNumbers, "WixCustomTable", tableName); | ||
705 | } | ||
706 | } | 475 | } |
707 | } | 476 | } |
708 | 477 | ||
@@ -716,7 +485,7 @@ namespace WixToolset | |||
716 | [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")] | 485 | [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")] |
717 | public string GetAttributeValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, EmptyRule emptyRule = EmptyRule.CanBeWhitespaceOnly) | 486 | public string GetAttributeValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, EmptyRule emptyRule = EmptyRule.CanBeWhitespaceOnly) |
718 | { | 487 | { |
719 | return Common.GetAttributeValue(sourceLineNumbers, attribute, emptyRule); | 488 | return this.parseHelper.GetAttributeValue(sourceLineNumbers, attribute, emptyRule); |
720 | } | 489 | } |
721 | 490 | ||
722 | /// <summary> | 491 | /// <summary> |
@@ -800,7 +569,7 @@ namespace WixToolset | |||
800 | [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")] | 569 | [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")] |
801 | public int GetAttributeIntegerValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, int minimum, int maximum) | 570 | public int GetAttributeIntegerValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, int minimum, int maximum) |
802 | { | 571 | { |
803 | return Common.GetAttributeIntegerValue(sourceLineNumbers, attribute, minimum, maximum); | 572 | return this.parseHelper.GetAttributeIntegerValue(sourceLineNumbers, attribute, minimum, maximum); |
804 | } | 573 | } |
805 | 574 | ||
806 | /// <summary> | 575 | /// <summary> |
@@ -813,39 +582,7 @@ namespace WixToolset | |||
813 | /// <returns>The attribute's long value or a special value if an error occurred during conversion.</returns> | 582 | /// <returns>The attribute's long value or a special value if an error occurred during conversion.</returns> |
814 | public long GetAttributeLongValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, long minimum, long maximum) | 583 | public long GetAttributeLongValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, long minimum, long maximum) |
815 | { | 584 | { |
816 | Debug.Assert(minimum > CompilerConstants.LongNotSet && minimum > CompilerConstants.IllegalLong, "The legal values for this attribute collide with at least one sentinel used during parsing."); | 585 | return this.parseHelper.GetAttributeLongValue(sourceLineNumbers, attribute, minimum, maximum); |
817 | |||
818 | string value = this.GetAttributeValue(sourceLineNumbers, attribute); | ||
819 | |||
820 | if (0 < value.Length) | ||
821 | { | ||
822 | try | ||
823 | { | ||
824 | long longValue = Convert.ToInt64(value, CultureInfo.InvariantCulture.NumberFormat); | ||
825 | |||
826 | if (CompilerConstants.LongNotSet == longValue || CompilerConstants.IllegalLong == longValue) | ||
827 | { | ||
828 | this.OnMessage(WixErrors.IntegralValueSentinelCollision(sourceLineNumbers, longValue)); | ||
829 | } | ||
830 | else if (minimum > longValue || maximum < longValue) | ||
831 | { | ||
832 | this.OnMessage(WixErrors.IntegralValueOutOfRange(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, longValue, minimum, maximum)); | ||
833 | longValue = CompilerConstants.IllegalLong; | ||
834 | } | ||
835 | |||
836 | return longValue; | ||
837 | } | ||
838 | catch (FormatException) | ||
839 | { | ||
840 | this.OnMessage(WixErrors.IllegalLongValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
841 | } | ||
842 | catch (OverflowException) | ||
843 | { | ||
844 | this.OnMessage(WixErrors.IllegalLongValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
845 | } | ||
846 | } | ||
847 | |||
848 | return CompilerConstants.IllegalLong; | ||
849 | } | 586 | } |
850 | 587 | ||
851 | /// <summary> | 588 | /// <summary> |
@@ -956,73 +693,9 @@ namespace WixToolset | |||
956 | /// <param name="generatable">Determines whether the guid can be automatically generated.</param> | 693 | /// <param name="generatable">Determines whether the guid can be automatically generated.</param> |
957 | /// <param name="canBeEmpty">If true, no error is raised on empty value. If false, an error is raised.</param> | 694 | /// <param name="canBeEmpty">If true, no error is raised on empty value. If false, an error is raised.</param> |
958 | /// <returns>The attribute's guid value or a special value if an error occurred.</returns> | 695 | /// <returns>The attribute's guid value or a special value if an error occurred.</returns> |
959 | [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")] | ||
960 | [SuppressMessage("Microsoft.Performance", "CA1807:AvoidUnnecessaryStringCreation")] | ||
961 | public string GetAttributeGuidValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, bool generatable = false, bool canBeEmpty = false) | 696 | public string GetAttributeGuidValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, bool generatable = false, bool canBeEmpty = false) |
962 | { | 697 | { |
963 | if (null == attribute) | 698 | return this.parseHelper.GetAttributeGuidValue(sourceLineNumbers, attribute, generatable, canBeEmpty); |
964 | { | ||
965 | throw new ArgumentNullException("attribute"); | ||
966 | } | ||
967 | |||
968 | EmptyRule emptyRule = canBeEmpty ? EmptyRule.CanBeEmpty : EmptyRule.CanBeWhitespaceOnly; | ||
969 | string value = this.GetAttributeValue(sourceLineNumbers, attribute, emptyRule); | ||
970 | |||
971 | if (String.IsNullOrEmpty(value) && canBeEmpty) | ||
972 | { | ||
973 | return String.Empty; | ||
974 | } | ||
975 | else if (!String.IsNullOrEmpty(value)) | ||
976 | { | ||
977 | // If the value starts and ends with braces or parenthesis, accept that and strip them off. | ||
978 | if ((value.StartsWith("{", StringComparison.Ordinal) && value.EndsWith("}", StringComparison.Ordinal)) | ||
979 | || (value.StartsWith("(", StringComparison.Ordinal) && value.EndsWith(")", StringComparison.Ordinal))) | ||
980 | { | ||
981 | value = value.Substring(1, value.Length - 2); | ||
982 | } | ||
983 | |||
984 | try | ||
985 | { | ||
986 | Guid guid; | ||
987 | |||
988 | if (generatable && "*".Equals(value, StringComparison.Ordinal)) | ||
989 | { | ||
990 | return value; | ||
991 | } | ||
992 | |||
993 | if (CompilerCore.PutGuidHere.IsMatch(value)) | ||
994 | { | ||
995 | this.OnMessage(WixErrors.ExampleGuid(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
996 | return CompilerConstants.IllegalGuid; | ||
997 | } | ||
998 | else if (value.StartsWith("!(loc", StringComparison.Ordinal) || value.StartsWith("$(loc", StringComparison.Ordinal) || value.StartsWith("!(wix", StringComparison.Ordinal)) | ||
999 | { | ||
1000 | return value; | ||
1001 | } | ||
1002 | else | ||
1003 | { | ||
1004 | guid = new Guid(value); | ||
1005 | } | ||
1006 | |||
1007 | string uppercaseGuid = guid.ToString().ToUpper(CultureInfo.InvariantCulture); | ||
1008 | |||
1009 | if (this.ShowPedanticMessages) | ||
1010 | { | ||
1011 | if (uppercaseGuid != value) | ||
1012 | { | ||
1013 | this.OnMessage(WixErrors.GuidContainsLowercaseLetters(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
1014 | } | ||
1015 | } | ||
1016 | |||
1017 | return String.Concat("{", uppercaseGuid, "}"); | ||
1018 | } | ||
1019 | catch (FormatException) | ||
1020 | { | ||
1021 | this.OnMessage(WixErrors.IllegalGuidValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
1022 | } | ||
1023 | } | ||
1024 | |||
1025 | return CompilerConstants.IllegalGuid; | ||
1026 | } | 699 | } |
1027 | 700 | ||
1028 | /// <summary> | 701 | /// <summary> |
@@ -1033,27 +706,7 @@ namespace WixToolset | |||
1033 | /// <returns>The attribute's identifier value or a special value if an error occurred.</returns> | 706 | /// <returns>The attribute's identifier value or a special value if an error occurred.</returns> |
1034 | public Identifier GetAttributeIdentifier(SourceLineNumber sourceLineNumbers, XAttribute attribute) | 707 | public Identifier GetAttributeIdentifier(SourceLineNumber sourceLineNumbers, XAttribute attribute) |
1035 | { | 708 | { |
1036 | string value = Common.GetAttributeValue(sourceLineNumbers, attribute, EmptyRule.CanBeEmpty); | 709 | return this.parseHelper.GetAttributeIdentifier(sourceLineNumbers, attribute); |
1037 | AccessModifier access = AccessModifier.Public; | ||
1038 | |||
1039 | Match match = CompilerCore.LegalIdentifierWithAccess.Match(value); | ||
1040 | if (!match.Success) | ||
1041 | { | ||
1042 | return null; | ||
1043 | } | ||
1044 | else if (match.Groups["access"].Success) | ||
1045 | { | ||
1046 | access = (AccessModifier)Enum.Parse(typeof(AccessModifier), match.Groups["access"].Value, true); | ||
1047 | } | ||
1048 | |||
1049 | value = match.Groups["id"].Value; | ||
1050 | |||
1051 | if (Common.IsIdentifier(value) && 72 < value.Length) | ||
1052 | { | ||
1053 | this.OnMessage(WixWarnings.IdentifierTooLong(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
1054 | } | ||
1055 | |||
1056 | return new Identifier(value, access); | ||
1057 | } | 710 | } |
1058 | 711 | ||
1059 | /// <summary> | 712 | /// <summary> |
@@ -1064,7 +717,7 @@ namespace WixToolset | |||
1064 | /// <returns>The attribute's identifier value or a special value if an error occurred.</returns> | 717 | /// <returns>The attribute's identifier value or a special value if an error occurred.</returns> |
1065 | public string GetAttributeIdentifierValue(SourceLineNumber sourceLineNumbers, XAttribute attribute) | 718 | public string GetAttributeIdentifierValue(SourceLineNumber sourceLineNumbers, XAttribute attribute) |
1066 | { | 719 | { |
1067 | return Common.GetAttributeIdentifierValue(sourceLineNumbers, attribute); | 720 | return this.parseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attribute); |
1068 | } | 721 | } |
1069 | 722 | ||
1070 | /// <summary> | 723 | /// <summary> |
@@ -1075,23 +728,7 @@ namespace WixToolset | |||
1075 | /// <returns>The attribute's YesNoType value.</returns> | 728 | /// <returns>The attribute's YesNoType value.</returns> |
1076 | public YesNoType GetAttributeYesNoValue(SourceLineNumber sourceLineNumbers, XAttribute attribute) | 729 | public YesNoType GetAttributeYesNoValue(SourceLineNumber sourceLineNumbers, XAttribute attribute) |
1077 | { | 730 | { |
1078 | string value = this.GetAttributeValue(sourceLineNumbers, attribute); | 731 | return this.parseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute); |
1079 | |||
1080 | YesNoType result = YesNoType.IllegalValue; | ||
1081 | if (value.Equals("yes") || value.Equals("true")) | ||
1082 | { | ||
1083 | result = YesNoType.Yes; | ||
1084 | } | ||
1085 | else if (value.Equals("no") || value.Equals("false")) | ||
1086 | { | ||
1087 | result = YesNoType.No; | ||
1088 | } | ||
1089 | else | ||
1090 | { | ||
1091 | this.OnMessage(WixErrors.IllegalYesNoValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
1092 | } | ||
1093 | |||
1094 | return result; | ||
1095 | } | 732 | } |
1096 | 733 | ||
1097 | /// <summary> | 734 | /// <summary> |
@@ -1103,28 +740,7 @@ namespace WixToolset | |||
1103 | [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")] | 740 | [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")] |
1104 | public YesNoDefaultType GetAttributeYesNoDefaultValue(SourceLineNumber sourceLineNumbers, XAttribute attribute) | 741 | public YesNoDefaultType GetAttributeYesNoDefaultValue(SourceLineNumber sourceLineNumbers, XAttribute attribute) |
1105 | { | 742 | { |
1106 | string value = this.GetAttributeValue(sourceLineNumbers, attribute); | 743 | return this.parseHelper.GetAttributeYesNoDefaultValue(sourceLineNumbers, attribute); |
1107 | |||
1108 | if (0 < value.Length) | ||
1109 | { | ||
1110 | switch (Wix.Enums.ParseYesNoDefaultType(value)) | ||
1111 | { | ||
1112 | case Wix.YesNoDefaultType.@default: | ||
1113 | return YesNoDefaultType.Default; | ||
1114 | case Wix.YesNoDefaultType.no: | ||
1115 | return YesNoDefaultType.No; | ||
1116 | case Wix.YesNoDefaultType.yes: | ||
1117 | return YesNoDefaultType.Yes; | ||
1118 | case Wix.YesNoDefaultType.NotSet: | ||
1119 | // Previous code never returned 'NotSet'! | ||
1120 | break; | ||
1121 | default: | ||
1122 | this.OnMessage(WixErrors.IllegalYesNoDefaultValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
1123 | break; | ||
1124 | } | ||
1125 | } | ||
1126 | |||
1127 | return YesNoDefaultType.IllegalValue; | ||
1128 | } | 744 | } |
1129 | 745 | ||
1130 | /// <summary> | 746 | /// <summary> |
@@ -1202,41 +818,7 @@ namespace WixToolset | |||
1202 | [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")] | 818 | [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")] |
1203 | public string GetAttributeLongFilename(SourceLineNumber sourceLineNumbers, XAttribute attribute, bool allowWildcards = false, bool allowRelative = false) | 819 | public string GetAttributeLongFilename(SourceLineNumber sourceLineNumbers, XAttribute attribute, bool allowWildcards = false, bool allowRelative = false) |
1204 | { | 820 | { |
1205 | if (null == attribute) | 821 | return this.parseHelper.GetAttributeLongFilename(sourceLineNumbers, attribute, allowWildcards, allowRelative); |
1206 | { | ||
1207 | throw new ArgumentNullException("attribute"); | ||
1208 | } | ||
1209 | |||
1210 | string value = this.GetAttributeValue(sourceLineNumbers, attribute); | ||
1211 | |||
1212 | if (0 < value.Length) | ||
1213 | { | ||
1214 | if (!this.IsValidLongFilename(value, allowWildcards, allowRelative) && !this.IsValidLocIdentifier(value)) | ||
1215 | { | ||
1216 | if (allowRelative) | ||
1217 | { | ||
1218 | this.OnMessage(WixErrors.IllegalRelativeLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
1219 | } | ||
1220 | else | ||
1221 | { | ||
1222 | this.OnMessage(WixErrors.IllegalLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
1223 | } | ||
1224 | } | ||
1225 | else if (allowRelative) | ||
1226 | { | ||
1227 | string normalizedPath = value.Replace('\\', '/'); | ||
1228 | if (normalizedPath.StartsWith("../", StringComparison.Ordinal) || normalizedPath.Contains("/../")) | ||
1229 | { | ||
1230 | this.OnMessage(WixErrors.PayloadMustBeRelativeToCache(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
1231 | } | ||
1232 | } | ||
1233 | else if (CompilerCore.IsAmbiguousFilename(value)) | ||
1234 | { | ||
1235 | this.OnMessage(WixWarnings.AmbiguousFileOrDirectoryName(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
1236 | } | ||
1237 | } | ||
1238 | |||
1239 | return value; | ||
1240 | } | 822 | } |
1241 | 823 | ||
1242 | /// <summary> | 824 | /// <summary> |
@@ -1247,31 +829,7 @@ namespace WixToolset | |||
1247 | /// <returns>The attribute's version value.</returns> | 829 | /// <returns>The attribute's version value.</returns> |
1248 | public string GetAttributeVersionValue(SourceLineNumber sourceLineNumbers, XAttribute attribute) | 830 | public string GetAttributeVersionValue(SourceLineNumber sourceLineNumbers, XAttribute attribute) |
1249 | { | 831 | { |
1250 | string value = this.GetAttributeValue(sourceLineNumbers, attribute); | 832 | return this.parseHelper.GetAttributeVersionValue(sourceLineNumbers, attribute); |
1251 | |||
1252 | if (!String.IsNullOrEmpty(value)) | ||
1253 | { | ||
1254 | try | ||
1255 | { | ||
1256 | return new Version(value).ToString(); | ||
1257 | } | ||
1258 | catch (FormatException) // illegal integer in version | ||
1259 | { | ||
1260 | // Allow versions to contain binder variables. | ||
1261 | if (Common.ContainsValidBinderVariable(value)) | ||
1262 | { | ||
1263 | return value; | ||
1264 | } | ||
1265 | |||
1266 | this.OnMessage(WixErrors.IllegalVersionValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
1267 | } | ||
1268 | catch (ArgumentException) | ||
1269 | { | ||
1270 | this.OnMessage(WixErrors.IllegalVersionValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
1271 | } | ||
1272 | } | ||
1273 | |||
1274 | return null; | ||
1275 | } | 833 | } |
1276 | 834 | ||
1277 | /// <summary> | 835 | /// <summary> |
@@ -1453,7 +1011,7 @@ namespace WixToolset | |||
1453 | /// <returns>True if a property is found in the string.</returns> | 1011 | /// <returns>True if a property is found in the string.</returns> |
1454 | public bool ContainsProperty(string possibleProperty) | 1012 | public bool ContainsProperty(string possibleProperty) |
1455 | { | 1013 | { |
1456 | return Common.ContainsProperty(possibleProperty); | 1014 | return this.parseHelper.ContainsProperty(possibleProperty); |
1457 | } | 1015 | } |
1458 | 1016 | ||
1459 | /// <summary> | 1017 | /// <summary> |
@@ -1465,8 +1023,7 @@ namespace WixToolset | |||
1465 | [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.InvalidOperationException.#ctor(System.String)")] | 1023 | [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.InvalidOperationException.#ctor(System.String)")] |
1466 | public Identifier CreateIdentifier(string prefix, params string[] args) | 1024 | public Identifier CreateIdentifier(string prefix, params string[] args) |
1467 | { | 1025 | { |
1468 | string id = Common.GenerateIdentifier(prefix, args); | 1026 | return this.parseHelper.CreateIdentifier(prefix, args); |
1469 | return new Identifier(id, AccessModifier.Private); | ||
1470 | } | 1027 | } |
1471 | 1028 | ||
1472 | /// <summary> | 1029 | /// <summary> |
@@ -1476,8 +1033,7 @@ namespace WixToolset | |||
1476 | /// <returns></returns> | 1033 | /// <returns></returns> |
1477 | public Identifier CreateIdentifierFromFilename(string filename) | 1034 | public Identifier CreateIdentifierFromFilename(string filename) |
1478 | { | 1035 | { |
1479 | string id = Common.GetIdentifierFromName(filename); | 1036 | return this.parseHelper.CreateIdentifierFromFilename(filename); |
1480 | return new Identifier(id, AccessModifier.Private); | ||
1481 | } | 1037 | } |
1482 | 1038 | ||
1483 | /// <summary> | 1039 | /// <summary> |
@@ -1488,22 +1044,7 @@ namespace WixToolset | |||
1488 | /// <param name="context">Extra information about the context in which this element is being parsed.</param> | 1044 | /// <param name="context">Extra information about the context in which this element is being parsed.</param> |
1489 | public void ParseExtensionAttribute(XElement element, XAttribute attribute, IDictionary<string, string> context = null) | 1045 | public void ParseExtensionAttribute(XElement element, XAttribute attribute, IDictionary<string, string> context = null) |
1490 | { | 1046 | { |
1491 | // Ignore attributes defined by the W3C because we'll assume they are always right. | 1047 | this.parseHelper.ParseExtensionAttribute(this.extensions.Values, this.intermediate, this.ActiveSection, element, attribute, context); |
1492 | if ((String.IsNullOrEmpty(attribute.Name.NamespaceName) && attribute.Name.LocalName.Equals("xmlns", StringComparison.Ordinal)) || | ||
1493 | attribute.Name.NamespaceName.StartsWith(CompilerCore.W3SchemaPrefix.NamespaceName, StringComparison.Ordinal)) | ||
1494 | { | ||
1495 | return; | ||
1496 | } | ||
1497 | |||
1498 | if (this.TryFindExtension(attribute.Name.NamespaceName, out var extension)) | ||
1499 | { | ||
1500 | extension.ParseAttribute(element, attribute, context); | ||
1501 | } | ||
1502 | else | ||
1503 | { | ||
1504 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(element); | ||
1505 | this.OnMessage(WixErrors.UnhandledExtensionAttribute(sourceLineNumbers, element.Name.LocalName, attribute.Name.LocalName, attribute.Name.NamespaceName)); | ||
1506 | } | ||
1507 | } | 1048 | } |
1508 | 1049 | ||
1509 | /// <summary> | 1050 | /// <summary> |
@@ -1514,16 +1055,7 @@ namespace WixToolset | |||
1514 | /// <param name="context">Extra information about the context in which this element is being parsed.</param> | 1055 | /// <param name="context">Extra information about the context in which this element is being parsed.</param> |
1515 | public void ParseExtensionElement(XElement parentElement, XElement element, IDictionary<string, string> context = null) | 1056 | public void ParseExtensionElement(XElement parentElement, XElement element, IDictionary<string, string> context = null) |
1516 | { | 1057 | { |
1517 | if (this.TryFindExtension(element.Name.Namespace, out var extension)) | 1058 | this.parseHelper.ParseExtensionElement(this.extensions.Values, this.intermediate, this.ActiveSection, parentElement, element, context); |
1518 | { | ||
1519 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(parentElement); | ||
1520 | extension.ParseElement(parentElement, element, context); | ||
1521 | } | ||
1522 | else | ||
1523 | { | ||
1524 | SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(element); | ||
1525 | this.OnMessage(WixErrors.UnhandledExtensionElement(childSourceLineNumbers, parentElement.Name.LocalName, element.Name.LocalName, element.Name.NamespaceName)); | ||
1526 | } | ||
1527 | } | 1059 | } |
1528 | 1060 | ||
1529 | /// <summary> | 1061 | /// <summary> |
@@ -1532,17 +1064,7 @@ namespace WixToolset | |||
1532 | /// <param name="element">Element to parse children.</param> | 1064 | /// <param name="element">Element to parse children.</param> |
1533 | public void ParseForExtensionElements(XElement element) | 1065 | public void ParseForExtensionElements(XElement element) |
1534 | { | 1066 | { |
1535 | foreach (XElement child in element.Elements()) | 1067 | this.parseHelper.ParseForExtensionElements(this.extensions.Values, this.intermediate, this.ActiveSection, element); |
1536 | { | ||
1537 | if (element.Name.Namespace == child.Name.Namespace) | ||
1538 | { | ||
1539 | this.UnexpectedElement(element, child); | ||
1540 | } | ||
1541 | else | ||
1542 | { | ||
1543 | this.ParseExtensionElement(element, child); | ||
1544 | } | ||
1545 | } | ||
1546 | } | 1068 | } |
1547 | 1069 | ||
1548 | /// <summary> | 1070 | /// <summary> |
@@ -1553,20 +1075,7 @@ namespace WixToolset | |||
1553 | /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param> | 1075 | /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param> |
1554 | public ComponentKeyPath ParsePossibleKeyPathExtensionElement(XElement parentElement, XElement element, IDictionary<string, string> context) | 1076 | public ComponentKeyPath ParsePossibleKeyPathExtensionElement(XElement parentElement, XElement element, IDictionary<string, string> context) |
1555 | { | 1077 | { |
1556 | ComponentKeyPath keyPath = null; | 1078 | return this.parseHelper.ParsePossibleKeyPathExtensionElement(this.extensions.Values, this.intermediate, this.ActiveSection, parentElement, element, context); |
1557 | |||
1558 | ICompilerExtension extension; | ||
1559 | if (this.TryFindExtension(element.Name.Namespace, out extension)) | ||
1560 | { | ||
1561 | keyPath = extension.ParsePossibleKeyPathElement(parentElement, element, context); | ||
1562 | } | ||
1563 | else | ||
1564 | { | ||
1565 | SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(element); | ||
1566 | this.OnMessage(WixErrors.UnhandledExtensionElement(childSourceLineNumbers, parentElement.Name.LocalName, element.Name.LocalName, element.Name.NamespaceName)); | ||
1567 | } | ||
1568 | |||
1569 | return keyPath; | ||
1570 | } | 1079 | } |
1571 | 1080 | ||
1572 | /// <summary> | 1081 | /// <summary> |
@@ -1576,8 +1085,7 @@ namespace WixToolset | |||
1576 | /// <param name="attribute">The unexpected attribute.</param> | 1085 | /// <param name="attribute">The unexpected attribute.</param> |
1577 | public void UnexpectedAttribute(XElement element, XAttribute attribute) | 1086 | public void UnexpectedAttribute(XElement element, XAttribute attribute) |
1578 | { | 1087 | { |
1579 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(element); | 1088 | this.parseHelper.UnexpectedAttribute(element, attribute); |
1580 | Common.UnexpectedAttribute(sourceLineNumbers, attribute); | ||
1581 | } | 1089 | } |
1582 | 1090 | ||
1583 | /// <summary> | 1091 | /// <summary> |
@@ -1587,9 +1095,7 @@ namespace WixToolset | |||
1587 | /// <param name="childElement">The unexpected child element.</param> | 1095 | /// <param name="childElement">The unexpected child element.</param> |
1588 | public void UnexpectedElement(XElement parentElement, XElement childElement) | 1096 | public void UnexpectedElement(XElement parentElement, XElement childElement) |
1589 | { | 1097 | { |
1590 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(childElement); | 1098 | this.parseHelper.UnexpectedElement(parentElement, childElement); |
1591 | |||
1592 | this.OnMessage(WixErrors.UnexpectedElement(sourceLineNumbers, parentElement.Name.LocalName, childElement.Name.LocalName)); | ||
1593 | } | 1099 | } |
1594 | 1100 | ||
1595 | /// <summary> | 1101 | /// <summary> |
@@ -1667,30 +1173,6 @@ namespace WixToolset | |||
1667 | } | 1173 | } |
1668 | 1174 | ||
1669 | /// <summary> | 1175 | /// <summary> |
1670 | /// Creates a WiX complex reference in the active section. | ||
1671 | /// </summary> | ||
1672 | /// <param name="sourceLineNumbers">Source line information.</param> | ||
1673 | /// <param name="parentType">The parent type.</param> | ||
1674 | /// <param name="parentId">The parent id.</param> | ||
1675 | /// <param name="parentLanguage">The parent language.</param> | ||
1676 | /// <param name="childType">The child type.</param> | ||
1677 | /// <param name="childId">The child id.</param> | ||
1678 | /// <param name="isPrimary">Whether the child is primary.</param> | ||
1679 | internal void CreateWixComplexReferenceRow(SourceLineNumber sourceLineNumbers, ComplexReferenceParentType parentType, string parentId, string parentLanguage, ComplexReferenceChildType childType, string childId, bool isPrimary) | ||
1680 | { | ||
1681 | if (!this.EncounteredError) | ||
1682 | { | ||
1683 | var wixComplexReferenceRow = (WixComplexReferenceTuple)this.CreateRow(sourceLineNumbers, TupleDefinitionType.WixComplexReference); | ||
1684 | wixComplexReferenceRow.Parent = parentId; | ||
1685 | wixComplexReferenceRow.ParentType = parentType; | ||
1686 | wixComplexReferenceRow.ParentLanguage = parentLanguage; | ||
1687 | wixComplexReferenceRow.Child = childId; | ||
1688 | wixComplexReferenceRow.ChildType = childType; | ||
1689 | wixComplexReferenceRow.IsPrimary = isPrimary; | ||
1690 | } | ||
1691 | } | ||
1692 | |||
1693 | /// <summary> | ||
1694 | /// Creates WixComplexReference and WixGroup rows in the active section. | 1176 | /// Creates WixComplexReference and WixGroup rows in the active section. |
1695 | /// </summary> | 1177 | /// </summary> |
1696 | /// <param name="sourceLineNumbers">Source line information.</param> | 1178 | /// <param name="sourceLineNumbers">Source line information.</param> |
@@ -1702,8 +1184,7 @@ namespace WixToolset | |||
1702 | /// <param name="isPrimary">Whether the child is primary.</param> | 1184 | /// <param name="isPrimary">Whether the child is primary.</param> |
1703 | public void CreateComplexReference(SourceLineNumber sourceLineNumbers, ComplexReferenceParentType parentType, string parentId, string parentLanguage, ComplexReferenceChildType childType, string childId, bool isPrimary) | 1185 | public void CreateComplexReference(SourceLineNumber sourceLineNumbers, ComplexReferenceParentType parentType, string parentId, string parentLanguage, ComplexReferenceChildType childType, string childId, bool isPrimary) |
1704 | { | 1186 | { |
1705 | this.CreateWixComplexReferenceRow(sourceLineNumbers, parentType, parentId, parentLanguage, childType, childId, isPrimary); | 1187 | this.parseHelper.CreateComplexReference(this.ActiveSection, sourceLineNumbers, parentType, parentId, parentLanguage, childType, childId, isPrimary); |
1706 | this.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, childType, childId); | ||
1707 | } | 1188 | } |
1708 | 1189 | ||
1709 | /// <summary> | 1190 | /// <summary> |
@@ -1719,56 +1200,57 @@ namespace WixToolset | |||
1719 | /// <returns>Identifier for the newly created row.</returns> | 1200 | /// <returns>Identifier for the newly created row.</returns> |
1720 | internal Identifier CreateDirectoryRow(SourceLineNumber sourceLineNumbers, Identifier id, string parentId, string name, string shortName = null, string sourceName = null, string shortSourceName = null) | 1201 | internal Identifier CreateDirectoryRow(SourceLineNumber sourceLineNumbers, Identifier id, string parentId, string name, string shortName = null, string sourceName = null, string shortSourceName = null) |
1721 | { | 1202 | { |
1722 | string defaultDir = null; | 1203 | //string defaultDir = null; |
1723 | 1204 | ||
1724 | if (name.Equals("SourceDir") || this.IsValidShortFilename(name, false)) | 1205 | //if (name.Equals("SourceDir") || this.IsValidShortFilename(name, false)) |
1725 | { | 1206 | //{ |
1726 | defaultDir = name; | 1207 | // defaultDir = name; |
1727 | } | 1208 | //} |
1728 | else | 1209 | //else |
1729 | { | 1210 | //{ |
1730 | if (String.IsNullOrEmpty(shortName)) | 1211 | // if (String.IsNullOrEmpty(shortName)) |
1731 | { | 1212 | // { |
1732 | shortName = this.CreateShortName(name, false, false, "Directory", parentId); | 1213 | // shortName = this.CreateShortName(name, false, false, "Directory", parentId); |
1733 | } | 1214 | // } |
1734 | 1215 | ||
1735 | defaultDir = String.Concat(shortName, "|", name); | 1216 | // defaultDir = String.Concat(shortName, "|", name); |
1736 | } | 1217 | //} |
1737 | 1218 | ||
1738 | if (!String.IsNullOrEmpty(sourceName)) | 1219 | //if (!String.IsNullOrEmpty(sourceName)) |
1739 | { | 1220 | //{ |
1740 | if (this.IsValidShortFilename(sourceName, false)) | 1221 | // if (this.IsValidShortFilename(sourceName, false)) |
1741 | { | 1222 | // { |
1742 | defaultDir = String.Concat(defaultDir, ":", sourceName); | 1223 | // defaultDir = String.Concat(defaultDir, ":", sourceName); |
1743 | } | 1224 | // } |
1744 | else | 1225 | // else |
1745 | { | 1226 | // { |
1746 | if (String.IsNullOrEmpty(shortSourceName)) | 1227 | // if (String.IsNullOrEmpty(shortSourceName)) |
1747 | { | 1228 | // { |
1748 | shortSourceName = this.CreateShortName(sourceName, false, false, "Directory", parentId); | 1229 | // shortSourceName = this.CreateShortName(sourceName, false, false, "Directory", parentId); |
1749 | } | 1230 | // } |
1750 | 1231 | ||
1751 | defaultDir = String.Concat(defaultDir, ":", shortSourceName, "|", sourceName); | 1232 | // defaultDir = String.Concat(defaultDir, ":", shortSourceName, "|", sourceName); |
1752 | } | 1233 | // } |
1753 | } | 1234 | //} |
1754 | 1235 | ||
1755 | // For anonymous directories, create the identifier. If this identifier already exists in the | 1236 | //// For anonymous directories, create the identifier. If this identifier already exists in the |
1756 | // active section, bail so we don't add duplicate anonymous directory rows (which are legal | 1237 | //// active section, bail so we don't add duplicate anonymous directory rows (which are legal |
1757 | // but bloat the intermediate and ultimately make the linker do "busy work"). | 1238 | //// but bloat the intermediate and ultimately make the linker do "busy work"). |
1758 | if (null == id) | 1239 | //if (null == id) |
1759 | { | 1240 | //{ |
1760 | id = this.CreateIdentifier("dir", parentId, name, shortName, sourceName, shortSourceName); | 1241 | // id = this.CreateIdentifier("dir", parentId, name, shortName, sourceName, shortSourceName); |
1761 | 1242 | ||
1762 | if (!this.activeSectionInlinedDirectoryIds.Add(id.Id)) | 1243 | // if (!this.activeSectionInlinedDirectoryIds.Add(id.Id)) |
1763 | { | 1244 | // { |
1764 | return id; | 1245 | // return id; |
1765 | } | 1246 | // } |
1766 | } | 1247 | //} |
1767 | 1248 | ||
1768 | var row = this.CreateRow(sourceLineNumbers, TupleDefinitionType.Directory, id); | 1249 | //var row = this.CreateRow(sourceLineNumbers, TupleDefinitionType.Directory, id); |
1769 | row.Set(1, parentId); | 1250 | //row.Set(1, parentId); |
1770 | row.Set(2, defaultDir); | 1251 | //row.Set(2, defaultDir); |
1771 | return id; | 1252 | //return id; |
1253 | return this.parseHelper.CreateDirectoryRow(this.ActiveSection, sourceLineNumbers, id, parentId, name, shortName, sourceName, shortSourceName, this.activeSectionInlinedDirectoryIds); | ||
1772 | } | 1254 | } |
1773 | 1255 | ||
1774 | /// <summary> | 1256 | /// <summary> |
@@ -1780,65 +1262,7 @@ namespace WixToolset | |||
1780 | /// <returns>Inline directory syntax split into array of strings or null if the syntax did not parse.</returns> | 1262 | /// <returns>Inline directory syntax split into array of strings or null if the syntax did not parse.</returns> |
1781 | internal string[] GetAttributeInlineDirectorySyntax(SourceLineNumber sourceLineNumbers, XAttribute attribute, bool resultUsedToCreateReference = false) | 1263 | internal string[] GetAttributeInlineDirectorySyntax(SourceLineNumber sourceLineNumbers, XAttribute attribute, bool resultUsedToCreateReference = false) |
1782 | { | 1264 | { |
1783 | string[] result = null; | 1265 | return this.parseHelper.GetAttributeInlineDirectorySyntax(sourceLineNumbers, attribute, resultUsedToCreateReference); |
1784 | string value = this.GetAttributeValue(sourceLineNumbers, attribute); | ||
1785 | |||
1786 | if (!String.IsNullOrEmpty(value)) | ||
1787 | { | ||
1788 | int pathStartsAt = 0; | ||
1789 | result = value.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); | ||
1790 | if (result[0].EndsWith(":", StringComparison.Ordinal)) | ||
1791 | { | ||
1792 | string id = result[0].TrimEnd(':'); | ||
1793 | if (1 == result.Length) | ||
1794 | { | ||
1795 | this.OnMessage(WixErrors.InlineDirectorySyntaxRequiresPath(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, id)); | ||
1796 | return null; | ||
1797 | } | ||
1798 | else if (!this.IsValidIdentifier(id)) | ||
1799 | { | ||
1800 | this.OnMessage(WixErrors.IllegalIdentifier(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, id)); | ||
1801 | return null; | ||
1802 | } | ||
1803 | |||
1804 | pathStartsAt = 1; | ||
1805 | } | ||
1806 | else if (resultUsedToCreateReference && 1 == result.Length) | ||
1807 | { | ||
1808 | if (value.EndsWith("\\")) | ||
1809 | { | ||
1810 | if (!this.IsValidLongFilename(result[0])) | ||
1811 | { | ||
1812 | this.OnMessage(WixErrors.IllegalLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, result[0])); | ||
1813 | return null; | ||
1814 | } | ||
1815 | } | ||
1816 | else if (!this.IsValidIdentifier(result[0])) | ||
1817 | { | ||
1818 | this.OnMessage(WixErrors.IllegalIdentifier(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, result[0])); | ||
1819 | return null; | ||
1820 | } | ||
1821 | |||
1822 | return result; // return early to avoid additional checks below. | ||
1823 | } | ||
1824 | |||
1825 | // Check each part of the relative path to ensure that it is a valid directory name. | ||
1826 | for (int i = pathStartsAt; i < result.Length; ++i) | ||
1827 | { | ||
1828 | if (!this.IsValidLongFilename(result[i])) | ||
1829 | { | ||
1830 | this.OnMessage(WixErrors.IllegalLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, result[i])); | ||
1831 | return null; | ||
1832 | } | ||
1833 | } | ||
1834 | |||
1835 | if (1 < result.Length && !value.EndsWith("\\")) | ||
1836 | { | ||
1837 | this.OnMessage(WixWarnings.BackslashTerminateInlineDirectorySyntax(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
1838 | } | ||
1839 | } | ||
1840 | |||
1841 | return result; | ||
1842 | } | 1266 | } |
1843 | 1267 | ||
1844 | /// <summary> | 1268 | /// <summary> |
diff --git a/src/WixToolset.Core/Converter.cs b/src/WixToolset.Core/Converter.cs index 6ae2f984..c0297758 100644 --- a/src/WixToolset.Core/Converter.cs +++ b/src/WixToolset.Core/Converter.cs | |||
@@ -1,6 +1,6 @@ | |||
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. | 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 | 2 | ||
3 | namespace WixToolset | 3 | namespace WixToolset.Core |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
diff --git a/src/WixToolset.Core/Extensibility/HeatExtension.cs b/src/WixToolset.Core/Extensibility/HeatExtension.cs index 48e1a93b..2b4a6823 100644 --- a/src/WixToolset.Core/Extensibility/HeatExtension.cs +++ b/src/WixToolset.Core/Extensibility/HeatExtension.cs | |||
@@ -1,6 +1,6 @@ | |||
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. | 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 | 2 | ||
3 | namespace WixToolset.Extensibility | 3 | namespace WixToolset.Core.Extensibility |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.IO; | 6 | using System.IO; |
diff --git a/src/WixToolset.Core/Extensibility/IHeatCore.cs b/src/WixToolset.Core/Extensibility/IHeatCore.cs index dbfc8929..031c8132 100644 --- a/src/WixToolset.Core/Extensibility/IHeatCore.cs +++ b/src/WixToolset.Core/Extensibility/IHeatCore.cs | |||
@@ -1,6 +1,6 @@ | |||
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. | 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 | 2 | ||
3 | namespace WixToolset.Extensibility | 3 | namespace WixToolset.Core.Extensibility |
4 | { | 4 | { |
5 | using WixToolset.Data; | 5 | using WixToolset.Data; |
6 | 6 | ||
diff --git a/src/WixToolset.Core/Extensibility/MutatorExtension.cs b/src/WixToolset.Core/Extensibility/MutatorExtension.cs index 9de64180..f95b5b11 100644 --- a/src/WixToolset.Core/Extensibility/MutatorExtension.cs +++ b/src/WixToolset.Core/Extensibility/MutatorExtension.cs | |||
@@ -1,6 +1,6 @@ | |||
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. | 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 | 2 | ||
3 | namespace WixToolset.Extensibility | 3 | namespace WixToolset.Core.Extensibility |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
diff --git a/src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs b/src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs new file mode 100644 index 00000000..87ad0da8 --- /dev/null +++ b/src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs | |||
@@ -0,0 +1,824 @@ | |||
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.ExtensibilityServices | ||
4 | { | ||
5 | using System; | ||
6 | using System.Collections.Generic; | ||
7 | using System.Diagnostics; | ||
8 | using System.Globalization; | ||
9 | using System.IO; | ||
10 | using System.Security.Cryptography; | ||
11 | using System.Text; | ||
12 | using System.Text.RegularExpressions; | ||
13 | using System.Xml.Linq; | ||
14 | using WixToolset.Data; | ||
15 | using WixToolset.Data.Tuples; | ||
16 | using WixToolset.Extensibility; | ||
17 | using WixToolset.Extensibility.Services; | ||
18 | |||
19 | internal class ParseHelper : IParseHelper | ||
20 | { | ||
21 | private const string LegalLongFilenameCharacters = @"[^\\\?|><:/\*""]"; // opposite of illegal above. | ||
22 | private static readonly Regex LegalLongFilename = new Regex(String.Concat("^", LegalLongFilenameCharacters, @"{1,259}$"), RegexOptions.Compiled); | ||
23 | |||
24 | private const string LegalRelativeLongFilenameCharacters = @"[^\?|><:/\*""]"; // (like legal long, but we allow '\') illegal: ? | > < : / * " | ||
25 | private static readonly Regex LegalRelativeLongFilename = new Regex(String.Concat("^", LegalRelativeLongFilenameCharacters, @"{1,259}$"), RegexOptions.Compiled); | ||
26 | |||
27 | private const string LegalWildcardLongFilenameCharacters = @"[^\\|><:/""]"; // illegal: \ | > < : / " | ||
28 | private static readonly Regex LegalWildcardLongFilename = new Regex(String.Concat("^", LegalWildcardLongFilenameCharacters, @"{1,259}$")); | ||
29 | |||
30 | private static readonly Regex LegalIdentifierWithAccess = new Regex(@"^((?<access>public|internal|protected|private)\s+)?(?<id>[_A-Za-z][0-9A-Za-z_\.]*)$", RegexOptions.Compiled | RegexOptions.ExplicitCapture); | ||
31 | |||
32 | private static readonly Regex PutGuidHere = new Regex(@"PUT\-GUID\-(?:\d+\-)?HERE", RegexOptions.Singleline); | ||
33 | |||
34 | public ParseHelper(IServiceProvider serviceProvider) | ||
35 | { | ||
36 | this.ServiceProvider = serviceProvider; | ||
37 | } | ||
38 | |||
39 | private IServiceProvider ServiceProvider { get; } | ||
40 | |||
41 | private ITupleDefinitionCreator Creator { get; set; } | ||
42 | |||
43 | public bool ContainsProperty(string possibleProperty) | ||
44 | { | ||
45 | return Common.ContainsProperty(possibleProperty); | ||
46 | } | ||
47 | |||
48 | public void CreateComplexReference(IntermediateSection section, SourceLineNumber sourceLineNumbers, ComplexReferenceParentType parentType, string parentId, string parentLanguage, ComplexReferenceChildType childType, string childId, bool isPrimary) | ||
49 | { | ||
50 | var wixComplexReferenceRow = (WixComplexReferenceTuple)this.CreateRow(section, sourceLineNumbers, TupleDefinitionType.WixComplexReference); | ||
51 | wixComplexReferenceRow.Parent = parentId; | ||
52 | wixComplexReferenceRow.ParentType = parentType; | ||
53 | wixComplexReferenceRow.ParentLanguage = parentLanguage; | ||
54 | wixComplexReferenceRow.Child = childId; | ||
55 | wixComplexReferenceRow.ChildType = childType; | ||
56 | wixComplexReferenceRow.IsPrimary = isPrimary; | ||
57 | |||
58 | this.CreateWixGroupRow(section, sourceLineNumbers, parentType, parentId, childType, childId); | ||
59 | } | ||
60 | |||
61 | public Identifier CreateDirectoryRow(IntermediateSection section, SourceLineNumber sourceLineNumbers, Identifier id, string parentId, string name, string shortName = null, string sourceName = null, string shortSourceName = null, ISet<string> sectionInlinedDirectoryIds = null) | ||
62 | { | ||
63 | string defaultDir = null; | ||
64 | |||
65 | if (name.Equals("SourceDir") || this.IsValidShortFilename(name, false)) | ||
66 | { | ||
67 | defaultDir = name; | ||
68 | } | ||
69 | else | ||
70 | { | ||
71 | if (String.IsNullOrEmpty(shortName)) | ||
72 | { | ||
73 | shortName = this.CreateShortName(name, false, false, "Directory", parentId); | ||
74 | } | ||
75 | |||
76 | defaultDir = String.Concat(shortName, "|", name); | ||
77 | } | ||
78 | |||
79 | if (!String.IsNullOrEmpty(sourceName)) | ||
80 | { | ||
81 | if (this.IsValidShortFilename(sourceName, false)) | ||
82 | { | ||
83 | defaultDir = String.Concat(defaultDir, ":", sourceName); | ||
84 | } | ||
85 | else | ||
86 | { | ||
87 | if (String.IsNullOrEmpty(shortSourceName)) | ||
88 | { | ||
89 | shortSourceName = this.CreateShortName(sourceName, false, false, "Directory", parentId); | ||
90 | } | ||
91 | |||
92 | defaultDir = String.Concat(defaultDir, ":", shortSourceName, "|", sourceName); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | // For anonymous directories, create the identifier. If this identifier already exists in the | ||
97 | // active section, bail so we don't add duplicate anonymous directory rows (which are legal | ||
98 | // but bloat the intermediate and ultimately make the linker do "busy work"). | ||
99 | if (null == id) | ||
100 | { | ||
101 | id = this.CreateIdentifier("dir", parentId, name, shortName, sourceName, shortSourceName); | ||
102 | |||
103 | if (!sectionInlinedDirectoryIds.Add(id.Id)) | ||
104 | { | ||
105 | return id; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | var row = this.CreateRow(section, sourceLineNumbers, TupleDefinitionType.Directory, id); | ||
110 | row.Set(1, parentId); | ||
111 | row.Set(2, defaultDir); | ||
112 | return id; | ||
113 | } | ||
114 | |||
115 | public string CreateDirectoryReferenceFromInlineSyntax(IntermediateSection section, SourceLineNumber sourceLineNumbers, XAttribute attribute, string parentId) | ||
116 | { | ||
117 | string id = null; | ||
118 | string[] inlineSyntax = this.GetAttributeInlineDirectorySyntax(sourceLineNumbers, attribute, true); | ||
119 | |||
120 | if (null != inlineSyntax) | ||
121 | { | ||
122 | // Special case the single entry in the inline syntax since it is the most common case | ||
123 | // and needs no extra processing. It's just a reference to an existing directory. | ||
124 | if (1 == inlineSyntax.Length) | ||
125 | { | ||
126 | id = inlineSyntax[0]; | ||
127 | this.CreateSimpleReference(section, sourceLineNumbers, "Directory", id); | ||
128 | } | ||
129 | else // start creating rows for the entries in the inline syntax | ||
130 | { | ||
131 | id = parentId; | ||
132 | |||
133 | int pathStartsAt = 0; | ||
134 | if (inlineSyntax[0].EndsWith(":")) | ||
135 | { | ||
136 | // TODO: should overriding the parent identifier with a specific id be an error or a warning or just let it slide? | ||
137 | //if (null != parentId) | ||
138 | //{ | ||
139 | // this.core.OnMessage(WixErrors.Xxx(sourceLineNumbers)); | ||
140 | //} | ||
141 | |||
142 | id = inlineSyntax[0].TrimEnd(':'); | ||
143 | this.CreateSimpleReference(section, sourceLineNumbers, "Directory", id); | ||
144 | |||
145 | pathStartsAt = 1; | ||
146 | } | ||
147 | |||
148 | for (int i = pathStartsAt; i < inlineSyntax.Length; ++i) | ||
149 | { | ||
150 | Identifier inlineId = this.CreateDirectoryRow(section, sourceLineNumbers, null, id, inlineSyntax[i]); | ||
151 | id = inlineId.Id; | ||
152 | } | ||
153 | } | ||
154 | } | ||
155 | |||
156 | return id; | ||
157 | } | ||
158 | |||
159 | public string CreateGuid(Guid namespaceGuid, string value) | ||
160 | { | ||
161 | return Uuid.NewUuid(namespaceGuid, value).ToString("B").ToUpperInvariant(); | ||
162 | } | ||
163 | |||
164 | public Identifier CreateIdentifier(string prefix, params string[] args) | ||
165 | { | ||
166 | var id = Common.GenerateIdentifier(prefix, args); | ||
167 | return new Identifier(id, AccessModifier.Private); | ||
168 | } | ||
169 | |||
170 | public Identifier CreateIdentifierFromFilename(string filename) | ||
171 | { | ||
172 | var id = Common.GetIdentifierFromName(filename); | ||
173 | return new Identifier(id, AccessModifier.Private); | ||
174 | } | ||
175 | |||
176 | public Identifier CreateRegistryRow(IntermediateSection section, SourceLineNumber sourceLineNumbers, int root, string key, string name, string value, string componentId, bool escapeLeadingHash) | ||
177 | { | ||
178 | Identifier id = null; | ||
179 | |||
180 | if (-1 > root || 3 < root) | ||
181 | { | ||
182 | throw new ArgumentOutOfRangeException("root"); | ||
183 | } | ||
184 | |||
185 | if (null == key) | ||
186 | { | ||
187 | throw new ArgumentNullException("key"); | ||
188 | } | ||
189 | |||
190 | if (null == componentId) | ||
191 | { | ||
192 | throw new ArgumentNullException("componentId"); | ||
193 | } | ||
194 | |||
195 | // Escape the leading '#' character for string registry values. | ||
196 | if (escapeLeadingHash && null != value && value.StartsWith("#", StringComparison.Ordinal)) | ||
197 | { | ||
198 | value = String.Concat("#", value); | ||
199 | } | ||
200 | |||
201 | id = this.CreateIdentifier("reg", componentId, root.ToString(CultureInfo.InvariantCulture.NumberFormat), key.ToLowerInvariant(), (null != name ? name.ToLowerInvariant() : name)); | ||
202 | |||
203 | var row = this.CreateRow(section, sourceLineNumbers, TupleDefinitionType.Registry, id); | ||
204 | row.Set(1, root); | ||
205 | row.Set(2, key); | ||
206 | row.Set(3, name); | ||
207 | row.Set(4, value); | ||
208 | row.Set(5, componentId); | ||
209 | |||
210 | return id; | ||
211 | } | ||
212 | |||
213 | public void CreateSimpleReference(IntermediateSection section, SourceLineNumber sourceLineNumbers, string tableName, params string[] primaryKeys) | ||
214 | { | ||
215 | var joinedKeys = String.Join("/", primaryKeys); | ||
216 | var id = String.Concat(tableName, ":", joinedKeys); | ||
217 | |||
218 | var wixSimpleReferenceRow = (WixSimpleReferenceTuple)this.CreateRow(section, sourceLineNumbers, TupleDefinitionType.WixSimpleReference); | ||
219 | wixSimpleReferenceRow.Table = tableName; | ||
220 | wixSimpleReferenceRow.PrimaryKeys = joinedKeys; | ||
221 | } | ||
222 | |||
223 | public void CreateWixGroupRow(IntermediateSection section, SourceLineNumber sourceLineNumbers, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType childType, string childId) | ||
224 | { | ||
225 | if (null == parentId || ComplexReferenceParentType.Unknown == parentType) | ||
226 | { | ||
227 | return; | ||
228 | } | ||
229 | |||
230 | if (null == childId) | ||
231 | { | ||
232 | throw new ArgumentNullException("childId"); | ||
233 | } | ||
234 | |||
235 | var row = (WixGroupTuple)this.CreateRow(section, sourceLineNumbers, TupleDefinitionType.WixGroup); | ||
236 | row.ParentId = parentId; | ||
237 | row.ParentType = parentType; | ||
238 | row.ChildId = childId; | ||
239 | row.ChildType = childType; | ||
240 | } | ||
241 | |||
242 | public IntermediateTuple CreateRow(IntermediateSection section, SourceLineNumber sourceLineNumbers, string tableName, Identifier identifier = null) | ||
243 | { | ||
244 | if (this.Creator == null) | ||
245 | { | ||
246 | this.CreateTupleDefinitionCreator(); | ||
247 | } | ||
248 | |||
249 | if (!this.Creator.TryGetTupleDefinitionByName(tableName, out var tupleDefinition)) | ||
250 | { | ||
251 | throw new ArgumentException(nameof(tableName)); | ||
252 | } | ||
253 | |||
254 | return CreateRow(section, sourceLineNumbers, tupleDefinition, identifier); | ||
255 | } | ||
256 | |||
257 | public IntermediateTuple CreateRow(IntermediateSection section, SourceLineNumber sourceLineNumbers, TupleDefinitionType tupleType, Identifier identifier = null) | ||
258 | { | ||
259 | var tupleDefinition = TupleDefinitions.ByType(tupleType); | ||
260 | |||
261 | return CreateRow(section, sourceLineNumbers, tupleDefinition, identifier); | ||
262 | } | ||
263 | |||
264 | public string CreateShortName(string longName, bool keepExtension, bool allowWildcards, params string[] args) | ||
265 | { | ||
266 | // canonicalize the long name if its not a localization identifier (they are case-sensitive) | ||
267 | if (!this.IsValidLocIdentifier(longName)) | ||
268 | { | ||
269 | longName = longName.ToLowerInvariant(); | ||
270 | } | ||
271 | |||
272 | // collect all the data | ||
273 | List<string> strings = new List<string>(1 + args.Length); | ||
274 | strings.Add(longName); | ||
275 | strings.AddRange(args); | ||
276 | |||
277 | // prepare for hashing | ||
278 | string stringData = String.Join("|", strings); | ||
279 | byte[] data = Encoding.UTF8.GetBytes(stringData); | ||
280 | |||
281 | // hash the data | ||
282 | byte[] hash; | ||
283 | using (var sha1 = new SHA1CryptoServiceProvider()) | ||
284 | { | ||
285 | hash = sha1.ComputeHash(data); | ||
286 | } | ||
287 | |||
288 | // generate the short file/directory name without an extension | ||
289 | StringBuilder shortName = new StringBuilder(Convert.ToBase64String(hash)); | ||
290 | shortName.Remove(8, shortName.Length - 8).Replace('+', '-').Replace('/', '_'); | ||
291 | |||
292 | if (keepExtension) | ||
293 | { | ||
294 | string extension = Path.GetExtension(longName); | ||
295 | |||
296 | if (4 < extension.Length) | ||
297 | { | ||
298 | extension = extension.Substring(0, 4); | ||
299 | } | ||
300 | |||
301 | shortName.Append(extension); | ||
302 | |||
303 | // check the generated short name to ensure its still legal (the extension may not be legal) | ||
304 | if (!this.IsValidShortFilename(shortName.ToString(), allowWildcards)) | ||
305 | { | ||
306 | // remove the extension (by truncating the generated file name back to the generated characters) | ||
307 | shortName.Length -= extension.Length; | ||
308 | } | ||
309 | } | ||
310 | |||
311 | return shortName.ToString().ToLowerInvariant(); | ||
312 | } | ||
313 | |||
314 | public void EnsureTable(IntermediateSection section, SourceLineNumber sourceLineNumbers, string tableName) | ||
315 | { | ||
316 | var row = this.CreateRow(section, sourceLineNumbers, TupleDefinitionType.WixEnsureTable); | ||
317 | row.Set(0, tableName); | ||
318 | |||
319 | if (this.Creator == null) | ||
320 | { | ||
321 | this.CreateTupleDefinitionCreator(); | ||
322 | } | ||
323 | |||
324 | // We don't add custom table definitions to the tableDefinitions collection, | ||
325 | // so if it's not in there, it better be a custom table. If the Id is just wrong, | ||
326 | // instead of a custom table, we get an unresolved reference at link time. | ||
327 | if (!this.Creator.TryGetTupleDefinitionByName(tableName, out var ignored)) | ||
328 | { | ||
329 | this.CreateSimpleReference(section, sourceLineNumbers, "WixCustomTable", tableName); | ||
330 | } | ||
331 | } | ||
332 | |||
333 | public string GetAttributeGuidValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, bool generatable = false, bool canBeEmpty = false) | ||
334 | { | ||
335 | if (null == attribute) | ||
336 | { | ||
337 | throw new ArgumentNullException("attribute"); | ||
338 | } | ||
339 | |||
340 | EmptyRule emptyRule = canBeEmpty ? EmptyRule.CanBeEmpty : EmptyRule.CanBeWhitespaceOnly; | ||
341 | string value = this.GetAttributeValue(sourceLineNumbers, attribute, emptyRule); | ||
342 | |||
343 | if (String.IsNullOrEmpty(value) && canBeEmpty) | ||
344 | { | ||
345 | return String.Empty; | ||
346 | } | ||
347 | else if (!String.IsNullOrEmpty(value)) | ||
348 | { | ||
349 | // If the value starts and ends with braces or parenthesis, accept that and strip them off. | ||
350 | if ((value.StartsWith("{", StringComparison.Ordinal) && value.EndsWith("}", StringComparison.Ordinal)) | ||
351 | || (value.StartsWith("(", StringComparison.Ordinal) && value.EndsWith(")", StringComparison.Ordinal))) | ||
352 | { | ||
353 | value = value.Substring(1, value.Length - 2); | ||
354 | } | ||
355 | |||
356 | if (generatable && "*".Equals(value, StringComparison.Ordinal)) | ||
357 | { | ||
358 | return value; | ||
359 | } | ||
360 | |||
361 | if (ParseHelper.PutGuidHere.IsMatch(value)) | ||
362 | { | ||
363 | Messaging.Instance.OnMessage(WixErrors.ExampleGuid(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
364 | return CompilerConstants.IllegalGuid; | ||
365 | } | ||
366 | else if (value.StartsWith("!(loc", StringComparison.Ordinal) || value.StartsWith("$(loc", StringComparison.Ordinal) || value.StartsWith("!(wix", StringComparison.Ordinal)) | ||
367 | { | ||
368 | return value; | ||
369 | } | ||
370 | else if (Guid.TryParse(value, out var guid)) | ||
371 | { | ||
372 | var uppercaseGuid = guid.ToString().ToUpperInvariant(); | ||
373 | |||
374 | // TODO: This used to be a pedantic error, what should it be now? | ||
375 | //if (uppercaseGuid != value) | ||
376 | //{ | ||
377 | // Messaging.Instance.OnMessage(WixErrors.GuidContainsLowercaseLetters(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
378 | //} | ||
379 | |||
380 | return String.Concat("{", uppercaseGuid, "}"); | ||
381 | } | ||
382 | else | ||
383 | { | ||
384 | Messaging.Instance.OnMessage(WixErrors.IllegalGuidValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
385 | } | ||
386 | } | ||
387 | |||
388 | return CompilerConstants.IllegalGuid; | ||
389 | } | ||
390 | |||
391 | public Identifier GetAttributeIdentifier(SourceLineNumber sourceLineNumbers, XAttribute attribute) | ||
392 | { | ||
393 | var access = AccessModifier.Public; | ||
394 | var value = Common.GetAttributeValue(sourceLineNumbers, attribute, EmptyRule.CanBeEmpty); | ||
395 | |||
396 | var match = ParseHelper.LegalIdentifierWithAccess.Match(value); | ||
397 | if (!match.Success) | ||
398 | { | ||
399 | return null; | ||
400 | } | ||
401 | else if (match.Groups["access"].Success) | ||
402 | { | ||
403 | access = (AccessModifier)Enum.Parse(typeof(AccessModifier), match.Groups["access"].Value, true); | ||
404 | } | ||
405 | |||
406 | value = match.Groups["id"].Value; | ||
407 | |||
408 | if (Common.IsIdentifier(value) && 72 < value.Length) | ||
409 | { | ||
410 | Messaging.Instance.OnMessage(WixWarnings.IdentifierTooLong(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
411 | } | ||
412 | |||
413 | return new Identifier(value, access); | ||
414 | } | ||
415 | |||
416 | public string GetAttributeIdentifierValue(SourceLineNumber sourceLineNumbers, XAttribute attribute) | ||
417 | { | ||
418 | return Common.GetAttributeIdentifierValue(sourceLineNumbers, attribute); | ||
419 | } | ||
420 | |||
421 | public string[] GetAttributeInlineDirectorySyntax(SourceLineNumber sourceLineNumbers, XAttribute attribute, bool resultUsedToCreateReference = false) | ||
422 | { | ||
423 | string[] result = null; | ||
424 | string value = this.GetAttributeValue(sourceLineNumbers, attribute); | ||
425 | |||
426 | if (!String.IsNullOrEmpty(value)) | ||
427 | { | ||
428 | int pathStartsAt = 0; | ||
429 | result = value.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); | ||
430 | if (result[0].EndsWith(":", StringComparison.Ordinal)) | ||
431 | { | ||
432 | string id = result[0].TrimEnd(':'); | ||
433 | if (1 == result.Length) | ||
434 | { | ||
435 | Messaging.Instance.OnMessage(WixErrors.InlineDirectorySyntaxRequiresPath(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, id)); | ||
436 | return null; | ||
437 | } | ||
438 | else if (!this.IsValidIdentifier(id)) | ||
439 | { | ||
440 | Messaging.Instance.OnMessage(WixErrors.IllegalIdentifier(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, id)); | ||
441 | return null; | ||
442 | } | ||
443 | |||
444 | pathStartsAt = 1; | ||
445 | } | ||
446 | else if (resultUsedToCreateReference && 1 == result.Length) | ||
447 | { | ||
448 | if (value.EndsWith("\\")) | ||
449 | { | ||
450 | if (!this.IsValidLongFilename(result[0], false, false)) | ||
451 | { | ||
452 | Messaging.Instance.OnMessage(WixErrors.IllegalLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, result[0])); | ||
453 | return null; | ||
454 | } | ||
455 | } | ||
456 | else if (!this.IsValidIdentifier(result[0])) | ||
457 | { | ||
458 | Messaging.Instance.OnMessage(WixErrors.IllegalIdentifier(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, result[0])); | ||
459 | return null; | ||
460 | } | ||
461 | |||
462 | return result; // return early to avoid additional checks below. | ||
463 | } | ||
464 | |||
465 | // Check each part of the relative path to ensure that it is a valid directory name. | ||
466 | for (int i = pathStartsAt; i < result.Length; ++i) | ||
467 | { | ||
468 | if (!this.IsValidLongFilename(result[i], false, false)) | ||
469 | { | ||
470 | Messaging.Instance.OnMessage(WixErrors.IllegalLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value, result[i])); | ||
471 | return null; | ||
472 | } | ||
473 | } | ||
474 | |||
475 | if (1 < result.Length && !value.EndsWith("\\")) | ||
476 | { | ||
477 | Messaging.Instance.OnMessage(WixWarnings.BackslashTerminateInlineDirectorySyntax(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
478 | } | ||
479 | } | ||
480 | |||
481 | return result; | ||
482 | } | ||
483 | |||
484 | public int GetAttributeIntegerValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, int minimum, int maximum) | ||
485 | { | ||
486 | return Common.GetAttributeIntegerValue(sourceLineNumbers, attribute, minimum, maximum); | ||
487 | } | ||
488 | |||
489 | public string GetAttributeLongFilename(SourceLineNumber sourceLineNumbers, XAttribute attribute, bool allowWildcards, bool allowRelative) | ||
490 | { | ||
491 | if (null == attribute) | ||
492 | { | ||
493 | throw new ArgumentNullException("attribute"); | ||
494 | } | ||
495 | |||
496 | string value = this.GetAttributeValue(sourceLineNumbers, attribute); | ||
497 | |||
498 | if (0 < value.Length) | ||
499 | { | ||
500 | if (!this.IsValidLongFilename(value, allowWildcards, allowRelative) && !this.IsValidLocIdentifier(value)) | ||
501 | { | ||
502 | if (allowRelative) | ||
503 | { | ||
504 | Messaging.Instance.OnMessage(WixErrors.IllegalRelativeLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
505 | } | ||
506 | else | ||
507 | { | ||
508 | Messaging.Instance.OnMessage(WixErrors.IllegalLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
509 | } | ||
510 | } | ||
511 | else if (allowRelative) | ||
512 | { | ||
513 | string normalizedPath = value.Replace('\\', '/'); | ||
514 | if (normalizedPath.StartsWith("../", StringComparison.Ordinal) || normalizedPath.Contains("/../")) | ||
515 | { | ||
516 | Messaging.Instance.OnMessage(WixErrors.PayloadMustBeRelativeToCache(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
517 | } | ||
518 | } | ||
519 | else if (CompilerCore.IsAmbiguousFilename(value)) | ||
520 | { | ||
521 | Messaging.Instance.OnMessage(WixWarnings.AmbiguousFileOrDirectoryName(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
522 | } | ||
523 | } | ||
524 | |||
525 | return value; | ||
526 | } | ||
527 | |||
528 | public long GetAttributeLongValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, long minimum, long maximum) | ||
529 | { | ||
530 | Debug.Assert(minimum > CompilerConstants.LongNotSet && minimum > CompilerConstants.IllegalLong, "The legal values for this attribute collide with at least one sentinel used during parsing."); | ||
531 | |||
532 | string value = this.GetAttributeValue(sourceLineNumbers, attribute); | ||
533 | |||
534 | if (0 < value.Length) | ||
535 | { | ||
536 | try | ||
537 | { | ||
538 | long longValue = Convert.ToInt64(value, CultureInfo.InvariantCulture.NumberFormat); | ||
539 | |||
540 | if (CompilerConstants.LongNotSet == longValue || CompilerConstants.IllegalLong == longValue) | ||
541 | { | ||
542 | Messaging.Instance.OnMessage(WixErrors.IntegralValueSentinelCollision(sourceLineNumbers, longValue)); | ||
543 | } | ||
544 | else if (minimum > longValue || maximum < longValue) | ||
545 | { | ||
546 | Messaging.Instance.OnMessage(WixErrors.IntegralValueOutOfRange(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, longValue, minimum, maximum)); | ||
547 | longValue = CompilerConstants.IllegalLong; | ||
548 | } | ||
549 | |||
550 | return longValue; | ||
551 | } | ||
552 | catch (FormatException) | ||
553 | { | ||
554 | Messaging.Instance.OnMessage(WixErrors.IllegalLongValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
555 | } | ||
556 | catch (OverflowException) | ||
557 | { | ||
558 | Messaging.Instance.OnMessage(WixErrors.IllegalLongValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
559 | } | ||
560 | } | ||
561 | |||
562 | return CompilerConstants.IllegalLong; | ||
563 | } | ||
564 | |||
565 | public string GetAttributeValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, EmptyRule emptyRule = EmptyRule.CanBeWhitespaceOnly) | ||
566 | { | ||
567 | return Common.GetAttributeValue(sourceLineNumbers, attribute, emptyRule); | ||
568 | } | ||
569 | |||
570 | public string GetAttributeVersionValue(SourceLineNumber sourceLineNumbers, XAttribute attribute) | ||
571 | { | ||
572 | var value = this.GetAttributeValue(sourceLineNumbers, attribute); | ||
573 | |||
574 | if (!String.IsNullOrEmpty(value)) | ||
575 | { | ||
576 | if (Version.TryParse(value, out var version)) | ||
577 | { | ||
578 | return version.ToString(); | ||
579 | } | ||
580 | |||
581 | // Allow versions to contain binder variables. | ||
582 | if (Common.ContainsValidBinderVariable(value)) | ||
583 | { | ||
584 | return value; | ||
585 | } | ||
586 | |||
587 | Messaging.Instance.OnMessage(WixErrors.IllegalVersionValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
588 | } | ||
589 | |||
590 | return null; | ||
591 | } | ||
592 | |||
593 | public YesNoDefaultType GetAttributeYesNoDefaultValue(SourceLineNumber sourceLineNumbers, XAttribute attribute) | ||
594 | { | ||
595 | var value = this.GetAttributeValue(sourceLineNumbers, attribute); | ||
596 | |||
597 | switch (value) | ||
598 | { | ||
599 | case "yes": | ||
600 | case "true": | ||
601 | return YesNoDefaultType.Yes; | ||
602 | |||
603 | case "no": | ||
604 | case "false": | ||
605 | return YesNoDefaultType.No; | ||
606 | |||
607 | case "default": | ||
608 | return YesNoDefaultType.Default; | ||
609 | |||
610 | default: | ||
611 | Messaging.Instance.OnMessage(WixErrors.IllegalYesNoDefaultValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
612 | return YesNoDefaultType.IllegalValue; | ||
613 | } | ||
614 | } | ||
615 | |||
616 | public YesNoType GetAttributeYesNoValue(SourceLineNumber sourceLineNumbers, XAttribute attribute) | ||
617 | { | ||
618 | var value = this.GetAttributeValue(sourceLineNumbers, attribute); | ||
619 | |||
620 | switch (value) | ||
621 | { | ||
622 | case "yes": | ||
623 | case "true": | ||
624 | return YesNoType.Yes; | ||
625 | |||
626 | case "no": | ||
627 | case "false": | ||
628 | return YesNoType.No; | ||
629 | |||
630 | default: | ||
631 | Messaging.Instance.OnMessage(WixErrors.IllegalYesNoValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); | ||
632 | return YesNoType.IllegalValue; | ||
633 | } | ||
634 | } | ||
635 | |||
636 | public string GetConditionInnerText(XElement element) | ||
637 | { | ||
638 | var value = Common.GetInnerText(element)?.Trim().Replace('\t', ' ').Replace('\r', ' ').Replace('\n', ' '); | ||
639 | |||
640 | // Return null for a non-existant condition. | ||
641 | return String.IsNullOrEmpty(value) ? null : value; | ||
642 | } | ||
643 | |||
644 | public string GetTrimmedInnerText(XElement element) | ||
645 | { | ||
646 | var value = Common.GetInnerText(element); | ||
647 | return value?.Trim(); | ||
648 | } | ||
649 | |||
650 | public bool IsValidIdentifier(string value) | ||
651 | { | ||
652 | return Common.IsIdentifier(value); | ||
653 | } | ||
654 | |||
655 | public bool IsValidLocIdentifier(string identifier) | ||
656 | { | ||
657 | if (String.IsNullOrEmpty(identifier)) | ||
658 | { | ||
659 | return false; | ||
660 | } | ||
661 | |||
662 | var match = Common.WixVariableRegex.Match(identifier); | ||
663 | |||
664 | return (match.Success && "loc" == match.Groups["namespace"].Value && 0 == match.Index && identifier.Length == match.Length); | ||
665 | } | ||
666 | |||
667 | public bool IsValidLongFilename(string filename, bool allowWildcards, bool allowRelative) | ||
668 | { | ||
669 | if (String.IsNullOrEmpty(filename)) | ||
670 | { | ||
671 | return false; | ||
672 | } | ||
673 | |||
674 | // Check for a non-period character (all periods is not legal) | ||
675 | bool nonPeriodFound = false; | ||
676 | foreach (char character in filename) | ||
677 | { | ||
678 | if ('.' != character) | ||
679 | { | ||
680 | nonPeriodFound = true; | ||
681 | break; | ||
682 | } | ||
683 | } | ||
684 | |||
685 | if (allowWildcards) | ||
686 | { | ||
687 | return (nonPeriodFound && ParseHelper.LegalWildcardLongFilename.IsMatch(filename)); | ||
688 | } | ||
689 | else if (allowRelative) | ||
690 | { | ||
691 | return (nonPeriodFound && ParseHelper.LegalRelativeLongFilename.IsMatch(filename)); | ||
692 | } | ||
693 | else | ||
694 | { | ||
695 | return (nonPeriodFound && ParseHelper.LegalLongFilename.IsMatch(filename)); | ||
696 | } | ||
697 | } | ||
698 | |||
699 | public bool IsValidShortFilename(string filename, bool allowWildcards = false) | ||
700 | { | ||
701 | return Common.IsValidShortFilename(filename, allowWildcards); | ||
702 | } | ||
703 | |||
704 | public void ParseExtensionAttribute(IEnumerable<ICompilerExtension> extensions, Intermediate intermediate, IntermediateSection section, XElement element, XAttribute attribute, IDictionary<string, string> context = null) | ||
705 | { | ||
706 | // Ignore attributes defined by the W3C because we'll assume they are always right. | ||
707 | if ((String.IsNullOrEmpty(attribute.Name.NamespaceName) && attribute.Name.LocalName.Equals("xmlns", StringComparison.Ordinal)) || | ||
708 | attribute.Name.NamespaceName.StartsWith(CompilerCore.W3SchemaPrefix.NamespaceName, StringComparison.Ordinal)) | ||
709 | { | ||
710 | return; | ||
711 | } | ||
712 | |||
713 | if (ParseHelper.TryFindExtension(extensions, attribute.Name.NamespaceName, out var extension)) | ||
714 | { | ||
715 | extension.ParseAttribute(intermediate, section, element, attribute, context); | ||
716 | } | ||
717 | else | ||
718 | { | ||
719 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(element); | ||
720 | Messaging.Instance.OnMessage(WixErrors.UnhandledExtensionAttribute(sourceLineNumbers, element.Name.LocalName, attribute.Name.LocalName, attribute.Name.NamespaceName)); | ||
721 | } | ||
722 | } | ||
723 | |||
724 | public void ParseExtensionElement(IEnumerable<ICompilerExtension> extensions, Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context = null) | ||
725 | { | ||
726 | if (ParseHelper.TryFindExtension(extensions, element.Name.Namespace, out var extension)) | ||
727 | { | ||
728 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(parentElement); | ||
729 | extension.ParseElement(intermediate, section, parentElement, element, context); | ||
730 | } | ||
731 | else | ||
732 | { | ||
733 | var childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(element); | ||
734 | Messaging.Instance.OnMessage(WixErrors.UnhandledExtensionElement(childSourceLineNumbers, parentElement.Name.LocalName, element.Name.LocalName, element.Name.NamespaceName)); | ||
735 | } | ||
736 | } | ||
737 | |||
738 | public ComponentKeyPath ParsePossibleKeyPathExtensionElement(IEnumerable<ICompilerExtension> extensions, Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context) | ||
739 | { | ||
740 | ComponentKeyPath keyPath = null; | ||
741 | |||
742 | if (ParseHelper.TryFindExtension(extensions, element.Name.Namespace, out var extension)) | ||
743 | { | ||
744 | keyPath = extension.ParsePossibleKeyPathElement(intermediate, section, parentElement, element, context); | ||
745 | } | ||
746 | else | ||
747 | { | ||
748 | var childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(element); | ||
749 | Messaging.Instance.OnMessage(WixErrors.UnhandledExtensionElement(childSourceLineNumbers, parentElement.Name.LocalName, element.Name.LocalName, element.Name.NamespaceName)); | ||
750 | } | ||
751 | |||
752 | return keyPath; | ||
753 | } | ||
754 | |||
755 | public void ParseForExtensionElements(IEnumerable<ICompilerExtension> extensions, Intermediate intermediate, IntermediateSection section, XElement element) | ||
756 | { | ||
757 | foreach (XElement child in element.Elements()) | ||
758 | { | ||
759 | if (element.Name.Namespace == child.Name.Namespace) | ||
760 | { | ||
761 | this.UnexpectedElement(element, child); | ||
762 | } | ||
763 | else | ||
764 | { | ||
765 | this.ParseExtensionElement(extensions, intermediate, section, element, child); | ||
766 | } | ||
767 | } | ||
768 | } | ||
769 | |||
770 | public void UnexpectedAttribute(XElement element, XAttribute attribute) | ||
771 | { | ||
772 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(element); | ||
773 | Common.UnexpectedAttribute(sourceLineNumbers, attribute); | ||
774 | } | ||
775 | |||
776 | public void UnexpectedElement(XElement parentElement, XElement childElement) | ||
777 | { | ||
778 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(childElement); | ||
779 | Messaging.Instance.OnMessage(WixErrors.UnexpectedElement(sourceLineNumbers, parentElement.Name.LocalName, childElement.Name.LocalName)); | ||
780 | } | ||
781 | |||
782 | private void CreateTupleDefinitionCreator() | ||
783 | { | ||
784 | this.Creator = (ITupleDefinitionCreator)this.ServiceProvider.GetService(typeof(ITupleDefinitionCreator)); | ||
785 | } | ||
786 | |||
787 | private static IntermediateTuple CreateRow(IntermediateSection section, SourceLineNumber sourceLineNumbers, IntermediateTupleDefinition tupleDefinition, Identifier identifier) | ||
788 | { | ||
789 | var row = tupleDefinition.CreateTuple(sourceLineNumbers, identifier); | ||
790 | |||
791 | if (null != identifier) | ||
792 | { | ||
793 | if (row.Definition.FieldDefinitions[0].Type == IntermediateFieldType.Number) | ||
794 | { | ||
795 | row.Set(0, Convert.ToInt32(identifier.Id)); | ||
796 | } | ||
797 | else | ||
798 | { | ||
799 | row.Set(0, identifier.Id); | ||
800 | } | ||
801 | } | ||
802 | |||
803 | section.Tuples.Add(row); | ||
804 | |||
805 | return row; | ||
806 | } | ||
807 | |||
808 | private static bool TryFindExtension(IEnumerable<ICompilerExtension> extensions, XNamespace ns, out ICompilerExtension extension) | ||
809 | { | ||
810 | extension = null; | ||
811 | |||
812 | foreach (var ext in extensions) | ||
813 | { | ||
814 | if (ext.Namespace == ns) | ||
815 | { | ||
816 | extension = ext; | ||
817 | break; | ||
818 | } | ||
819 | } | ||
820 | |||
821 | return extension != null; | ||
822 | } | ||
823 | } | ||
824 | } | ||
diff --git a/src/WixToolset.Core/TupleDefinitionCreator.cs b/src/WixToolset.Core/ExtensibilityServices/TupleDefinitionCreator.cs index 8c9b9d29..4075def8 100644 --- a/src/WixToolset.Core/TupleDefinitionCreator.cs +++ b/src/WixToolset.Core/ExtensibilityServices/TupleDefinitionCreator.cs | |||
@@ -1,6 +1,6 @@ | |||
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. | 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 | 2 | ||
3 | namespace WixToolset.Core | 3 | namespace WixToolset.Core.ExtensibilityServices |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
diff --git a/src/WixToolset.Core/HarvesterCore.cs b/src/WixToolset.Core/HarvesterCore.cs index 66a693f2..87e3c33f 100644 --- a/src/WixToolset.Core/HarvesterCore.cs +++ b/src/WixToolset.Core/HarvesterCore.cs | |||
@@ -1,12 +1,11 @@ | |||
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. | 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 | 2 | ||
3 | namespace WixToolset | 3 | namespace WixToolset.Core |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Diagnostics.CodeAnalysis; | 6 | using System.Diagnostics.CodeAnalysis; |
7 | using System.IO; | 7 | using System.IO; |
8 | using WixToolset.Data; | 8 | using WixToolset.Data; |
9 | using Wix = WixToolset.Data.Serialize; | ||
10 | 9 | ||
11 | /// <summary> | 10 | /// <summary> |
12 | /// The WiX Toolset harvester core. | 11 | /// The WiX Toolset harvester core. |
diff --git a/src/WixToolset.Core/HeatCore.cs b/src/WixToolset.Core/HeatCore.cs index 01233c40..2384a1ed 100644 --- a/src/WixToolset.Core/HeatCore.cs +++ b/src/WixToolset.Core/HeatCore.cs | |||
@@ -1,9 +1,9 @@ | |||
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. | 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 | 2 | ||
3 | namespace WixToolset.Tools | 3 | namespace WixToolset.Core |
4 | { | 4 | { |
5 | using WixToolset.Core.Extensibility; | ||
5 | using WixToolset.Data; | 6 | using WixToolset.Data; |
6 | using WixToolset.Extensibility; | ||
7 | 7 | ||
8 | /// <summary> | 8 | /// <summary> |
9 | /// The WiX Toolset Harvester application core. | 9 | /// The WiX Toolset Harvester application core. |
diff --git a/src/WixToolset.Core/Link/WixGroupingOrdering.cs b/src/WixToolset.Core/Link/WixGroupingOrdering.cs index 4dd1596c..f15ebc75 100644 --- a/src/WixToolset.Core/Link/WixGroupingOrdering.cs +++ b/src/WixToolset.Core/Link/WixGroupingOrdering.cs | |||
@@ -1,16 +1,14 @@ | |||
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. | 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 | 2 | ||
3 | namespace WixToolset.Link | 3 | namespace WixToolset.Core.Link |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections; | ||
7 | using System.Collections.ObjectModel; | 6 | using System.Collections.ObjectModel; |
8 | using System.Collections.Generic; | 7 | using System.Collections.Generic; |
9 | using System.Diagnostics; | 8 | using System.Diagnostics; |
10 | using System.Globalization; | 9 | using System.Globalization; |
11 | using System.Linq; | 10 | using System.Linq; |
12 | using System.Text; | 11 | using System.Text; |
13 | using WixToolset.Extensibility; | ||
14 | using WixToolset.Data; | 12 | using WixToolset.Data; |
15 | using WixToolset.Data.Tuples; | 13 | using WixToolset.Data.Tuples; |
16 | 14 | ||
diff --git a/src/WixToolset.Core/Localizer.cs b/src/WixToolset.Core/Localizer.cs index a19c32fb..8265c026 100644 --- a/src/WixToolset.Core/Localizer.cs +++ b/src/WixToolset.Core/Localizer.cs | |||
@@ -1,6 +1,6 @@ | |||
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. | 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 | 2 | ||
3 | namespace WixToolset | 3 | namespace WixToolset.Core |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
diff --git a/src/WixToolset.Core/Mutator.cs b/src/WixToolset.Core/Mutator.cs index d37815f4..f935b570 100644 --- a/src/WixToolset.Core/Mutator.cs +++ b/src/WixToolset.Core/Mutator.cs | |||
@@ -1,10 +1,10 @@ | |||
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. | 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 | 2 | ||
3 | namespace WixToolset | 3 | namespace WixToolset.Core |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections; | 6 | using System.Collections; |
7 | using WixToolset.Extensibility; | 7 | using WixToolset.Core.Extensibility; |
8 | using Wix = WixToolset.Data.Serialize; | 8 | using Wix = WixToolset.Data.Serialize; |
9 | 9 | ||
10 | /// <summary> | 10 | /// <summary> |
diff --git a/src/WixToolset.Core/Preprocessor.cs b/src/WixToolset.Core/Preprocessor.cs index 85b3dab8..23f568a8 100644 --- a/src/WixToolset.Core/Preprocessor.cs +++ b/src/WixToolset.Core/Preprocessor.cs | |||
@@ -1,9 +1,8 @@ | |||
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. | 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 | 2 | ||
3 | namespace WixToolset | 3 | namespace WixToolset.Core |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections; | ||
7 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
8 | using System.Diagnostics.CodeAnalysis; | 7 | using System.Diagnostics.CodeAnalysis; |
9 | using System.Globalization; | 8 | using System.Globalization; |
diff --git a/src/WixToolset.Core/WixToolsetServiceProvider.cs b/src/WixToolset.Core/WixToolsetServiceProvider.cs index dd49e7ed..8693461b 100644 --- a/src/WixToolset.Core/WixToolsetServiceProvider.cs +++ b/src/WixToolset.Core/WixToolsetServiceProvider.cs | |||
@@ -3,6 +3,7 @@ | |||
3 | namespace WixToolset.Core | 3 | namespace WixToolset.Core |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using WixToolset.Core.ExtensibilityServices; | ||
6 | using WixToolset.Data; | 7 | using WixToolset.Data; |
7 | using WixToolset.Extensibility; | 8 | using WixToolset.Extensibility; |
8 | using WixToolset.Extensibility.Services; | 9 | using WixToolset.Extensibility.Services; |
@@ -10,6 +11,7 @@ namespace WixToolset.Core | |||
10 | public class WixToolsetServiceProvider : IServiceProvider | 11 | public class WixToolsetServiceProvider : IServiceProvider |
11 | { | 12 | { |
12 | private ExtensionManager extensionManager; | 13 | private ExtensionManager extensionManager; |
14 | private ParseHelper parseHelper; | ||
13 | private TupleDefinitionCreator tupleDefinitionCreator; | 15 | private TupleDefinitionCreator tupleDefinitionCreator; |
14 | 16 | ||
15 | public object GetService(Type serviceType) | 17 | public object GetService(Type serviceType) |
@@ -58,6 +60,11 @@ namespace WixToolset.Core | |||
58 | return this.tupleDefinitionCreator = this.tupleDefinitionCreator ?? new TupleDefinitionCreator(this); | 60 | return this.tupleDefinitionCreator = this.tupleDefinitionCreator ?? new TupleDefinitionCreator(this); |
59 | } | 61 | } |
60 | 62 | ||
63 | if (serviceType == typeof(IParseHelper)) | ||
64 | { | ||
65 | return this.parseHelper = this.parseHelper ?? new ParseHelper(this); | ||
66 | } | ||
67 | |||
61 | throw new ArgumentException($"Unknown service type: {serviceType.Name}", nameof(serviceType)); | 68 | throw new ArgumentException($"Unknown service type: {serviceType.Name}", nameof(serviceType)); |
62 | } | 69 | } |
63 | } | 70 | } |