aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBob Arnson <bob@firegiant.com>2023-10-23 00:17:18 -0400
committerBob Arnson <github@bobs.org>2023-10-28 21:18:18 -0400
commitb84202794f5fd4f21e0fb1fc74c2f5d531035db3 (patch)
treecdf4f858489a50fefef122843837252c760ef4c0 /src
parentbb691bde8bff680ead1e6b0cf41cf3af7736331b (diff)
downloadwix-b84202794f5fd4f21e0fb1fc74c2f5d531035db3.tar.gz
wix-b84202794f5fd4f21e0fb1fc74c2f5d531035db3.tar.bz2
wix-b84202794f5fd4f21e0fb1fc74c2f5d531035db3.zip
Introduce a new phase in the build pipeline.
A useful point in the build pipeline is after all the files in the project have been compiled but before they've been linked. The WiX core and extensions can operate on symbols across the project but without operating at the source-code level. This phase is currently named "optimize," after a moderately-similar phase in other compiler architectures. The name is, for now, a stake in the ground and a better alternate is welcome.
Diffstat (limited to 'src')
-rw-r--r--src/api/wix/WixToolset.Extensibility/BaseOptimizerExtension.cs26
-rw-r--r--src/api/wix/WixToolset.Extensibility/Data/ICompileContext.cs2
-rw-r--r--src/api/wix/WixToolset.Extensibility/Data/IOptimizeContext.cs61
-rw-r--r--src/api/wix/WixToolset.Extensibility/IOptimizerExtension.cs22
-rw-r--r--src/wix/WixToolset.Core/CommandLine/BuildCommand.cs19
-rw-r--r--src/wix/WixToolset.Core/IOptimizer.cs17
-rw-r--r--src/wix/WixToolset.Core/OptimizeContext.cs39
-rw-r--r--src/wix/WixToolset.Core/Optimizer.cs36
-rw-r--r--src/wix/WixToolset.Core/WixToolsetServiceProvider.cs2
-rw-r--r--src/wix/test/Example.Extension/ExampleExtensionFactory.cs4
-rw-r--r--src/wix/test/Example.Extension/ExampleOptimizerExtension.cs22
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/ExtensionFixture.cs4
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExampleExtension/Decompiled-Expected.xml2
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/WixlibFixture.cs4
14 files changed, 253 insertions, 7 deletions
diff --git a/src/api/wix/WixToolset.Extensibility/BaseOptimizerExtension.cs b/src/api/wix/WixToolset.Extensibility/BaseOptimizerExtension.cs
new file mode 100644
index 00000000..5bb89272
--- /dev/null
+++ b/src/api/wix/WixToolset.Extensibility/BaseOptimizerExtension.cs
@@ -0,0 +1,26 @@
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
3namespace WixToolset.Extensibility
4{
5 using WixToolset.Extensibility.Data;
6
7 /// <summary>
8 /// Base class for creating an optimizer extension.
9 /// </summary>
10 public abstract class BaseOptimizerExtension : IOptimizerExtension
11 {
12 /// <summary>
13 /// Called after all files have been compiled, before built-in optimizations, and before all sections are linked into a single section.
14 /// </summary>
15 public virtual void PreOptimize(IOptimizeContext context)
16 {
17 }
18
19 /// <summary>
20 /// Called after all files have been compiled, after built-in optimizations, and before all sections are linked into a single section.
21 /// </summary>
22 public virtual void PostOptimize(IOptimizeContext context)
23 {
24 }
25 }
26}
diff --git a/src/api/wix/WixToolset.Extensibility/Data/ICompileContext.cs b/src/api/wix/WixToolset.Extensibility/Data/ICompileContext.cs
index 7006fde8..cfccd0a9 100644
--- a/src/api/wix/WixToolset.Extensibility/Data/ICompileContext.cs
+++ b/src/api/wix/WixToolset.Extensibility/Data/ICompileContext.cs
@@ -55,7 +55,7 @@ namespace WixToolset.Extensibility.Data
55 XDocument Source { get; set; } 55 XDocument Source { get; set; }
56 56
57 /// <summary> 57 /// <summary>
58 /// Cancellation token to abort cancellation. 58 /// Cancellation token.
59 /// </summary> 59 /// </summary>
60 CancellationToken CancellationToken { get; set; } 60 CancellationToken CancellationToken { get; set; }
61 } 61 }
diff --git a/src/api/wix/WixToolset.Extensibility/Data/IOptimizeContext.cs b/src/api/wix/WixToolset.Extensibility/Data/IOptimizeContext.cs
new file mode 100644
index 00000000..5684ebcd
--- /dev/null
+++ b/src/api/wix/WixToolset.Extensibility/Data/IOptimizeContext.cs
@@ -0,0 +1,61 @@
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
3namespace WixToolset.Extensibility.Data
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Threading;
8 using WixToolset.Data;
9
10 /// <summary>
11 /// Context provided to the optimizer.
12 /// </summary>
13 public interface IOptimizeContext
14 {
15 /// <summary>
16 /// Service provider made available to the optimizer and its extensions.
17 /// </summary>
18 IServiceProvider ServiceProvider { get; }
19
20 /// <summary>
21 /// Set of extensions provided to the optimizer.
22 /// </summary>
23 IReadOnlyCollection<IOptimizerExtension> Extensions { get; set; }
24
25 /// <summary>
26 /// Intermediate folder.
27 /// </summary>
28 string IntermediateFolder { get; set; }
29
30 /// <summary>
31 /// Collection of bindpaths used to bind files.
32 /// </summary>
33 IReadOnlyCollection<IBindPath> BindPaths { get; set; }
34
35 /// <summary>
36 /// Bind variables used during optimization.
37 /// </summary>
38 IDictionary<string, string> BindVariables { get; set; }
39
40 /// <summary>
41 /// Gets or sets the platform which the optimizer will use when defaulting 64-bit symbol properties.
42 /// </summary>
43 /// <value>The platform which the optimizer will use when defaulting 64-bit symbol properties.</value>
44 Platform Platform { get; set; }
45
46 /// <summary>
47 /// Collection of intermediates to optimize.
48 /// </summary>
49 IReadOnlyCollection<Intermediate> Intermediates { get; set; }
50
51 /// <summary>
52 /// Collection of localization files to use in the optimizer.
53 /// </summary>
54 IReadOnlyCollection<Localization> Localizations { get; set; }
55
56 /// <summary>
57 /// Cancellation token.
58 /// </summary>
59 CancellationToken CancellationToken { get; set; }
60 }
61}
diff --git a/src/api/wix/WixToolset.Extensibility/IOptimizerExtension.cs b/src/api/wix/WixToolset.Extensibility/IOptimizerExtension.cs
new file mode 100644
index 00000000..589e7ecc
--- /dev/null
+++ b/src/api/wix/WixToolset.Extensibility/IOptimizerExtension.cs
@@ -0,0 +1,22 @@
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
3namespace WixToolset.Extensibility
4{
5 using WixToolset.Extensibility.Data;
6
7 /// <summary>
8 /// Interface that all optimizer extensions implement.
9 /// </summary>
10 public interface IOptimizerExtension
11 {
12 /// <summary>
13 /// Called after all files have been compiled, before built-in optimizations, and before all sections are linked into a single section.
14 /// </summary>
15 void PreOptimize(IOptimizeContext context);
16
17 /// <summary>
18 /// Called after all files have been compiled, after built-in optimizations, and before all sections are linked into a single section.
19 /// </summary>
20 void PostOptimize(IOptimizeContext context);
21 }
22}
diff --git a/src/wix/WixToolset.Core/CommandLine/BuildCommand.cs b/src/wix/WixToolset.Core/CommandLine/BuildCommand.cs
index 68dbd768..2ad18073 100644
--- a/src/wix/WixToolset.Core/CommandLine/BuildCommand.cs
+++ b/src/wix/WixToolset.Core/CommandLine/BuildCommand.cs
@@ -10,7 +10,6 @@ namespace WixToolset.Core.CommandLine
10 using System.Threading.Tasks; 10 using System.Threading.Tasks;
11 using System.Xml.Linq; 11 using System.Xml.Linq;
12 using WixToolset.Data; 12 using WixToolset.Data;
13 using WixToolset.Data.Bind;
14 using WixToolset.Extensibility; 13 using WixToolset.Extensibility;
15 using WixToolset.Extensibility.Data; 14 using WixToolset.Extensibility.Data;
16 using WixToolset.Extensibility.Services; 15 using WixToolset.Extensibility.Services;
@@ -112,6 +111,8 @@ namespace WixToolset.Core.CommandLine
112 return Task.FromResult(this.Messaging.LastErrorNumber); 111 return Task.FromResult(this.Messaging.LastErrorNumber);
113 } 112 }
114 113
114 this.OptimizePhase(wixobjs, wxls, this.commandLine.BindPaths, this.commandLine.BindVariables, cancellationToken);
115
115 if (inputsOutputs.OutputType == OutputType.Library) 116 if (inputsOutputs.OutputType == OutputType.Library)
116 { 117 {
117 using (new IntermediateFieldContext("wix.lib")) 118 using (new IntermediateFieldContext("wix.lib"))
@@ -207,6 +208,22 @@ namespace WixToolset.Core.CommandLine
207 return intermediates; 208 return intermediates;
208 } 209 }
209 210
211 private void OptimizePhase(IReadOnlyCollection<Intermediate> intermediates, IReadOnlyCollection<Localization> localizations, IReadOnlyCollection<IBindPath> bindPaths, Dictionary<string, string> bindVariables, CancellationToken cancellationToken)
212 {
213 var context = this.ServiceProvider.GetService<IOptimizeContext>();
214 context.Extensions = this.ExtensionManager.GetServices<IOptimizerExtension>();
215 context.IntermediateFolder = this.IntermediateFolder;
216 context.BindPaths = bindPaths;
217 context.BindVariables = bindVariables;
218 context.Platform = this.Platform;
219 context.Intermediates = intermediates;
220 context.Localizations = localizations;
221 context.CancellationToken = cancellationToken;
222
223 var optimizer = this.ServiceProvider.GetService<IOptimizer>();
224 optimizer.Optimize(context);
225 }
226
210 private void LibraryPhase(IReadOnlyCollection<Intermediate> intermediates, IReadOnlyCollection<Localization> localizations, IEnumerable<string> libraryFiles, ISymbolDefinitionCreator creator, bool bindFiles, IReadOnlyCollection<IBindPath> bindPaths, Dictionary<string, string> bindVariables, string outputPath, CancellationToken cancellationToken) 227 private void LibraryPhase(IReadOnlyCollection<Intermediate> intermediates, IReadOnlyCollection<Localization> localizations, IEnumerable<string> libraryFiles, ISymbolDefinitionCreator creator, bool bindFiles, IReadOnlyCollection<IBindPath> bindPaths, Dictionary<string, string> bindVariables, string outputPath, CancellationToken cancellationToken)
211 { 228 {
212 var libraries = this.LoadLibraries(libraryFiles, creator); 229 var libraries = this.LoadLibraries(libraryFiles, creator);
diff --git a/src/wix/WixToolset.Core/IOptimizer.cs b/src/wix/WixToolset.Core/IOptimizer.cs
new file mode 100644
index 00000000..85c90b80
--- /dev/null
+++ b/src/wix/WixToolset.Core/IOptimizer.cs
@@ -0,0 +1,17 @@
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
3namespace WixToolset.Core
4{
5 using WixToolset.Extensibility.Data;
6
7 /// <summary>
8 /// Interface for built-in optimizer.
9 /// </summary>
10 public interface IOptimizer
11 {
12 /// <summary>
13 /// Called after all files have been compiled and before all sections are linked into a single section.
14 /// </summary>
15 void Optimize(IOptimizeContext context);
16 }
17}
diff --git a/src/wix/WixToolset.Core/OptimizeContext.cs b/src/wix/WixToolset.Core/OptimizeContext.cs
new file mode 100644
index 00000000..93b6c354
--- /dev/null
+++ b/src/wix/WixToolset.Core/OptimizeContext.cs
@@ -0,0 +1,39 @@
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
3namespace WixToolset.Core
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Threading;
8 using WixToolset.Data;
9 using WixToolset.Extensibility;
10 using WixToolset.Extensibility.Data;
11
12 internal class OptimizeContext : IOptimizeContext
13 {
14 internal OptimizeContext(IServiceProvider serviceProvider)
15 {
16 this.ServiceProvider = serviceProvider;
17 }
18
19 public IServiceProvider ServiceProvider { get; }
20
21 public IReadOnlyCollection<IOptimizerExtension> Extensions { get; set; }
22
23 public string IntermediateFolder { get; set; }
24
25 public IReadOnlyCollection<IBindPath> BindPaths { get; set; }
26
27 public IDictionary<string, string> BindVariables { get; set; }
28
29 public Platform Platform { get; set; }
30
31 public bool IsCurrentPlatform64Bit => this.Platform == Platform.ARM64 || this.Platform == Platform.X64;
32
33 public IReadOnlyCollection<Intermediate> Intermediates { get; set; }
34
35 public IReadOnlyCollection<Localization> Localizations { get; set; }
36
37 public CancellationToken CancellationToken { get; set; }
38 }
39}
diff --git a/src/wix/WixToolset.Core/Optimizer.cs b/src/wix/WixToolset.Core/Optimizer.cs
new file mode 100644
index 00000000..5864121e
--- /dev/null
+++ b/src/wix/WixToolset.Core/Optimizer.cs
@@ -0,0 +1,36 @@
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
3namespace WixToolset.Core
4{
5 using System;
6 using WixToolset.Extensibility.Data;
7 using WixToolset.Extensibility.Services;
8
9 internal class Optimizer : IOptimizer
10 {
11 internal Optimizer(IServiceProvider serviceProvider)
12 {
13 this.ServiceProvider = serviceProvider;
14 this.Messaging = this.ServiceProvider.GetService<IMessaging>();
15 }
16
17 private IServiceProvider ServiceProvider { get; }
18
19 private IMessaging Messaging { get; }
20
21 public void Optimize(IOptimizeContext context)
22 {
23 foreach (var extension in context.Extensions)
24 {
25 extension.PreOptimize(context);
26 }
27
28 // TODO: Fill with useful optimization features.
29
30 foreach (var extension in context.Extensions)
31 {
32 extension.PostOptimize(context);
33 }
34 }
35 }
36}
diff --git a/src/wix/WixToolset.Core/WixToolsetServiceProvider.cs b/src/wix/WixToolset.Core/WixToolsetServiceProvider.cs
index 5620bcd2..cb8dbd87 100644
--- a/src/wix/WixToolset.Core/WixToolsetServiceProvider.cs
+++ b/src/wix/WixToolset.Core/WixToolsetServiceProvider.cs
@@ -37,6 +37,7 @@ namespace WixToolset.Core
37 this.AddService<ICommandLine>((provider, singletons) => new CommandLine.CommandLine(provider)); 37 this.AddService<ICommandLine>((provider, singletons) => new CommandLine.CommandLine(provider));
38 this.AddService<IPreprocessContext>((provider, singletons) => new PreprocessContext(provider)); 38 this.AddService<IPreprocessContext>((provider, singletons) => new PreprocessContext(provider));
39 this.AddService<ICompileContext>((provider, singletons) => new CompileContext(provider)); 39 this.AddService<ICompileContext>((provider, singletons) => new CompileContext(provider));
40 this.AddService<IOptimizeContext>((provider, singletons) => new OptimizeContext(provider));
40 this.AddService<ILibraryContext>((provider, singletons) => new LibraryContext(provider)); 41 this.AddService<ILibraryContext>((provider, singletons) => new LibraryContext(provider));
41 this.AddService<ILibraryResult>((provider, singletons) => new LibraryResult()); 42 this.AddService<ILibraryResult>((provider, singletons) => new LibraryResult());
42 this.AddService<ILinkContext>((provider, singletons) => new LinkContext(provider)); 43 this.AddService<ILinkContext>((provider, singletons) => new LinkContext(provider));
@@ -58,6 +59,7 @@ namespace WixToolset.Core
58 59
59 this.AddService<IBinder>((provider, singletons) => new Binder(provider)); 60 this.AddService<IBinder>((provider, singletons) => new Binder(provider));
60 this.AddService<ICompiler>((provider, singletons) => new Compiler(provider)); 61 this.AddService<ICompiler>((provider, singletons) => new Compiler(provider));
62 this.AddService<IOptimizer>((provider, singletons) => new Optimizer(provider));
61 this.AddService<ILayoutCreator>((provider, singletons) => new LayoutCreator(provider)); 63 this.AddService<ILayoutCreator>((provider, singletons) => new LayoutCreator(provider));
62 this.AddService<IPreprocessor>((provider, singletons) => new Preprocessor(provider)); 64 this.AddService<IPreprocessor>((provider, singletons) => new Preprocessor(provider));
63 this.AddService<ILibrarian>((provider, singletons) => new Librarian(provider)); 65 this.AddService<ILibrarian>((provider, singletons) => new Librarian(provider));
diff --git a/src/wix/test/Example.Extension/ExampleExtensionFactory.cs b/src/wix/test/Example.Extension/ExampleExtensionFactory.cs
index 0b0fb836..16eea6dc 100644
--- a/src/wix/test/Example.Extension/ExampleExtensionFactory.cs
+++ b/src/wix/test/Example.Extension/ExampleExtensionFactory.cs
@@ -35,6 +35,10 @@ namespace Example.Extension
35 { 35 {
36 extension = new ExampleCompilerExtension(); 36 extension = new ExampleCompilerExtension();
37 } 37 }
38 else if (extensionType == typeof(IOptimizerExtension))
39 {
40 extension = new ExampleOptimizerExtension();
41 }
38 else if (extensionType == typeof(IExtensionData)) 42 else if (extensionType == typeof(IExtensionData))
39 { 43 {
40 extension = new ExampleExtensionData(); 44 extension = new ExampleExtensionData();
diff --git a/src/wix/test/Example.Extension/ExampleOptimizerExtension.cs b/src/wix/test/Example.Extension/ExampleOptimizerExtension.cs
new file mode 100644
index 00000000..6a2cb91e
--- /dev/null
+++ b/src/wix/test/Example.Extension/ExampleOptimizerExtension.cs
@@ -0,0 +1,22 @@
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
3namespace Example.Extension
4{
5 using System.Linq;
6 using WixToolset.Extensibility;
7 using WixToolset.Extensibility.Data;
8
9 internal class ExampleOptimizerExtension : BaseOptimizerExtension
10 {
11 public override void PostOptimize(IOptimizeContext context)
12 {
13 foreach (var intermediate in context.Intermediates)
14 {
15 foreach (var symbol in intermediate.Sections.SelectMany(s=>s.Symbols).OfType<ExampleSymbol>())
16 {
17 symbol.Value = $"{symbol.Value} <optimized>";
18 }
19 }
20 }
21 }
22}
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/ExtensionFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/ExtensionFixture.cs
index 710f3b8d..429226f5 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/ExtensionFixture.cs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/ExtensionFixture.cs
@@ -24,7 +24,7 @@ namespace WixToolsetTest.CoreIntegration
24 var results = build.BuildAndQuery(Build, "Wix4Example"); 24 var results = build.BuildAndQuery(Build, "Wix4Example");
25 WixAssert.CompareLineByLine(new[] 25 WixAssert.CompareLineByLine(new[]
26 { 26 {
27 "Wix4Example:Foo\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo\tBar" 27 "Wix4Example:Foo\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo\tBar <optimized>"
28 }, results); 28 }, results);
29 } 29 }
30 30
@@ -92,7 +92,7 @@ namespace WixToolsetTest.CoreIntegration
92 var example = section.Symbols.Where(t => t.Definition.Type == SymbolDefinitionType.MustBeFromAnExtension).Single(); 92 var example = section.Symbols.Where(t => t.Definition.Type == SymbolDefinitionType.MustBeFromAnExtension).Single();
93 WixAssert.StringEqual("Foo", example.Id?.Id); 93 WixAssert.StringEqual("Foo", example.Id?.Id);
94 WixAssert.StringEqual("filF5_pLhBuF5b4N9XEo52g_hUM5Lo", example[0].AsString()); 94 WixAssert.StringEqual("filF5_pLhBuF5b4N9XEo52g_hUM5Lo", example[0].AsString());
95 WixAssert.StringEqual("Bar", example[1].AsString()); 95 WixAssert.StringEqual("Bar <optimized>", example[1].AsString());
96 } 96 }
97 } 97 }
98 98
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExampleExtension/Decompiled-Expected.xml b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExampleExtension/Decompiled-Expected.xml
index 42ececb1..0375b3b6 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExampleExtension/Decompiled-Expected.xml
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExampleExtension/Decompiled-Expected.xml
@@ -5,7 +5,7 @@
5 <StandardDirectory Id="ProgramFilesFolder"> 5 <StandardDirectory Id="ProgramFilesFolder">
6 <Directory Id="INSTALLFOLDER" ShortName="oekcr5lq" Name="MsiPackage"> 6 <Directory Id="INSTALLFOLDER" ShortName="oekcr5lq" Name="MsiPackage">
7 <Component Id="filF5_pLhBuF5b4N9XEo52g_hUM5Lo" Guid="{GUID}" Bitness="always32"> 7 <Component Id="filF5_pLhBuF5b4N9XEo52g_hUM5Lo" Guid="{GUID}" Bitness="always32">
8 <Example Id="Foo" Value="Bar" xmlns="http://www.example.com/scheams/v1/wxs" /> 8 <Example Id="Foo" Value="Bar &lt;optimized&gt;" xmlns="http://www.example.com/scheams/v1/wxs" />
9 <File Id="filF5_pLhBuF5b4N9XEo52g_hUM5Lo" Name="example.txt" KeyPath="yes" Source="PFiles\MsiPackage\example.txt" /> 9 <File Id="filF5_pLhBuF5b4N9XEo52g_hUM5Lo" Name="example.txt" KeyPath="yes" Source="PFiles\MsiPackage\example.txt" />
10 </Component> 10 </Component>
11 </Directory> 11 </Directory>
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/WixlibFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/WixlibFixture.cs
index 76326741..0cd8a542 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/WixlibFixture.cs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/WixlibFixture.cs
@@ -288,7 +288,7 @@ namespace WixToolsetTest.CoreIntegration
288 288
289 var example = section.Symbols.Where(t => t.Definition.Type == SymbolDefinitionType.MustBeFromAnExtension).Single(); 289 var example = section.Symbols.Where(t => t.Definition.Type == SymbolDefinitionType.MustBeFromAnExtension).Single();
290 WixAssert.StringEqual("Foo", example.Id?.Id); 290 WixAssert.StringEqual("Foo", example.Id?.Id);
291 WixAssert.StringEqual("Bar", example[1].AsString()); 291 WixAssert.StringEqual("Bar <optimized>", example[1].AsString());
292 } 292 }
293 } 293 }
294 294
@@ -351,7 +351,7 @@ namespace WixToolsetTest.CoreIntegration
351 var examples = section.Symbols.Where(t => t.Definition.Type == SymbolDefinitionType.MustBeFromAnExtension).ToArray(); 351 var examples = section.Symbols.Where(t => t.Definition.Type == SymbolDefinitionType.MustBeFromAnExtension).ToArray();
352 WixAssert.CompareLineByLine(new[] { "Foo", "Other" }, examples.Select(t => t.Id?.Id).ToArray()); 352 WixAssert.CompareLineByLine(new[] { "Foo", "Other" }, examples.Select(t => t.Id?.Id).ToArray());
353 WixAssert.CompareLineByLine(new[] { "filF5_pLhBuF5b4N9XEo52g_hUM5Lo", "filvxdStJhRE_M5kbpLsTZJXbs34Sg" }, examples.Select(t => t[0].AsString()).ToArray()); 353 WixAssert.CompareLineByLine(new[] { "filF5_pLhBuF5b4N9XEo52g_hUM5Lo", "filvxdStJhRE_M5kbpLsTZJXbs34Sg" }, examples.Select(t => t[0].AsString()).ToArray());
354 WixAssert.CompareLineByLine(new[] { "Bar", "Value" }, examples.Select(t => t[1].AsString()).ToArray()); 354 WixAssert.CompareLineByLine(new[] { "Bar <optimized>", "Value <optimized>" }, examples.Select(t => t[1].AsString()).ToArray());
355 } 355 }
356 } 356 }
357 } 357 }