diff options
| author | Rob Mensching <rob@firegiant.com> | 2018-10-18 13:42:54 -0700 |
|---|---|---|
| committer | Rob Mensching <rob@robmensching.com> | 2018-10-24 21:17:34 -0700 |
| commit | 13eedbfcf97e402ade06f2be29f98723ef7ff286 (patch) | |
| tree | 50155e7f0e9ee253b709a95b488b1a427fa0e013 /src | |
| parent | d98126dc766b9b063d2d26ced62553d4a5a218b5 (diff) | |
| download | wix-13eedbfcf97e402ade06f2be29f98723ef7ff286.tar.gz wix-13eedbfcf97e402ade06f2be29f98723ef7ff286.tar.bz2 wix-13eedbfcf97e402ade06f2be29f98723ef7ff286.zip | |
Extract interfaces for Preprocess/Compile/Link/Bind/etc
Diffstat (limited to 'src')
30 files changed, 928 insertions, 790 deletions
diff --git a/src/WixToolset.Core.Burn/BundleBackend.cs b/src/WixToolset.Core.Burn/BundleBackend.cs index 96a35b14..3baa526e 100644 --- a/src/WixToolset.Core.Burn/BundleBackend.cs +++ b/src/WixToolset.Core.Burn/BundleBackend.cs | |||
| @@ -27,6 +27,11 @@ namespace WixToolset.Core.Burn | |||
| 27 | return new BindResult { FileTransfers = command.FileTransfers, TrackedFiles = command.TrackedFiles }; | 27 | return new BindResult { FileTransfers = command.FileTransfers, TrackedFiles = command.TrackedFiles }; |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | public BindResult Decompile(IDecompileContext context) | ||
| 31 | { | ||
| 32 | throw new NotImplementedException(); | ||
| 33 | } | ||
| 34 | |||
| 30 | public bool Inscribe(IInscribeContext context) | 35 | public bool Inscribe(IInscribeContext context) |
| 31 | { | 36 | { |
| 32 | if (String.IsNullOrEmpty(context.SignedEngineFile)) | 37 | if (String.IsNullOrEmpty(context.SignedEngineFile)) |
diff --git a/src/WixToolset.Core.Burn/BurnBackendFactory.cs b/src/WixToolset.Core.Burn/BurnBackendFactory.cs index 5f98ada9..4b2e833f 100644 --- a/src/WixToolset.Core.Burn/BurnBackendFactory.cs +++ b/src/WixToolset.Core.Burn/BurnBackendFactory.cs | |||
| @@ -9,7 +9,7 @@ namespace WixToolset.Core.Burn | |||
| 9 | 9 | ||
| 10 | internal class BurnBackendFactory : IBackendFactory | 10 | internal class BurnBackendFactory : IBackendFactory |
| 11 | { | 11 | { |
| 12 | public bool TryCreateBackend(string outputType, string outputFile, IBindContext context, out IBackend backend) | 12 | public bool TryCreateBackend(string outputType, string outputFile, out IBackend backend) |
| 13 | { | 13 | { |
| 14 | if (String.IsNullOrEmpty(outputType)) | 14 | if (String.IsNullOrEmpty(outputType)) |
| 15 | { | 15 | { |
diff --git a/src/WixToolset.Core.WindowsInstaller/MsiBackend.cs b/src/WixToolset.Core.WindowsInstaller/MsiBackend.cs index c0c518f8..8b63ae9a 100644 --- a/src/WixToolset.Core.WindowsInstaller/MsiBackend.cs +++ b/src/WixToolset.Core.WindowsInstaller/MsiBackend.cs | |||
| @@ -38,6 +38,11 @@ namespace WixToolset.Core.WindowsInstaller | |||
| 38 | return result; | 38 | return result; |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | public BindResult Decompile(IDecompileContext context) | ||
| 42 | { | ||
| 43 | throw new NotImplementedException(); | ||
| 44 | } | ||
| 45 | |||
| 41 | public bool Inscribe(IInscribeContext context) | 46 | public bool Inscribe(IInscribeContext context) |
| 42 | { | 47 | { |
| 43 | var command = new InscribeMsiPackageCommand(context); | 48 | var command = new InscribeMsiPackageCommand(context); |
diff --git a/src/WixToolset.Core.WindowsInstaller/MsmBackend.cs b/src/WixToolset.Core.WindowsInstaller/MsmBackend.cs index 6c97f08d..c12e6c79 100644 --- a/src/WixToolset.Core.WindowsInstaller/MsmBackend.cs +++ b/src/WixToolset.Core.WindowsInstaller/MsmBackend.cs | |||
| @@ -43,6 +43,11 @@ namespace WixToolset.Core.WindowsInstaller | |||
| 43 | return result; | 43 | return result; |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | public BindResult Decompile(IDecompileContext context) | ||
| 47 | { | ||
| 48 | throw new NotImplementedException(); | ||
| 49 | } | ||
| 50 | |||
| 46 | public bool Inscribe(IInscribeContext context) | 51 | public bool Inscribe(IInscribeContext context) |
| 47 | { | 52 | { |
| 48 | return false; | 53 | return false; |
diff --git a/src/WixToolset.Core.WindowsInstaller/MspBackend.cs b/src/WixToolset.Core.WindowsInstaller/MspBackend.cs index a47802bb..c6a05b20 100644 --- a/src/WixToolset.Core.WindowsInstaller/MspBackend.cs +++ b/src/WixToolset.Core.WindowsInstaller/MspBackend.cs | |||
| @@ -21,6 +21,11 @@ namespace WixToolset.Core.WindowsInstaller | |||
| 21 | throw new NotImplementedException(); | 21 | throw new NotImplementedException(); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | public BindResult Decompile(IDecompileContext context) | ||
| 25 | { | ||
| 26 | throw new NotImplementedException(); | ||
| 27 | } | ||
| 28 | |||
| 24 | public bool Inscribe(IInscribeContext context) | 29 | public bool Inscribe(IInscribeContext context) |
| 25 | { | 30 | { |
| 26 | throw new NotImplementedException(); | 31 | throw new NotImplementedException(); |
diff --git a/src/WixToolset.Core.WindowsInstaller/MstBackend.cs b/src/WixToolset.Core.WindowsInstaller/MstBackend.cs index fa696d55..3e105963 100644 --- a/src/WixToolset.Core.WindowsInstaller/MstBackend.cs +++ b/src/WixToolset.Core.WindowsInstaller/MstBackend.cs | |||
| @@ -25,6 +25,11 @@ namespace WixToolset.Core.WindowsInstaller | |||
| 25 | throw new NotImplementedException(); | 25 | throw new NotImplementedException(); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | public BindResult Decompile(IDecompileContext context) | ||
| 29 | { | ||
| 30 | throw new NotImplementedException(); | ||
| 31 | } | ||
| 32 | |||
| 28 | public bool Inscribe(IInscribeContext context) | 33 | public bool Inscribe(IInscribeContext context) |
| 29 | { | 34 | { |
| 30 | throw new NotImplementedException(); | 35 | throw new NotImplementedException(); |
diff --git a/src/WixToolset.Core.WindowsInstaller/Unbinder.cs b/src/WixToolset.Core.WindowsInstaller/Unbinder.cs index db121fc0..e8c109d2 100644 --- a/src/WixToolset.Core.WindowsInstaller/Unbinder.cs +++ b/src/WixToolset.Core.WindowsInstaller/Unbinder.cs | |||
| @@ -74,7 +74,7 @@ namespace WixToolset.Core | |||
| 74 | 74 | ||
| 75 | foreach (var factory in this.BackendFactories) | 75 | foreach (var factory in this.BackendFactories) |
| 76 | { | 76 | { |
| 77 | if (factory.TryCreateBackend(outputType.ToString(), file, null, out var backend)) | 77 | if (factory.TryCreateBackend(outputType.ToString(), file, out var backend)) |
| 78 | { | 78 | { |
| 79 | return backend.Unbind(context); | 79 | return backend.Unbind(context); |
| 80 | } | 80 | } |
diff --git a/src/WixToolset.Core.WindowsInstaller/WindowsInstallerBackendFactory.cs b/src/WixToolset.Core.WindowsInstaller/WindowsInstallerBackendFactory.cs index 8ffa1a03..173404d7 100644 --- a/src/WixToolset.Core.WindowsInstaller/WindowsInstallerBackendFactory.cs +++ b/src/WixToolset.Core.WindowsInstaller/WindowsInstallerBackendFactory.cs | |||
| @@ -9,7 +9,7 @@ namespace WixToolset.Core.WindowsInstaller | |||
| 9 | 9 | ||
| 10 | internal class WindowsInstallerBackendFactory : IBackendFactory | 10 | internal class WindowsInstallerBackendFactory : IBackendFactory |
| 11 | { | 11 | { |
| 12 | public bool TryCreateBackend(string outputType, string outputFile, IBindContext context, out IBackend backend) | 12 | public bool TryCreateBackend(string outputType, string outputFile, out IBackend backend) |
| 13 | { | 13 | { |
| 14 | if (String.IsNullOrEmpty(outputType)) | 14 | if (String.IsNullOrEmpty(outputType)) |
| 15 | { | 15 | { |
diff --git a/src/WixToolset.Core/Binder.cs b/src/WixToolset.Core/Binder.cs index bbc4173b..87b5d2b3 100644 --- a/src/WixToolset.Core/Binder.cs +++ b/src/WixToolset.Core/Binder.cs | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | namespace WixToolset.Core | 3 | namespace WixToolset.Core |
| 4 | { | 4 | { |
| 5 | using System; | 5 | using System; |
| 6 | using System.Collections.Generic; | ||
| 7 | using System.Diagnostics; | 6 | using System.Diagnostics; |
| 8 | using System.Linq; | 7 | using System.Linq; |
| 9 | using System.Reflection; | 8 | using System.Reflection; |
| @@ -16,61 +15,17 @@ namespace WixToolset.Core | |||
| 16 | /// <summary> | 15 | /// <summary> |
| 17 | /// Binder of the WiX toolset. | 16 | /// Binder of the WiX toolset. |
| 18 | /// </summary> | 17 | /// </summary> |
| 19 | internal class Binder | 18 | internal class Binder : IBinder |
| 20 | { | 19 | { |
| 21 | internal Binder(IServiceProvider serviceProvider) | 20 | internal Binder(IServiceProvider serviceProvider) |
| 22 | { | 21 | { |
| 23 | this.ServiceProvider = serviceProvider; | 22 | this.ServiceProvider = serviceProvider; |
| 24 | } | 23 | } |
| 25 | 24 | ||
| 26 | public int CabbingThreadCount { get; set; } | ||
| 27 | |||
| 28 | public string CabCachePath { get; set; } | ||
| 29 | |||
| 30 | public int Codepage { get; set; } | ||
| 31 | |||
| 32 | public CompressionLevel? DefaultCompressionLevel { get; set; } | ||
| 33 | |||
| 34 | public IEnumerable<IDelayedField> DelayedFields { get; set; } | ||
| 35 | |||
| 36 | public IEnumerable<IExpectedExtractFile> ExpectedEmbeddedFiles { get; set; } | ||
| 37 | |||
| 38 | public IEnumerable<string> Ices { get; set; } | ||
| 39 | |||
| 40 | public string IntermediateFolder { get; set; } | ||
| 41 | |||
| 42 | public Intermediate IntermediateRepresentation { get; set; } | ||
| 43 | |||
| 44 | public string OutputPath { get; set; } | ||
| 45 | |||
| 46 | public string OutputPdbPath { get; set; } | ||
| 47 | |||
| 48 | public IEnumerable<string> SuppressIces { get; set; } | ||
| 49 | |||
| 50 | public bool SuppressValidation { get; set; } | ||
| 51 | |||
| 52 | public bool DeltaBinaryPatch { get; set; } | ||
| 53 | |||
| 54 | public IServiceProvider ServiceProvider { get; } | 25 | public IServiceProvider ServiceProvider { get; } |
| 55 | 26 | ||
| 56 | public BindResult Execute() | 27 | public BindResult Bind(IBindContext context) |
| 57 | { | 28 | { |
| 58 | var context = this.ServiceProvider.GetService<IBindContext>(); | ||
| 59 | context.CabbingThreadCount = this.CabbingThreadCount; | ||
| 60 | context.CabCachePath = this.CabCachePath; | ||
| 61 | context.Codepage = this.Codepage; | ||
| 62 | context.DefaultCompressionLevel = this.DefaultCompressionLevel; | ||
| 63 | context.DelayedFields = this.DelayedFields; | ||
| 64 | context.ExpectedEmbeddedFiles = this.ExpectedEmbeddedFiles; | ||
| 65 | context.Extensions = this.ServiceProvider.GetService<IExtensionManager>().Create<IBinderExtension>(); | ||
| 66 | context.Ices = this.Ices; | ||
| 67 | context.IntermediateFolder = this.IntermediateFolder; | ||
| 68 | context.IntermediateRepresentation = this.IntermediateRepresentation; | ||
| 69 | context.OutputPath = this.OutputPath; | ||
| 70 | context.OutputPdbPath = this.OutputPdbPath; | ||
| 71 | context.SuppressIces = this.SuppressIces; | ||
| 72 | context.SuppressValidation = this.SuppressValidation; | ||
| 73 | |||
| 74 | // Prebind. | 29 | // Prebind. |
| 75 | // | 30 | // |
| 76 | foreach (var extension in context.Extensions) | 31 | foreach (var extension in context.Extensions) |
| @@ -80,7 +35,7 @@ namespace WixToolset.Core | |||
| 80 | 35 | ||
| 81 | // Bind. | 36 | // Bind. |
| 82 | // | 37 | // |
| 83 | this.WriteBuildInfoTable(context.IntermediateRepresentation, context.OutputPath, context.OutputPdbPath); | 38 | this.WriteBuildInfoTuple(context.IntermediateRepresentation, context.OutputPath, context.OutputPdbPath); |
| 84 | 39 | ||
| 85 | var bindResult = this.BackendBind(context); | 40 | var bindResult = this.BackendBind(context); |
| 86 | 41 | ||
| @@ -107,7 +62,7 @@ namespace WixToolset.Core | |||
| 107 | 62 | ||
| 108 | foreach (var factory in backendFactories) | 63 | foreach (var factory in backendFactories) |
| 109 | { | 64 | { |
| 110 | if (factory.TryCreateBackend(entrySection.Type.ToString(), context.OutputPath, null, out var backend)) | 65 | if (factory.TryCreateBackend(entrySection.Type.ToString(), context.OutputPath, out var backend)) |
| 111 | { | 66 | { |
| 112 | var result = backend.Bind(context); | 67 | var result = backend.Bind(context); |
| 113 | return result; | 68 | return result; |
| @@ -118,8 +73,8 @@ namespace WixToolset.Core | |||
| 118 | 73 | ||
| 119 | return null; | 74 | return null; |
| 120 | } | 75 | } |
| 121 | 76 | ||
| 122 | private void WriteBuildInfoTable(Intermediate output, string outputFile, string outputPdbPath) | 77 | private void WriteBuildInfoTuple(Intermediate output, string outputFile, string outputPdbPath) |
| 123 | { | 78 | { |
| 124 | var entrySection = output.Sections.First(s => s.Type != SectionType.Fragment); | 79 | var entrySection = output.Sections.First(s => s.Type != SectionType.Fragment); |
| 125 | 80 | ||
diff --git a/src/WixToolset.Core/CommandLine/BuildCommand.cs b/src/WixToolset.Core/CommandLine/BuildCommand.cs index 76502bb0..6052d979 100644 --- a/src/WixToolset.Core/CommandLine/BuildCommand.cs +++ b/src/WixToolset.Core/CommandLine/BuildCommand.cs | |||
| @@ -8,6 +8,7 @@ namespace WixToolset.Core.CommandLine | |||
| 8 | using System.Linq; | 8 | using System.Linq; |
| 9 | using System.Xml.Linq; | 9 | using System.Xml.Linq; |
| 10 | using WixToolset.Data; | 10 | using WixToolset.Data; |
| 11 | using WixToolset.Extensibility; | ||
| 11 | using WixToolset.Extensibility.Data; | 12 | using WixToolset.Extensibility.Data; |
| 12 | using WixToolset.Extensibility.Services; | 13 | using WixToolset.Extensibility.Services; |
| 13 | 14 | ||
| @@ -172,16 +173,24 @@ namespace WixToolset.Core.CommandLine | |||
| 172 | 173 | ||
| 173 | foreach (var sourceFile in sourceFiles) | 174 | foreach (var sourceFile in sourceFiles) |
| 174 | { | 175 | { |
| 175 | var preprocessor = new Preprocessor(this.ServiceProvider); | 176 | var document = this.Preprocess(sourceFile.SourcePath); |
| 176 | preprocessor.IncludeSearchPaths = this.IncludeSearchPaths; | ||
| 177 | preprocessor.Platform = this.Platform; | ||
| 178 | preprocessor.SourcePath = sourceFile.SourcePath; | ||
| 179 | preprocessor.Variables = this.PreprocessorVariables; | ||
| 180 | 177 | ||
| 181 | XDocument document = null; | 178 | if (this.Messaging.EncounteredError) |
| 179 | { | ||
| 180 | continue; | ||
| 181 | } | ||
| 182 | |||
| 183 | var context = this.ServiceProvider.GetService<ICompileContext>(); | ||
| 184 | context.Extensions = this.ExtensionManager.Create<ICompilerExtension>(); | ||
| 185 | context.OutputPath = sourceFile.OutputPath; | ||
| 186 | context.Platform = this.Platform; | ||
| 187 | context.Source = document; | ||
| 188 | |||
| 189 | Intermediate intermediate = null; | ||
| 182 | try | 190 | try |
| 183 | { | 191 | { |
| 184 | document = preprocessor.Execute(); | 192 | var compiler = this.ServiceProvider.GetService<ICompiler>(); |
| 193 | intermediate = compiler.Compile(context); | ||
| 185 | } | 194 | } |
| 186 | catch (WixException e) | 195 | catch (WixException e) |
| 187 | { | 196 | { |
| @@ -193,17 +202,6 @@ namespace WixToolset.Core.CommandLine | |||
| 193 | continue; | 202 | continue; |
| 194 | } | 203 | } |
| 195 | 204 | ||
| 196 | var compiler = new Compiler(this.ServiceProvider); | ||
| 197 | compiler.OutputPath = sourceFile.OutputPath; | ||
| 198 | compiler.Platform = this.Platform; | ||
| 199 | compiler.SourceDocument = document; | ||
| 200 | var intermediate = compiler.Execute(); | ||
| 201 | |||
| 202 | if (this.Messaging.EncounteredError) | ||
| 203 | { | ||
| 204 | continue; | ||
| 205 | } | ||
| 206 | |||
| 207 | intermediates.Add(intermediate); | 205 | intermediates.Add(intermediate); |
| 208 | } | 206 | } |
| 209 | 207 | ||
| @@ -212,14 +210,27 @@ namespace WixToolset.Core.CommandLine | |||
| 212 | 210 | ||
| 213 | private Intermediate LibraryPhase(IEnumerable<Intermediate> intermediates, IEnumerable<Localization> localizations) | 211 | private Intermediate LibraryPhase(IEnumerable<Intermediate> intermediates, IEnumerable<Localization> localizations) |
| 214 | { | 212 | { |
| 215 | var librarian = new Librarian(this.ServiceProvider); | 213 | var context = this.ServiceProvider.GetService<ILibraryContext>(); |
| 216 | librarian.BindFiles = this.BindFiles; | 214 | context.BindFiles = this.BindFiles; |
| 217 | librarian.BindPaths = this.BindPaths; | 215 | context.BindPaths = this.BindPaths; |
| 218 | librarian.Intermediates = intermediates; | 216 | context.Extensions = this.ExtensionManager.Create<ILibrarianExtension>(); |
| 219 | librarian.Localizations = localizations; | 217 | context.Localizations = localizations; |
| 220 | return librarian.Execute(); | 218 | context.Intermediates = intermediates; |
| 221 | } | 219 | |
| 220 | Intermediate library = null; | ||
| 221 | try | ||
| 222 | { | ||
| 223 | var librarian = this.ServiceProvider.GetService<ILibrarian>(); | ||
| 224 | library = librarian.Combine(context); | ||
| 225 | } | ||
| 226 | catch (WixException e) | ||
| 227 | { | ||
| 228 | this.Messaging.Write(e.Error); | ||
| 229 | } | ||
| 222 | 230 | ||
| 231 | return library; | ||
| 232 | } | ||
| 233 | |||
| 223 | private Intermediate LinkPhase(IEnumerable<Intermediate> intermediates, ITupleDefinitionCreator creator) | 234 | private Intermediate LinkPhase(IEnumerable<Intermediate> intermediates, ITupleDefinitionCreator creator) |
| 224 | { | 235 | { |
| 225 | var libraries = this.LoadLibraries(creator); | 236 | var libraries = this.LoadLibraries(creator); |
| @@ -229,26 +240,39 @@ namespace WixToolset.Core.CommandLine | |||
| 229 | return null; | 240 | return null; |
| 230 | } | 241 | } |
| 231 | 242 | ||
| 232 | var linker = new Linker(this.ServiceProvider); | 243 | var context = this.ServiceProvider.GetService<ILinkContext>(); |
| 233 | linker.OutputType = this.OutputType; | 244 | context.Extensions = this.ExtensionManager.Create<ILinkerExtension>(); |
| 234 | linker.Intermediates = intermediates; | 245 | context.ExtensionData = this.ExtensionManager.Create<IExtensionData>(); |
| 235 | linker.Libraries = libraries; | 246 | context.ExpectedOutputType = this.OutputType; |
| 236 | linker.TupleDefinitionCreator = creator; | 247 | context.Intermediates = intermediates.Concat(libraries).ToList(); |
| 237 | return linker.Execute(); | 248 | context.TupleDefinitionCreator = creator; |
| 249 | |||
| 250 | var linker = this.ServiceProvider.GetService<ILinker>(); | ||
| 251 | return linker.Link(context); | ||
| 238 | } | 252 | } |
| 239 | 253 | ||
| 240 | private void BindPhase(Intermediate output, IEnumerable<Localization> localizations) | 254 | private void BindPhase(Intermediate output, IEnumerable<Localization> localizations) |
| 241 | { | 255 | { |
| 256 | var intermediateFolder = this.IntermediateFolder; | ||
| 257 | if (String.IsNullOrEmpty(intermediateFolder)) | ||
| 258 | { | ||
| 259 | intermediateFolder = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); | ||
| 260 | } | ||
| 261 | |||
| 242 | ResolveResult resolveResult; | 262 | ResolveResult resolveResult; |
| 243 | { | 263 | { |
| 244 | var resolver = new Resolver(this.ServiceProvider); | 264 | var context = this.ServiceProvider.GetService<IResolveContext>(); |
| 245 | resolver.BindPaths = this.BindPaths; | 265 | context.BindPaths = this.BindPaths; |
| 246 | resolver.FilterCultures = this.FilterCultures; | 266 | context.Extensions = this.ExtensionManager.Create<IResolverExtension>(); |
| 247 | resolver.IntermediateFolder = this.IntermediateFolder; | 267 | context.ExtensionData = this.ExtensionManager.Create<IExtensionData>(); |
| 248 | resolver.IntermediateRepresentation = output; | 268 | context.FilterCultures = this.FilterCultures; |
| 249 | resolver.Localizations = localizations; | 269 | context.IntermediateFolder = intermediateFolder; |
| 250 | 270 | context.IntermediateRepresentation = output; | |
| 251 | resolveResult = resolver.Execute(); | 271 | context.Localizations = localizations; |
| 272 | context.VariableResolver = new WixVariableResolver(this.Messaging); | ||
| 273 | |||
| 274 | var resolver = this.ServiceProvider.GetService<IResolver>(); | ||
| 275 | resolveResult = resolver.Resolve(context); | ||
| 252 | } | 276 | } |
| 253 | 277 | ||
| 254 | if (this.Messaging.EncounteredError) | 278 | if (this.Messaging.EncounteredError) |
| @@ -258,28 +282,24 @@ namespace WixToolset.Core.CommandLine | |||
| 258 | 282 | ||
| 259 | BindResult bindResult; | 283 | BindResult bindResult; |
| 260 | { | 284 | { |
| 261 | var intermediateFolder = this.IntermediateFolder; | 285 | var context = this.ServiceProvider.GetService<IBindContext>(); |
| 262 | if (String.IsNullOrEmpty(intermediateFolder)) | 286 | //context.CabbingThreadCount = this.CabbingThreadCount; |
| 263 | { | 287 | context.CabCachePath = this.CabCachePath; |
| 264 | intermediateFolder = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); | 288 | context.Codepage = resolveResult.Codepage; |
| 265 | } | 289 | //context.DefaultCompressionLevel = this.DefaultCompressionLevel; |
| 266 | 290 | context.DelayedFields = resolveResult.DelayedFields; | |
| 267 | var binder = new Binder(this.ServiceProvider); | 291 | context.ExpectedEmbeddedFiles = resolveResult.ExpectedEmbeddedFiles; |
| 268 | //binder.CabbingThreadCount = this.CabbingThreadCount; | 292 | context.Extensions = this.ExtensionManager.Create<IBinderExtension>(); |
| 269 | binder.CabCachePath = this.CabCachePath; | 293 | context.Ices = Array.Empty<string>(); // TODO: set this correctly |
| 270 | binder.Codepage = resolveResult.Codepage; | 294 | context.IntermediateFolder = intermediateFolder; |
| 271 | //binder.DefaultCompressionLevel = this.DefaultCompressionLevel; | 295 | context.IntermediateRepresentation = resolveResult.IntermediateRepresentation; |
| 272 | binder.DelayedFields = resolveResult.DelayedFields; | 296 | context.OutputPath = this.OutputPath; |
| 273 | binder.ExpectedEmbeddedFiles = resolveResult.ExpectedEmbeddedFiles; | 297 | context.OutputPdbPath = Path.ChangeExtension(this.OutputPath, ".wixpdb"); |
| 274 | binder.Ices = Array.Empty<string>(); // TODO: set this correctly | 298 | context.SuppressIces = Array.Empty<string>(); // TODO: set this correctly |
| 275 | binder.IntermediateFolder = intermediateFolder; | 299 | context.SuppressValidation = true; // TODO: set this correctly |
| 276 | binder.IntermediateRepresentation = resolveResult.IntermediateRepresentation; | 300 | |
| 277 | binder.OutputPath = this.OutputPath; | 301 | var binder = this.ServiceProvider.GetService<IBinder>(); |
| 278 | binder.OutputPdbPath = Path.ChangeExtension(this.OutputPath, ".wixpdb"); | 302 | bindResult = binder.Bind(context); |
| 279 | binder.SuppressIces = Array.Empty<string>(); // TODO: set this correctly | ||
| 280 | binder.SuppressValidation = true; // TODO: set this correctly | ||
| 281 | |||
| 282 | bindResult = binder.Execute(); | ||
| 283 | } | 303 | } |
| 284 | 304 | ||
| 285 | if (this.Messaging.EncounteredError) | 305 | if (this.Messaging.EncounteredError) |
| @@ -288,16 +308,18 @@ namespace WixToolset.Core.CommandLine | |||
| 288 | } | 308 | } |
| 289 | 309 | ||
| 290 | { | 310 | { |
| 291 | var layout = new Layout(this.ServiceProvider); | 311 | var context = this.ServiceProvider.GetService<ILayoutContext>(); |
| 292 | layout.TrackedFiles = bindResult.TrackedFiles; | 312 | context.Extensions = this.ExtensionManager.Create<ILayoutExtension>(); |
| 293 | layout.FileTransfers = bindResult.FileTransfers; | 313 | context.TrackedFiles = bindResult.TrackedFiles; |
| 294 | layout.IntermediateFolder = this.IntermediateFolder; | 314 | context.FileTransfers = bindResult.FileTransfers; |
| 295 | layout.ContentsFile = this.ContentsFile; | 315 | context.IntermediateFolder = intermediateFolder; |
| 296 | layout.OutputsFile = this.OutputsFile; | 316 | context.ContentsFile = this.ContentsFile; |
| 297 | layout.BuiltOutputsFile = this.BuiltOutputsFile; | 317 | context.OutputsFile = this.OutputsFile; |
| 298 | layout.SuppressAclReset = false; // TODO: correctly set SuppressAclReset | 318 | context.BuiltOutputsFile = this.BuiltOutputsFile; |
| 299 | 319 | context.SuppressAclReset = false; // TODO: correctly set SuppressAclReset | |
| 300 | layout.Execute(); | 320 | |
| 321 | var layout = this.ServiceProvider.GetService<ILayoutCreator>(); | ||
| 322 | layout.Layout(context); | ||
| 301 | } | 323 | } |
| 302 | } | 324 | } |
| 303 | 325 | ||
| @@ -335,12 +357,7 @@ namespace WixToolset.Core.CommandLine | |||
| 335 | 357 | ||
| 336 | foreach (var loc in this.LocFiles) | 358 | foreach (var loc in this.LocFiles) |
| 337 | { | 359 | { |
| 338 | var preprocessor = new Preprocessor(this.ServiceProvider); | 360 | var document = this.Preprocess(loc); |
| 339 | preprocessor.IncludeSearchPaths = this.IncludeSearchPaths; | ||
| 340 | preprocessor.Platform = Platform.X86; // TODO: set this correctly | ||
| 341 | preprocessor.SourcePath = loc; | ||
| 342 | preprocessor.Variables = this.PreprocessorVariables; | ||
| 343 | var document = preprocessor.Execute(); | ||
| 344 | 361 | ||
| 345 | if (this.Messaging.EncounteredError) | 362 | if (this.Messaging.EncounteredError) |
| 346 | { | 363 | { |
| @@ -351,5 +368,28 @@ namespace WixToolset.Core.CommandLine | |||
| 351 | yield return localization; | 368 | yield return localization; |
| 352 | } | 369 | } |
| 353 | } | 370 | } |
| 371 | |||
| 372 | private XDocument Preprocess(string sourcePath) | ||
| 373 | { | ||
| 374 | var context = this.ServiceProvider.GetService<IPreprocessContext>(); | ||
| 375 | context.Extensions = this.ExtensionManager.Create<IPreprocessorExtension>(); | ||
| 376 | context.Platform = this.Platform; | ||
| 377 | context.IncludeSearchPaths = this.IncludeSearchPaths; | ||
| 378 | context.SourcePath = sourcePath; | ||
| 379 | context.Variables = this.PreprocessorVariables; | ||
| 380 | |||
| 381 | XDocument document = null; | ||
| 382 | try | ||
| 383 | { | ||
| 384 | var preprocessor = this.ServiceProvider.GetService<IPreprocessor>(); | ||
| 385 | document = preprocessor.Preprocess(context); | ||
| 386 | } | ||
| 387 | catch (WixException e) | ||
| 388 | { | ||
| 389 | this.Messaging.Write(e.Error); | ||
| 390 | } | ||
| 391 | |||
| 392 | return document; | ||
| 393 | } | ||
| 354 | } | 394 | } |
| 355 | } | 395 | } |
diff --git a/src/WixToolset.Core/CommandLine/CompileCommand.cs b/src/WixToolset.Core/CommandLine/CompileCommand.cs index 621571b1..4007c263 100644 --- a/src/WixToolset.Core/CommandLine/CompileCommand.cs +++ b/src/WixToolset.Core/CommandLine/CompileCommand.cs | |||
| @@ -6,6 +6,7 @@ namespace WixToolset.Core.CommandLine | |||
| 6 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
| 7 | using System.Xml.Linq; | 7 | using System.Xml.Linq; |
| 8 | using WixToolset.Data; | 8 | using WixToolset.Data; |
| 9 | using WixToolset.Extensibility; | ||
| 9 | using WixToolset.Extensibility.Data; | 10 | using WixToolset.Extensibility.Data; |
| 10 | using WixToolset.Extensibility.Services; | 11 | using WixToolset.Extensibility.Services; |
| 11 | 12 | ||
| @@ -15,6 +16,7 @@ namespace WixToolset.Core.CommandLine | |||
| 15 | { | 16 | { |
| 16 | this.ServiceProvider = serviceProvider; | 17 | this.ServiceProvider = serviceProvider; |
| 17 | this.Messaging = serviceProvider.GetService<IMessaging>(); | 18 | this.Messaging = serviceProvider.GetService<IMessaging>(); |
| 19 | this.ExtensionManager = serviceProvider.GetService<IExtensionManager>(); | ||
| 18 | this.SourceFiles = sources; | 20 | this.SourceFiles = sources; |
| 19 | this.PreprocessorVariables = preprocessorVariables; | 21 | this.PreprocessorVariables = preprocessorVariables; |
| 20 | this.Platform = platform; | 22 | this.Platform = platform; |
| @@ -24,6 +26,8 @@ namespace WixToolset.Core.CommandLine | |||
| 24 | 26 | ||
| 25 | public IMessaging Messaging { get; } | 27 | public IMessaging Messaging { get; } |
| 26 | 28 | ||
| 29 | public IExtensionManager ExtensionManager { get; } | ||
| 30 | |||
| 27 | private IEnumerable<SourceFile> SourceFiles { get; } | 31 | private IEnumerable<SourceFile> SourceFiles { get; } |
| 28 | 32 | ||
| 29 | private IDictionary<string, string> PreprocessorVariables { get; } | 33 | private IDictionary<string, string> PreprocessorVariables { get; } |
| @@ -36,16 +40,18 @@ namespace WixToolset.Core.CommandLine | |||
| 36 | { | 40 | { |
| 37 | foreach (var sourceFile in this.SourceFiles) | 41 | foreach (var sourceFile in this.SourceFiles) |
| 38 | { | 42 | { |
| 39 | var preprocessor = new Preprocessor(this.ServiceProvider); | 43 | var context = this.ServiceProvider.GetService<IPreprocessContext>(); |
| 40 | preprocessor.IncludeSearchPaths = this.IncludeSearchPaths; | 44 | context.Extensions = this.ExtensionManager.Create<IPreprocessorExtension>(); |
| 41 | preprocessor.Platform = Platform.X86; // TODO: set this correctly | 45 | context.Platform = this.Platform; |
| 42 | preprocessor.SourcePath = sourceFile.SourcePath; | 46 | context.IncludeSearchPaths = this.IncludeSearchPaths; |
| 43 | preprocessor.Variables = new Dictionary<string, string>(this.PreprocessorVariables); | 47 | context.SourcePath = sourceFile.SourcePath; |
| 48 | context.Variables = this.PreprocessorVariables; | ||
| 44 | 49 | ||
| 45 | XDocument document = null; | 50 | XDocument document = null; |
| 46 | try | 51 | try |
| 47 | { | 52 | { |
| 48 | document = preprocessor.Execute(); | 53 | var preprocessor = this.ServiceProvider.GetService<IPreprocessor>(); |
| 54 | document = preprocessor.Preprocess(context); | ||
| 49 | } | 55 | } |
| 50 | catch (WixException e) | 56 | catch (WixException e) |
| 51 | { | 57 | { |
| @@ -57,11 +63,14 @@ namespace WixToolset.Core.CommandLine | |||
| 57 | continue; | 63 | continue; |
| 58 | } | 64 | } |
| 59 | 65 | ||
| 60 | var compiler = new Compiler(this.ServiceProvider); | 66 | var compileContext = this.ServiceProvider.GetService<ICompileContext>(); |
| 61 | compiler.OutputPath = sourceFile.OutputPath; | 67 | compileContext.Extensions = this.ExtensionManager.Create<ICompilerExtension>(); |
| 62 | compiler.Platform = this.Platform; | 68 | compileContext.OutputPath = sourceFile.OutputPath; |
| 63 | compiler.SourceDocument = document; | 69 | compileContext.Platform = this.Platform; |
| 64 | var intermediate = compiler.Execute(); | 70 | compileContext.Source = document; |
| 71 | |||
| 72 | var compiler = this.ServiceProvider.GetService<ICompiler>(); | ||
| 73 | var intermediate = compiler.Compile(compileContext); | ||
| 65 | 74 | ||
| 66 | intermediate.Save(sourceFile.OutputPath); | 75 | intermediate.Save(sourceFile.OutputPath); |
| 67 | } | 76 | } |
diff --git a/src/WixToolset.Core/Compiler.cs b/src/WixToolset.Core/Compiler.cs index 7d09be6d..ffe907e8 100644 --- a/src/WixToolset.Core/Compiler.cs +++ b/src/WixToolset.Core/Compiler.cs | |||
| @@ -22,7 +22,7 @@ namespace WixToolset.Core | |||
| 22 | /// <summary> | 22 | /// <summary> |
| 23 | /// Compiler of the WiX toolset. | 23 | /// Compiler of the WiX toolset. |
| 24 | /// </summary> | 24 | /// </summary> |
| 25 | internal class Compiler | 25 | internal class Compiler : ICompiler |
| 26 | { | 26 | { |
| 27 | public const string UpgradeDetectedProperty = "WIX_UPGRADE_DETECTED"; | 27 | public const string UpgradeDetectedProperty = "WIX_UPGRADE_DETECTED"; |
| 28 | public const string UpgradePreventedCondition = "NOT WIX_UPGRADE_DETECTED"; | 28 | public const string UpgradePreventedCondition = "NOT WIX_UPGRADE_DETECTED"; |
| @@ -84,14 +84,6 @@ namespace WixToolset.Core | |||
| 84 | 84 | ||
| 85 | private CompilerCore Core { get; set; } | 85 | private CompilerCore Core { get; set; } |
| 86 | 86 | ||
| 87 | public string CompliationId { get; set; } | ||
| 88 | |||
| 89 | public string OutputPath { get; set; } | ||
| 90 | |||
| 91 | public Platform Platform { get; set; } | ||
| 92 | |||
| 93 | public XDocument SourceDocument { get; set; } | ||
| 94 | |||
| 95 | /// <summary> | 87 | /// <summary> |
| 96 | /// Gets or sets the platform which the compiler will use when defaulting 64-bit attributes and elements. | 88 | /// Gets or sets the platform which the compiler will use when defaulting 64-bit attributes and elements. |
| 97 | /// </summary> | 89 | /// </summary> |
| @@ -109,22 +101,17 @@ namespace WixToolset.Core | |||
| 109 | /// </summary> | 101 | /// </summary> |
| 110 | /// <returns>Intermediate object representing compiled source document.</returns> | 102 | /// <returns>Intermediate object representing compiled source document.</returns> |
| 111 | /// <remarks>This method is not thread-safe.</remarks> | 103 | /// <remarks>This method is not thread-safe.</remarks> |
| 112 | public Intermediate Execute() | 104 | public Intermediate Compile(ICompileContext context) |
| 113 | { | 105 | { |
| 114 | this.Context = this.ServiceProvider.GetService<ICompileContext>(); | ||
| 115 | this.Context.Extensions = this.ServiceProvider.GetService<IExtensionManager>().Create<ICompilerExtension>(); | ||
| 116 | this.Context.CompilationId = this.CompliationId; | ||
| 117 | this.Context.OutputPath = this.OutputPath; | ||
| 118 | this.Context.Platform = this.Platform; | ||
| 119 | this.Context.Source = this.SourceDocument; | ||
| 120 | |||
| 121 | var target = new Intermediate(); | 106 | var target = new Intermediate(); |
| 122 | 107 | ||
| 123 | if (String.IsNullOrEmpty(this.Context.CompilationId)) | 108 | if (String.IsNullOrEmpty(context.CompilationId)) |
| 124 | { | 109 | { |
| 125 | this.Context.CompilationId = target.Id; | 110 | context.CompilationId = target.Id; |
| 126 | } | 111 | } |
| 127 | 112 | ||
| 113 | this.Context = context; | ||
| 114 | |||
| 128 | var extensionsByNamespace = new Dictionary<XNamespace, ICompilerExtension>(); | 115 | var extensionsByNamespace = new Dictionary<XNamespace, ICompilerExtension>(); |
| 129 | 116 | ||
| 130 | foreach (var extension in this.Context.Extensions) | 117 | foreach (var extension in this.Context.Extensions) |
diff --git a/src/WixToolset.Core/DecompileContext.cs b/src/WixToolset.Core/DecompileContext.cs new file mode 100644 index 00000000..a9f0640a --- /dev/null +++ b/src/WixToolset.Core/DecompileContext.cs | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | namespace WixToolset.Core | ||
| 4 | { | ||
| 5 | using System; | ||
| 6 | using System.Collections.Generic; | ||
| 7 | using WixToolset.Data; | ||
| 8 | using WixToolset.Extensibility; | ||
| 9 | using WixToolset.Extensibility.Data; | ||
| 10 | |||
| 11 | internal class DecompileContext : IDecompileContext | ||
| 12 | { | ||
| 13 | internal DecompileContext(IServiceProvider serviceProvider) | ||
| 14 | { | ||
| 15 | this.ServiceProvider = serviceProvider; | ||
| 16 | } | ||
| 17 | |||
| 18 | public IServiceProvider ServiceProvider { get; } | ||
| 19 | |||
| 20 | public OutputType DecompileType { get; set; } | ||
| 21 | |||
| 22 | public IEnumerable<IDecompilerExtension> Extensions { get; set; } | ||
| 23 | |||
| 24 | public string IntermediateFolder { get; set; } | ||
| 25 | |||
| 26 | public string OutputPath { get; set; } | ||
| 27 | } | ||
| 28 | } | ||
diff --git a/src/WixToolset.Core/Decompiler.cs b/src/WixToolset.Core/Decompiler.cs new file mode 100644 index 00000000..5f14dfca --- /dev/null +++ b/src/WixToolset.Core/Decompiler.cs | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | namespace WixToolset.Core | ||
| 4 | { | ||
| 5 | using System; | ||
| 6 | using WixToolset.Data; | ||
| 7 | using WixToolset.Extensibility; | ||
| 8 | using WixToolset.Extensibility.Data; | ||
| 9 | using WixToolset.Extensibility.Services; | ||
| 10 | |||
| 11 | /// <summary> | ||
| 12 | /// Decompiler of the WiX toolset. | ||
| 13 | /// </summary> | ||
| 14 | internal class Decompiler : IDecompiler | ||
| 15 | { | ||
| 16 | internal Decompiler(IServiceProvider serviceProvider) | ||
| 17 | { | ||
| 18 | this.ServiceProvider = serviceProvider; | ||
| 19 | } | ||
| 20 | |||
| 21 | public OutputType DecompileType { get; set; } | ||
| 22 | |||
| 23 | public string IntermediateFolder { get; set; } | ||
| 24 | |||
| 25 | public string OutputPath { get; set; } | ||
| 26 | |||
| 27 | public IServiceProvider ServiceProvider { get; } | ||
| 28 | |||
| 29 | public BindResult Decompile(IDecompileContext context) | ||
| 30 | { | ||
| 31 | // Pre-decompile. | ||
| 32 | // | ||
| 33 | foreach (var extension in context.Extensions) | ||
| 34 | { | ||
| 35 | extension.PreDecompile(context); | ||
| 36 | } | ||
| 37 | |||
| 38 | // Decompile. | ||
| 39 | // | ||
| 40 | var bindResult = this.BackendDecompile(context); | ||
| 41 | |||
| 42 | if (bindResult != null) | ||
| 43 | { | ||
| 44 | // Post-decompile. | ||
| 45 | // | ||
| 46 | foreach (var extension in context.Extensions) | ||
| 47 | { | ||
| 48 | extension.PostDecompile(bindResult); | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | return bindResult; | ||
| 53 | } | ||
| 54 | |||
| 55 | private BindResult BackendDecompile(IDecompileContext context) | ||
| 56 | { | ||
| 57 | var extensionManager = context.ServiceProvider.GetService<IExtensionManager>(); | ||
| 58 | |||
| 59 | var backendFactories = extensionManager.Create<IBackendFactory>(); | ||
| 60 | |||
| 61 | foreach (var factory in backendFactories) | ||
| 62 | { | ||
| 63 | if (factory.TryCreateBackend(context.DecompileType.ToString(), context.OutputPath, out var backend)) | ||
| 64 | { | ||
| 65 | var result = backend.Decompile(context); | ||
| 66 | return result; | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | // TODO: messaging that a backend could not be found to decompile the decompile type? | ||
| 71 | |||
| 72 | return null; | ||
| 73 | } | ||
| 74 | } | ||
| 75 | } | ||
diff --git a/src/WixToolset.Core/IBinder.cs b/src/WixToolset.Core/IBinder.cs new file mode 100644 index 00000000..884ee6b9 --- /dev/null +++ b/src/WixToolset.Core/IBinder.cs | |||
| @@ -0,0 +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. | ||
| 2 | |||
| 3 | namespace WixToolset.Core | ||
| 4 | { | ||
| 5 | using WixToolset.Extensibility.Data; | ||
| 6 | |||
| 7 | public interface IBinder | ||
| 8 | { | ||
| 9 | BindResult Bind(IBindContext context); | ||
| 10 | } | ||
| 11 | } | ||
diff --git a/src/WixToolset.Core/ICompiler.cs b/src/WixToolset.Core/ICompiler.cs new file mode 100644 index 00000000..a2c4a6e8 --- /dev/null +++ b/src/WixToolset.Core/ICompiler.cs | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | namespace WixToolset.Core | ||
| 4 | { | ||
| 5 | using WixToolset.Data; | ||
| 6 | using WixToolset.Extensibility.Data; | ||
| 7 | |||
| 8 | public interface ICompiler | ||
| 9 | { | ||
| 10 | Intermediate Compile(ICompileContext context); | ||
| 11 | } | ||
| 12 | } | ||
diff --git a/src/WixToolset.Core/IDecompiler.cs b/src/WixToolset.Core/IDecompiler.cs new file mode 100644 index 00000000..b9bb7ed8 --- /dev/null +++ b/src/WixToolset.Core/IDecompiler.cs | |||
| @@ -0,0 +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. | ||
| 2 | |||
| 3 | namespace WixToolset.Core | ||
| 4 | { | ||
| 5 | using WixToolset.Extensibility.Data; | ||
| 6 | |||
| 7 | public interface IDecompiler | ||
| 8 | { | ||
| 9 | BindResult Decompile(IDecompileContext context); | ||
| 10 | } | ||
| 11 | } | ||
diff --git a/src/WixToolset.Core/ILayoutCreator.cs b/src/WixToolset.Core/ILayoutCreator.cs new file mode 100644 index 00000000..f58d0aad --- /dev/null +++ b/src/WixToolset.Core/ILayoutCreator.cs | |||
| @@ -0,0 +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. | ||
| 2 | |||
| 3 | namespace WixToolset.Core | ||
| 4 | { | ||
| 5 | using WixToolset.Extensibility.Data; | ||
| 6 | |||
| 7 | public interface ILayoutCreator | ||
| 8 | { | ||
| 9 | void Layout(ILayoutContext context); | ||
| 10 | } | ||
| 11 | } | ||
diff --git a/src/WixToolset.Core/ILibrarian.cs b/src/WixToolset.Core/ILibrarian.cs new file mode 100644 index 00000000..3e951e65 --- /dev/null +++ b/src/WixToolset.Core/ILibrarian.cs | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | namespace WixToolset.Core | ||
| 4 | { | ||
| 5 | using WixToolset.Data; | ||
| 6 | using WixToolset.Extensibility.Data; | ||
| 7 | |||
| 8 | public interface ILibrarian | ||
| 9 | { | ||
| 10 | Intermediate Combine(ILibraryContext context); | ||
| 11 | } | ||
| 12 | } | ||
diff --git a/src/WixToolset.Core/ILinker.cs b/src/WixToolset.Core/ILinker.cs new file mode 100644 index 00000000..0580bf46 --- /dev/null +++ b/src/WixToolset.Core/ILinker.cs | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | namespace WixToolset.Core | ||
| 4 | { | ||
| 5 | using WixToolset.Data; | ||
| 6 | using WixToolset.Extensibility.Data; | ||
| 7 | |||
| 8 | public interface ILinker | ||
| 9 | { | ||
| 10 | Intermediate Link(ILinkContext context); | ||
| 11 | } | ||
| 12 | } | ||
diff --git a/src/WixToolset.Core/IPreprocessor.cs b/src/WixToolset.Core/IPreprocessor.cs new file mode 100644 index 00000000..946d8cc2 --- /dev/null +++ b/src/WixToolset.Core/IPreprocessor.cs | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | namespace WixToolset.Core | ||
| 4 | { | ||
| 5 | using System.Xml; | ||
| 6 | using System.Xml.Linq; | ||
| 7 | using WixToolset.Extensibility.Data; | ||
| 8 | |||
| 9 | internal interface IPreprocessor | ||
| 10 | { | ||
| 11 | XDocument Preprocess(IPreprocessContext context); | ||
| 12 | |||
| 13 | XDocument Preprocess(IPreprocessContext context, XmlReader reader); | ||
| 14 | } | ||
| 15 | } | ||
diff --git a/src/WixToolset.Core/IResolver.cs b/src/WixToolset.Core/IResolver.cs new file mode 100644 index 00000000..a027f348 --- /dev/null +++ b/src/WixToolset.Core/IResolver.cs | |||
| @@ -0,0 +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. | ||
| 2 | |||
| 3 | namespace WixToolset.Core | ||
| 4 | { | ||
| 5 | using WixToolset.Extensibility.Data; | ||
| 6 | |||
| 7 | public interface IResolver | ||
| 8 | { | ||
| 9 | ResolveResult Resolve(IResolveContext context); | ||
| 10 | } | ||
| 11 | } | ||
diff --git a/src/WixToolset.Core/LayoutContext.cs b/src/WixToolset.Core/LayoutContext.cs index 20d29b5f..b8a8635d 100644 --- a/src/WixToolset.Core/LayoutContext.cs +++ b/src/WixToolset.Core/LayoutContext.cs | |||
| @@ -24,7 +24,7 @@ namespace WixToolset.Core | |||
| 24 | 24 | ||
| 25 | public IEnumerable<ITrackedFile> TrackedFiles { get; set; } | 25 | public IEnumerable<ITrackedFile> TrackedFiles { get; set; } |
| 26 | 26 | ||
| 27 | public string OutputPdbPath { get; set; } | 27 | public string IntermediateFolder { get; set; } |
| 28 | 28 | ||
| 29 | public string ContentsFile { get; set; } | 29 | public string ContentsFile { get; set; } |
| 30 | 30 | ||
diff --git a/src/WixToolset.Core/Layout.cs b/src/WixToolset.Core/LayoutCreator.cs index b1b03aa7..684465d2 100644 --- a/src/WixToolset.Core/Layout.cs +++ b/src/WixToolset.Core/LayoutCreator.cs | |||
| @@ -8,16 +8,15 @@ namespace WixToolset.Core | |||
| 8 | using System.Linq; | 8 | using System.Linq; |
| 9 | using WixToolset.Core.Bind; | 9 | using WixToolset.Core.Bind; |
| 10 | using WixToolset.Data; | 10 | using WixToolset.Data; |
| 11 | using WixToolset.Extensibility; | ||
| 12 | using WixToolset.Extensibility.Data; | 11 | using WixToolset.Extensibility.Data; |
| 13 | using WixToolset.Extensibility.Services; | 12 | using WixToolset.Extensibility.Services; |
| 14 | 13 | ||
| 15 | /// <summary> | 14 | /// <summary> |
| 16 | /// Layout for the WiX toolset. | 15 | /// Layout for the WiX toolset. |
| 17 | /// </summary> | 16 | /// </summary> |
| 18 | internal class Layout | 17 | internal class LayoutCreator : ILayoutCreator |
| 19 | { | 18 | { |
| 20 | internal Layout(IServiceProvider serviceProvider) | 19 | internal LayoutCreator(IServiceProvider serviceProvider) |
| 21 | { | 20 | { |
| 22 | this.ServiceProvider = serviceProvider; | 21 | this.ServiceProvider = serviceProvider; |
| 23 | 22 | ||
| @@ -28,33 +27,8 @@ namespace WixToolset.Core | |||
| 28 | 27 | ||
| 29 | private IMessaging Messaging { get; } | 28 | private IMessaging Messaging { get; } |
| 30 | 29 | ||
| 31 | public IEnumerable<ITrackedFile> TrackedFiles { get; set; } | 30 | public void Layout(ILayoutContext context) |
| 32 | |||
| 33 | public IEnumerable<IFileTransfer> FileTransfers { get; set; } | ||
| 34 | |||
| 35 | public string IntermediateFolder { get; set; } | ||
| 36 | |||
| 37 | public string ContentsFile { get; set; } | ||
| 38 | |||
| 39 | public string OutputsFile { get; set; } | ||
| 40 | |||
| 41 | public string BuiltOutputsFile { get; set; } | ||
| 42 | |||
| 43 | public bool SuppressAclReset { get; set; } | ||
| 44 | |||
| 45 | public void Execute() | ||
| 46 | { | 31 | { |
| 47 | var extensionManager = this.ServiceProvider.GetService<IExtensionManager>(); | ||
| 48 | |||
| 49 | var context = this.ServiceProvider.GetService<ILayoutContext>(); | ||
| 50 | context.Extensions = extensionManager.Create<ILayoutExtension>(); | ||
| 51 | context.TrackedFiles = this.TrackedFiles; | ||
| 52 | context.FileTransfers = this.FileTransfers; | ||
| 53 | context.ContentsFile = this.ContentsFile; | ||
| 54 | context.OutputsFile = this.OutputsFile; | ||
| 55 | context.BuiltOutputsFile = this.BuiltOutputsFile; | ||
| 56 | context.SuppressAclReset = this.SuppressAclReset; | ||
| 57 | |||
| 58 | // Pre-layout. | 32 | // Pre-layout. |
| 59 | // | 33 | // |
| 60 | foreach (var extension in context.Extensions) | 34 | foreach (var extension in context.Extensions) |
| @@ -76,7 +50,7 @@ namespace WixToolset.Core | |||
| 76 | 50 | ||
| 77 | if (context.TrackedFiles != null) | 51 | if (context.TrackedFiles != null) |
| 78 | { | 52 | { |
| 79 | this.CleanTempFiles(context.TrackedFiles); | 53 | this.CleanTempFiles(context.IntermediateFolder, context.TrackedFiles); |
| 80 | } | 54 | } |
| 81 | } | 55 | } |
| 82 | finally | 56 | finally |
| @@ -126,7 +100,7 @@ namespace WixToolset.Core | |||
| 126 | 100 | ||
| 127 | using (var contents = new StreamWriter(path, false)) | 101 | using (var contents = new StreamWriter(path, false)) |
| 128 | { | 102 | { |
| 129 | foreach (string inputPath in uniqueInputFilePaths) | 103 | foreach (var inputPath in uniqueInputFilePaths) |
| 130 | { | 104 | { |
| 131 | contents.WriteLine(inputPath); | 105 | contents.WriteLine(inputPath); |
| 132 | } | 106 | } |
| @@ -190,7 +164,7 @@ namespace WixToolset.Core | |||
| 190 | } | 164 | } |
| 191 | } | 165 | } |
| 192 | 166 | ||
| 193 | private void CleanTempFiles(IEnumerable<ITrackedFile> trackedFiles) | 167 | private void CleanTempFiles(string intermediateFolder, IEnumerable<ITrackedFile> trackedFiles) |
| 194 | { | 168 | { |
| 195 | var uniqueTempPaths = new SortedSet<string>(trackedFiles.Where(t => t.Type == TrackedFileType.Temporary).Select(t => t.Path), StringComparer.OrdinalIgnoreCase); | 169 | var uniqueTempPaths = new SortedSet<string>(trackedFiles.Where(t => t.Type == TrackedFileType.Temporary).Select(t => t.Path), StringComparer.OrdinalIgnoreCase); |
| 196 | 170 | ||
| @@ -201,7 +175,7 @@ namespace WixToolset.Core | |||
| 201 | 175 | ||
| 202 | var uniqueFolders = new SortedSet<string>(StringComparer.OrdinalIgnoreCase) | 176 | var uniqueFolders = new SortedSet<string>(StringComparer.OrdinalIgnoreCase) |
| 203 | { | 177 | { |
| 204 | this.IntermediateFolder | 178 | intermediateFolder |
| 205 | }; | 179 | }; |
| 206 | 180 | ||
| 207 | // Clean up temp files. | 181 | // Clean up temp files. |
| @@ -209,7 +183,7 @@ namespace WixToolset.Core | |||
| 209 | { | 183 | { |
| 210 | try | 184 | try |
| 211 | { | 185 | { |
| 212 | this.SplitUniqueFolders(tempPath, uniqueFolders); | 186 | this.SplitUniqueFolders(intermediateFolder, tempPath, uniqueFolders); |
| 213 | 187 | ||
| 214 | File.Delete(tempPath); | 188 | File.Delete(tempPath); |
| 215 | } | 189 | } |
| @@ -231,15 +205,15 @@ namespace WixToolset.Core | |||
| 231 | } | 205 | } |
| 232 | } | 206 | } |
| 233 | 207 | ||
| 234 | private void SplitUniqueFolders(string tempPath, SortedSet<string> uniqueFolders) | 208 | private void SplitUniqueFolders(string intermediateFolder, string tempPath, SortedSet<string> uniqueFolders) |
| 235 | { | 209 | { |
| 236 | if (tempPath.StartsWith(this.IntermediateFolder, StringComparison.OrdinalIgnoreCase)) | 210 | if (tempPath.StartsWith(intermediateFolder, StringComparison.OrdinalIgnoreCase)) |
| 237 | { | 211 | { |
| 238 | var folder = Path.GetDirectoryName(tempPath).Substring(this.IntermediateFolder.Length); | 212 | var folder = Path.GetDirectoryName(tempPath).Substring(intermediateFolder.Length); |
| 239 | 213 | ||
| 240 | var parts = folder.Split(new[] { '\\', '/' }, StringSplitOptions.RemoveEmptyEntries); | 214 | var parts = folder.Split(new[] { '\\', '/' }, StringSplitOptions.RemoveEmptyEntries); |
| 241 | 215 | ||
| 242 | folder = this.IntermediateFolder; | 216 | folder = intermediateFolder; |
| 243 | 217 | ||
| 244 | foreach (var part in parts) | 218 | foreach (var part in parts) |
| 245 | { | 219 | { |
diff --git a/src/WixToolset.Core/Librarian.cs b/src/WixToolset.Core/Librarian.cs index abd6c844..5db4b219 100644 --- a/src/WixToolset.Core/Librarian.cs +++ b/src/WixToolset.Core/Librarian.cs | |||
| @@ -8,14 +8,13 @@ namespace WixToolset.Core | |||
| 8 | using WixToolset.Core.Bind; | 8 | using WixToolset.Core.Bind; |
| 9 | using WixToolset.Core.Link; | 9 | using WixToolset.Core.Link; |
| 10 | using WixToolset.Data; | 10 | using WixToolset.Data; |
| 11 | using WixToolset.Extensibility; | ||
| 12 | using WixToolset.Extensibility.Data; | 11 | using WixToolset.Extensibility.Data; |
| 13 | using WixToolset.Extensibility.Services; | 12 | using WixToolset.Extensibility.Services; |
| 14 | 13 | ||
| 15 | /// <summary> | 14 | /// <summary> |
| 16 | /// Core librarian tool. | 15 | /// Core librarian tool. |
| 17 | /// </summary> | 16 | /// </summary> |
| 18 | internal class Librarian | 17 | internal class Librarian : ILibrarian |
| 19 | { | 18 | { |
| 20 | internal Librarian(IServiceProvider serviceProvider) | 19 | internal Librarian(IServiceProvider serviceProvider) |
| 21 | { | 20 | { |
| @@ -28,42 +27,29 @@ namespace WixToolset.Core | |||
| 28 | 27 | ||
| 29 | private IMessaging Messaging { get; } | 28 | private IMessaging Messaging { get; } |
| 30 | 29 | ||
| 31 | private ILibraryContext Context { get; set; } | ||
| 32 | |||
| 33 | public bool BindFiles { get; set; } | ||
| 34 | |||
| 35 | public IEnumerable<BindPath> BindPaths { get; set; } | ||
| 36 | |||
| 37 | public IEnumerable<Localization> Localizations { get; set; } | ||
| 38 | |||
| 39 | public IEnumerable<Intermediate> Intermediates { get; set; } | ||
| 40 | |||
| 41 | /// <summary> | 30 | /// <summary> |
| 42 | /// Create a library by combining several intermediates (objects). | 31 | /// Create a library by combining several intermediates (objects). |
| 43 | /// </summary> | 32 | /// </summary> |
| 44 | /// <param name="sections">The sections to combine into a library.</param> | 33 | /// <param name="sections">The sections to combine into a library.</param> |
| 45 | /// <returns>Returns the new library.</returns> | 34 | /// <returns>Returns the new library.</returns> |
| 46 | public Intermediate Execute() | 35 | public Intermediate Combine(ILibraryContext context) |
| 47 | { | 36 | { |
| 48 | this.Context = new LibraryContext(this.ServiceProvider); | 37 | if (String.IsNullOrEmpty(context.LibraryId)) |
| 49 | this.Context.BindFiles = this.BindFiles; | 38 | { |
| 50 | this.Context.BindPaths = this.BindPaths; | 39 | context.LibraryId = Convert.ToBase64String(Guid.NewGuid().ToByteArray()).TrimEnd('=').Replace('+', '.').Replace('/', '_'); |
| 51 | this.Context.Extensions = this.ServiceProvider.GetService<IExtensionManager>().Create<ILibrarianExtension>(); | 40 | } |
| 52 | this.Context.Localizations = this.Localizations; | 41 | |
| 53 | this.Context.LibraryId = Convert.ToBase64String(Guid.NewGuid().ToByteArray()).TrimEnd('=').Replace('+', '.').Replace('/', '_'); | 42 | foreach (var extension in context.Extensions) |
| 54 | this.Context.Intermediates = this.Intermediates; | ||
| 55 | |||
| 56 | foreach (var extension in this.Context.Extensions) | ||
| 57 | { | 43 | { |
| 58 | extension.PreCombine(this.Context); | 44 | extension.PreCombine(context); |
| 59 | } | 45 | } |
| 60 | 46 | ||
| 61 | Intermediate library = null; | 47 | Intermediate library = null; |
| 62 | try | 48 | try |
| 63 | { | 49 | { |
| 64 | var sections = this.Context.Intermediates.SelectMany(i => i.Sections).ToList(); | 50 | var sections = context.Intermediates.SelectMany(i => i.Sections).ToList(); |
| 65 | 51 | ||
| 66 | var collate = new CollateLocalizationsCommand(this.Messaging, this.Context.Localizations); | 52 | var collate = new CollateLocalizationsCommand(this.Messaging, context.Localizations); |
| 67 | var localizationsByCulture = collate.Execute(); | 53 | var localizationsByCulture = collate.Execute(); |
| 68 | 54 | ||
| 69 | if (this.Messaging.EncounteredError) | 55 | if (this.Messaging.EncounteredError) |
| @@ -71,20 +57,20 @@ namespace WixToolset.Core | |||
| 71 | return null; | 57 | return null; |
| 72 | } | 58 | } |
| 73 | 59 | ||
| 74 | var embedFilePaths = this.ResolveFilePathsToEmbed(sections); | 60 | var embedFilePaths = this.ResolveFilePathsToEmbed(context, sections); |
| 75 | 61 | ||
| 76 | foreach (var section in sections) | 62 | foreach (var section in sections) |
| 77 | { | 63 | { |
| 78 | section.LibraryId = this.Context.LibraryId; | 64 | section.LibraryId = context.LibraryId; |
| 79 | } | 65 | } |
| 80 | 66 | ||
| 81 | library = new Intermediate(this.Context.LibraryId, sections, localizationsByCulture, embedFilePaths); | 67 | library = new Intermediate(context.LibraryId, sections, localizationsByCulture, embedFilePaths); |
| 82 | 68 | ||
| 83 | this.Validate(library); | 69 | this.Validate(library); |
| 84 | } | 70 | } |
| 85 | finally | 71 | finally |
| 86 | { | 72 | { |
| 87 | foreach (var extension in this.Context.Extensions) | 73 | foreach (var extension in context.Extensions) |
| 88 | { | 74 | { |
| 89 | extension.PostCombine(library); | 75 | extension.PostCombine(library); |
| 90 | } | 76 | } |
| @@ -99,7 +85,7 @@ namespace WixToolset.Core | |||
| 99 | /// <param name="library">Library to validate.</param> | 85 | /// <param name="library">Library to validate.</param> |
| 100 | private void Validate(Intermediate library) | 86 | private void Validate(Intermediate library) |
| 101 | { | 87 | { |
| 102 | FindEntrySectionAndLoadSymbolsCommand find = new FindEntrySectionAndLoadSymbolsCommand(this.Messaging, library.Sections); | 88 | var find = new FindEntrySectionAndLoadSymbolsCommand(this.Messaging, library.Sections); |
| 103 | find.Execute(); | 89 | find.Execute(); |
| 104 | 90 | ||
| 105 | // TODO: Consider bringing this sort of verification back. | 91 | // TODO: Consider bringing this sort of verification back. |
| @@ -113,16 +99,16 @@ namespace WixToolset.Core | |||
| 113 | // } | 99 | // } |
| 114 | } | 100 | } |
| 115 | 101 | ||
| 116 | private List<string> ResolveFilePathsToEmbed(IEnumerable<IntermediateSection> sections) | 102 | private List<string> ResolveFilePathsToEmbed(ILibraryContext context, IEnumerable<IntermediateSection> sections) |
| 117 | { | 103 | { |
| 118 | var embedFilePaths = new List<string>(); | 104 | var embedFilePaths = new List<string>(); |
| 119 | 105 | ||
| 120 | // Resolve paths to files that are to be embedded in the library. | 106 | // Resolve paths to files that are to be embedded in the library. |
| 121 | if (this.Context.BindFiles) | 107 | if (context.BindFiles) |
| 122 | { | 108 | { |
| 123 | var variableResolver = new WixVariableResolver(this.Messaging); | 109 | var variableResolver = new WixVariableResolver(this.Messaging); |
| 124 | 110 | ||
| 125 | var fileResolver = new FileResolver(this.Context.BindPaths, this.Context.Extensions); | 111 | var fileResolver = new FileResolver(context.BindPaths, context.Extensions); |
| 126 | 112 | ||
| 127 | foreach (var tuple in sections.SelectMany(s => s.Tuples)) | 113 | foreach (var tuple in sections.SelectMany(s => s.Tuples)) |
| 128 | { | 114 | { |
diff --git a/src/WixToolset.Core/Linker.cs b/src/WixToolset.Core/Linker.cs index 04188e53..80d57fa7 100644 --- a/src/WixToolset.Core/Linker.cs +++ b/src/WixToolset.Core/Linker.cs | |||
| @@ -11,19 +11,18 @@ namespace WixToolset.Core | |||
| 11 | using WixToolset.Core.Link; | 11 | using WixToolset.Core.Link; |
| 12 | using WixToolset.Data; | 12 | using WixToolset.Data; |
| 13 | using WixToolset.Data.Tuples; | 13 | using WixToolset.Data.Tuples; |
| 14 | using WixToolset.Extensibility; | ||
| 15 | using WixToolset.Extensibility.Data; | 14 | using WixToolset.Extensibility.Data; |
| 16 | using WixToolset.Extensibility.Services; | 15 | using WixToolset.Extensibility.Services; |
| 17 | 16 | ||
| 18 | /// <summary> | 17 | /// <summary> |
| 19 | /// Linker core of the WiX toolset. | 18 | /// Linker core of the WiX toolset. |
| 20 | /// </summary> | 19 | /// </summary> |
| 21 | internal class Linker | 20 | internal class Linker : ILinker |
| 22 | { | 21 | { |
| 23 | private static readonly char[] colonCharacter = ":".ToCharArray(); | 22 | private static readonly char[] colonCharacter = ":".ToCharArray(); |
| 24 | private static readonly string emptyGuid = Guid.Empty.ToString("B"); | 23 | private static readonly string emptyGuid = Guid.Empty.ToString("B"); |
| 25 | 24 | ||
| 26 | private bool sectionIdOnRows; | 25 | private readonly bool sectionIdOnRows; |
| 27 | 26 | ||
| 28 | /// <summary> | 27 | /// <summary> |
| 29 | /// Creates a linker. | 28 | /// Creates a linker. |
| @@ -53,32 +52,20 @@ namespace WixToolset.Core | |||
| 53 | /// <value>The option to show pedantic messages.</value> | 52 | /// <value>The option to show pedantic messages.</value> |
| 54 | public bool ShowPedanticMessages { get; set; } | 53 | public bool ShowPedanticMessages { get; set; } |
| 55 | 54 | ||
| 56 | public OutputType OutputType { get; set; } | ||
| 57 | |||
| 58 | public IEnumerable<Intermediate> Intermediates { get; set; } | ||
| 59 | |||
| 60 | public IEnumerable<Intermediate> Libraries { get; set; } | ||
| 61 | |||
| 62 | public ITupleDefinitionCreator TupleDefinitionCreator { get; set; } | ||
| 63 | |||
| 64 | /// <summary> | 55 | /// <summary> |
| 65 | /// Links a collection of sections into an output. | 56 | /// Links a collection of sections into an output. |
| 66 | /// </summary> | 57 | /// </summary> |
| 67 | /// <param name="inputs">The collection of sections to link together.</param> | 58 | /// <param name="inputs">The collection of sections to link together.</param> |
| 68 | /// <param name="expectedOutputType">Expected output type, based on output file extension provided to the linker.</param> | 59 | /// <param name="expectedOutputType">Expected output type, based on output file extension provided to the linker.</param> |
| 69 | /// <returns>Output object from the linking.</returns> | 60 | /// <returns>Output object from the linking.</returns> |
| 70 | public Intermediate Execute() | 61 | public Intermediate Link(ILinkContext context) |
| 71 | { | 62 | { |
| 72 | var extensionManager = this.ServiceProvider.GetService<IExtensionManager>(); | 63 | this.Context = context; |
| 73 | |||
| 74 | var creator = this.TupleDefinitionCreator ?? this.ServiceProvider.GetService<ITupleDefinitionCreator>(); | ||
| 75 | 64 | ||
| 76 | this.Context = this.ServiceProvider.GetService<ILinkContext>(); | 65 | if (this.Context.TupleDefinitionCreator == null) |
| 77 | this.Context.Extensions = extensionManager.Create<ILinkerExtension>(); | 66 | { |
| 78 | this.Context.ExtensionData = extensionManager.Create<IExtensionData>(); | 67 | this.Context.TupleDefinitionCreator = this.ServiceProvider.GetService<ITupleDefinitionCreator>(); |
| 79 | this.Context.ExpectedOutputType = this.OutputType; | 68 | } |
| 80 | this.Context.Intermediates = this.Intermediates.Concat(this.Libraries).ToList(); | ||
| 81 | this.Context.TupleDefinitionCreator = creator; | ||
| 82 | 69 | ||
| 83 | foreach (var extension in this.Context.Extensions) | 70 | foreach (var extension in this.Context.Extensions) |
| 84 | { | 71 | { |
| @@ -117,7 +104,7 @@ namespace WixToolset.Core | |||
| 117 | Hashtable generatedShortFileNames = new Hashtable(); | 104 | Hashtable generatedShortFileNames = new Hashtable(); |
| 118 | #endif | 105 | #endif |
| 119 | 106 | ||
| 120 | Hashtable multipleFeatureComponents = new Hashtable(); | 107 | var multipleFeatureComponents = new Hashtable(); |
| 121 | 108 | ||
| 122 | var wixVariables = new Dictionary<string, WixVariableTuple>(); | 109 | var wixVariables = new Dictionary<string, WixVariableTuple>(); |
| 123 | 110 | ||
| @@ -238,7 +225,7 @@ namespace WixToolset.Core | |||
| 238 | sectionCount++; | 225 | sectionCount++; |
| 239 | 226 | ||
| 240 | var sectionId = section.Id; | 227 | var sectionId = section.Id; |
| 241 | if (null == sectionId && this.sectionIdOnRows) | 228 | if (null == sectionId && sectionIdOnRows) |
| 242 | { | 229 | { |
| 243 | sectionId = "wix.section." + sectionCount.ToString(CultureInfo.InvariantCulture); | 230 | sectionId = "wix.section." + sectionCount.ToString(CultureInfo.InvariantCulture); |
| 244 | } | 231 | } |
| @@ -256,12 +243,12 @@ namespace WixToolset.Core | |||
| 256 | break; | 243 | break; |
| 257 | #endif | 244 | #endif |
| 258 | 245 | ||
| 259 | case TupleDefinitionType.Class: | 246 | case TupleDefinitionType.Class: |
| 260 | if (SectionType.Product == resolvedSection.Type) | 247 | if (SectionType.Product == resolvedSection.Type) |
| 261 | { | 248 | { |
| 262 | this.ResolveFeatures(tuple, 2, 11, componentsToFeatures, multipleFeatureComponents); | 249 | this.ResolveFeatures(tuple, 2, 11, componentsToFeatures, multipleFeatureComponents); |
| 263 | } | 250 | } |
| 264 | break; | 251 | break; |
| 265 | 252 | ||
| 266 | #if MOVE_TO_BACKEND | 253 | #if MOVE_TO_BACKEND |
| 267 | case "CustomAction": | 254 | case "CustomAction": |
| @@ -315,12 +302,12 @@ namespace WixToolset.Core | |||
| 315 | } | 302 | } |
| 316 | break; | 303 | break; |
| 317 | #endif | 304 | #endif |
| 318 | case TupleDefinitionType.Extension: | 305 | case TupleDefinitionType.Extension: |
| 319 | if (SectionType.Product == resolvedSection.Type) | 306 | if (SectionType.Product == resolvedSection.Type) |
| 320 | { | 307 | { |
| 321 | this.ResolveFeatures(tuple, 1, 4, componentsToFeatures, multipleFeatureComponents); | 308 | this.ResolveFeatures(tuple, 1, 4, componentsToFeatures, multipleFeatureComponents); |
| 322 | } | 309 | } |
| 323 | break; | 310 | break; |
| 324 | 311 | ||
| 325 | #if MOVE_TO_BACKEND | 312 | #if MOVE_TO_BACKEND |
| 326 | case TupleDefinitionType.ModuleSubstitution: | 313 | case TupleDefinitionType.ModuleSubstitution: |
| @@ -332,12 +319,12 @@ namespace WixToolset.Core | |||
| 332 | break; | 319 | break; |
| 333 | #endif | 320 | #endif |
| 334 | 321 | ||
| 335 | case TupleDefinitionType.MsiAssembly: | 322 | case TupleDefinitionType.MsiAssembly: |
| 336 | if (SectionType.Product == resolvedSection.Type) | 323 | if (SectionType.Product == resolvedSection.Type) |
| 337 | { | 324 | { |
| 338 | this.ResolveFeatures(tuple, 0, 1, componentsToFeatures, multipleFeatureComponents); | 325 | this.ResolveFeatures(tuple, 0, 1, componentsToFeatures, multipleFeatureComponents); |
| 339 | } | 326 | } |
| 340 | break; | 327 | break; |
| 341 | 328 | ||
| 342 | #if MOVE_TO_BACKEND | 329 | #if MOVE_TO_BACKEND |
| 343 | case "ProgId": | 330 | case "ProgId": |
| @@ -359,26 +346,26 @@ namespace WixToolset.Core | |||
| 359 | break; | 346 | break; |
| 360 | #endif | 347 | #endif |
| 361 | 348 | ||
| 362 | case TupleDefinitionType.PublishComponent: | 349 | case TupleDefinitionType.PublishComponent: |
| 363 | if (SectionType.Product == resolvedSection.Type) | 350 | if (SectionType.Product == resolvedSection.Type) |
| 364 | { | 351 | { |
| 365 | this.ResolveFeatures(tuple, 2, 4, componentsToFeatures, multipleFeatureComponents); | 352 | this.ResolveFeatures(tuple, 2, 4, componentsToFeatures, multipleFeatureComponents); |
| 366 | } | 353 | } |
| 367 | break; | 354 | break; |
| 368 | 355 | ||
| 369 | case TupleDefinitionType.Shortcut: | 356 | case TupleDefinitionType.Shortcut: |
| 370 | if (SectionType.Product == resolvedSection.Type) | 357 | if (SectionType.Product == resolvedSection.Type) |
| 371 | { | 358 | { |
| 372 | this.ResolveFeatures(tuple, 3, 4, componentsToFeatures, multipleFeatureComponents); | 359 | this.ResolveFeatures(tuple, 3, 4, componentsToFeatures, multipleFeatureComponents); |
| 373 | } | 360 | } |
| 374 | break; | 361 | break; |
| 375 | 362 | ||
| 376 | case TupleDefinitionType.TypeLib: | 363 | case TupleDefinitionType.TypeLib: |
| 377 | if (SectionType.Product == resolvedSection.Type) | 364 | if (SectionType.Product == resolvedSection.Type) |
| 378 | { | 365 | { |
| 379 | this.ResolveFeatures(tuple, 2, 6, componentsToFeatures, multipleFeatureComponents); | 366 | this.ResolveFeatures(tuple, 2, 6, componentsToFeatures, multipleFeatureComponents); |
| 380 | } | 367 | } |
| 381 | break; | 368 | break; |
| 382 | 369 | ||
| 383 | #if SOLVE_CUSTOM_TABLE | 370 | #if SOLVE_CUSTOM_TABLE |
| 384 | case "WixCustomTable": | 371 | case "WixCustomTable": |
| @@ -396,9 +383,9 @@ namespace WixToolset.Core | |||
| 396 | break; | 383 | break; |
| 397 | #endif | 384 | #endif |
| 398 | 385 | ||
| 399 | case TupleDefinitionType.WixEnsureTable: | 386 | case TupleDefinitionType.WixEnsureTable: |
| 400 | ensureTableRows.Add(tuple); | 387 | ensureTableRows.Add(tuple); |
| 401 | break; | 388 | break; |
| 402 | 389 | ||
| 403 | 390 | ||
| 404 | #if MOVE_TO_BACKEND | 391 | #if MOVE_TO_BACKEND |
| @@ -421,45 +408,45 @@ namespace WixToolset.Core | |||
| 421 | break; | 408 | break; |
| 422 | #endif | 409 | #endif |
| 423 | 410 | ||
| 424 | case TupleDefinitionType.WixMerge: | 411 | case TupleDefinitionType.WixMerge: |
| 425 | if (SectionType.Product == resolvedSection.Type) | 412 | if (SectionType.Product == resolvedSection.Type) |
| 426 | { | 413 | { |
| 427 | this.ResolveFeatures(tuple, 0, 7, modulesToFeatures, null); | 414 | this.ResolveFeatures(tuple, 0, 7, modulesToFeatures, null); |
| 428 | } | 415 | } |
| 429 | break; | 416 | break; |
| 430 | 417 | ||
| 431 | case TupleDefinitionType.WixComplexReference: | 418 | case TupleDefinitionType.WixComplexReference: |
| 432 | copyTuple = false; | 419 | copyTuple = false; |
| 433 | break; | 420 | break; |
| 434 | 421 | ||
| 435 | case TupleDefinitionType.WixSimpleReference: | 422 | case TupleDefinitionType.WixSimpleReference: |
| 436 | copyTuple = false; | 423 | copyTuple = false; |
| 437 | break; | 424 | break; |
| 438 | 425 | ||
| 439 | case TupleDefinitionType.WixVariable: | 426 | case TupleDefinitionType.WixVariable: |
| 440 | // check for colliding values and collect the wix variable rows | 427 | // check for colliding values and collect the wix variable rows |
| 441 | { | 428 | { |
| 442 | var row = (WixVariableTuple)tuple; | 429 | var row = (WixVariableTuple)tuple; |
| 443 | 430 | ||
| 444 | if (wixVariables.TryGetValue(row.WixVariable, out var collidingRow)) | 431 | if (wixVariables.TryGetValue(row.WixVariable, out var collidingRow)) |
| 445 | { | 432 | { |
| 446 | if (collidingRow.Overridable && !row.Overridable) | 433 | if (collidingRow.Overridable && !row.Overridable) |
| 447 | { | 434 | { |
| 448 | wixVariables[row.WixVariable] = row; | 435 | wixVariables[row.WixVariable] = row; |
| 449 | } | 436 | } |
| 450 | else if (!row.Overridable || (collidingRow.Overridable && row.Overridable)) | 437 | else if (!row.Overridable || (collidingRow.Overridable && row.Overridable)) |
| 451 | { | 438 | { |
| 452 | this.OnMessage(ErrorMessages.WixVariableCollision(row.SourceLineNumbers, row.WixVariable)); | 439 | this.OnMessage(ErrorMessages.WixVariableCollision(row.SourceLineNumbers, row.WixVariable)); |
| 453 | } | ||
| 454 | } | ||
| 455 | else | ||
| 456 | { | ||
| 457 | wixVariables.Add(row.WixVariable, row); | ||
| 458 | } | ||
| 459 | } | 440 | } |
| 441 | } | ||
| 442 | else | ||
| 443 | { | ||
| 444 | wixVariables.Add(row.WixVariable, row); | ||
| 445 | } | ||
| 446 | } | ||
| 460 | 447 | ||
| 461 | copyTuple = false; | 448 | copyTuple = false; |
| 462 | break; | 449 | break; |
| 463 | } | 450 | } |
| 464 | 451 | ||
| 465 | if (copyTuple) | 452 | if (copyTuple) |
| @@ -624,7 +611,7 @@ namespace WixToolset.Core | |||
| 624 | #endif | 611 | #endif |
| 625 | 612 | ||
| 626 | //correct the section Id in FeatureComponents table | 613 | //correct the section Id in FeatureComponents table |
| 627 | if (this.sectionIdOnRows) | 614 | if (sectionIdOnRows) |
| 628 | { | 615 | { |
| 629 | //var componentSectionIds = new Dictionary<string, string>(); | 616 | //var componentSectionIds = new Dictionary<string, string>(); |
| 630 | 617 | ||
| @@ -1152,7 +1139,7 @@ namespace WixToolset.Core | |||
| 1152 | /// <param name="modulesToFeatures">Module to feature complex references.</param> | 1139 | /// <param name="modulesToFeatures">Module to feature complex references.</param> |
| 1153 | private void ProcessComplexReferences(IntermediateSection resolvedSection, IEnumerable<IntermediateSection> sections, ISet<string> referencedComponents, ConnectToFeatureCollection componentsToFeatures, ConnectToFeatureCollection featuresToFeatures, ConnectToFeatureCollection modulesToFeatures) | 1140 | private void ProcessComplexReferences(IntermediateSection resolvedSection, IEnumerable<IntermediateSection> sections, ISet<string> referencedComponents, ConnectToFeatureCollection componentsToFeatures, ConnectToFeatureCollection featuresToFeatures, ConnectToFeatureCollection modulesToFeatures) |
| 1154 | { | 1141 | { |
| 1155 | Hashtable componentsToModules = new Hashtable(); | 1142 | var componentsToModules = new Hashtable(); |
| 1156 | 1143 | ||
| 1157 | foreach (var section in sections) | 1144 | foreach (var section in sections) |
| 1158 | { | 1145 | { |
| @@ -1163,154 +1150,154 @@ namespace WixToolset.Core | |||
| 1163 | ConnectToFeature connection; | 1150 | ConnectToFeature connection; |
| 1164 | switch (wixComplexReferenceRow.ParentType) | 1151 | switch (wixComplexReferenceRow.ParentType) |
| 1165 | { | 1152 | { |
| 1166 | case ComplexReferenceParentType.Feature: | 1153 | case ComplexReferenceParentType.Feature: |
| 1167 | switch (wixComplexReferenceRow.ChildType) | 1154 | switch (wixComplexReferenceRow.ChildType) |
| 1155 | { | ||
| 1156 | case ComplexReferenceChildType.Component: | ||
| 1157 | connection = componentsToFeatures[wixComplexReferenceRow.Child]; | ||
| 1158 | if (null == connection) | ||
| 1168 | { | 1159 | { |
| 1169 | case ComplexReferenceChildType.Component: | 1160 | componentsToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, wixComplexReferenceRow.Parent, wixComplexReferenceRow.IsPrimary)); |
| 1170 | connection = componentsToFeatures[wixComplexReferenceRow.Child]; | 1161 | } |
| 1171 | if (null == connection) | 1162 | else if (wixComplexReferenceRow.IsPrimary) |
| 1172 | { | 1163 | { |
| 1173 | componentsToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, wixComplexReferenceRow.Parent, wixComplexReferenceRow.IsPrimary)); | 1164 | if (connection.IsExplicitPrimaryFeature) |
| 1174 | } | 1165 | { |
| 1175 | else if (wixComplexReferenceRow.IsPrimary) | 1166 | this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), connection.PrimaryFeature ?? resolvedSection.Id)); |
| 1176 | { | 1167 | continue; |
| 1177 | if (connection.IsExplicitPrimaryFeature) | 1168 | } |
| 1178 | { | 1169 | else |
| 1179 | this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), connection.PrimaryFeature ?? resolvedSection.Id)); | 1170 | { |
| 1180 | continue; | 1171 | connection.ConnectFeatures.Add(connection.PrimaryFeature); // move the guessed primary feature to the list of connects |
| 1181 | } | 1172 | connection.PrimaryFeature = wixComplexReferenceRow.Parent; // set the new primary feature |
| 1182 | else | 1173 | connection.IsExplicitPrimaryFeature = true; // and make sure we remember that we set it so we can fail if we try to set it again |
| 1183 | { | 1174 | } |
| 1184 | connection.ConnectFeatures.Add(connection.PrimaryFeature); // move the guessed primary feature to the list of connects | 1175 | } |
| 1185 | connection.PrimaryFeature = wixComplexReferenceRow.Parent; // set the new primary feature | 1176 | else |
| 1186 | connection.IsExplicitPrimaryFeature = true; // and make sure we remember that we set it so we can fail if we try to set it again | 1177 | { |
| 1187 | } | 1178 | connection.ConnectFeatures.Add(wixComplexReferenceRow.Parent); |
| 1188 | } | 1179 | } |
| 1189 | else | ||
| 1190 | { | ||
| 1191 | connection.ConnectFeatures.Add(wixComplexReferenceRow.Parent); | ||
| 1192 | } | ||
| 1193 | |||
| 1194 | // add a row to the FeatureComponents table | ||
| 1195 | var featureComponent = new FeatureComponentsTuple(); | ||
| 1196 | featureComponent.Feature_ = wixComplexReferenceRow.Parent; | ||
| 1197 | featureComponent.Component_ = wixComplexReferenceRow.Child; | ||
| 1198 | 1180 | ||
| 1199 | featureComponents.Add(featureComponent); | 1181 | // add a row to the FeatureComponents table |
| 1182 | var featureComponent = new FeatureComponentsTuple(); | ||
| 1183 | featureComponent.Feature_ = wixComplexReferenceRow.Parent; | ||
| 1184 | featureComponent.Component_ = wixComplexReferenceRow.Child; | ||
| 1200 | 1185 | ||
| 1201 | // index the component for finding orphaned records | 1186 | featureComponents.Add(featureComponent); |
| 1202 | var symbolName = String.Concat("Component:", wixComplexReferenceRow.Child); | ||
| 1203 | referencedComponents.Add(symbolName); | ||
| 1204 | 1187 | ||
| 1205 | break; | 1188 | // index the component for finding orphaned records |
| 1189 | var symbolName = String.Concat("Component:", wixComplexReferenceRow.Child); | ||
| 1190 | referencedComponents.Add(symbolName); | ||
| 1206 | 1191 | ||
| 1207 | case ComplexReferenceChildType.Feature: | 1192 | break; |
| 1208 | connection = featuresToFeatures[wixComplexReferenceRow.Child]; | ||
| 1209 | if (null != connection) | ||
| 1210 | { | ||
| 1211 | this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id))); | ||
| 1212 | continue; | ||
| 1213 | } | ||
| 1214 | 1193 | ||
| 1215 | featuresToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, wixComplexReferenceRow.Parent, wixComplexReferenceRow.IsPrimary)); | 1194 | case ComplexReferenceChildType.Feature: |
| 1216 | break; | 1195 | connection = featuresToFeatures[wixComplexReferenceRow.Child]; |
| 1196 | if (null != connection) | ||
| 1197 | { | ||
| 1198 | this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id))); | ||
| 1199 | continue; | ||
| 1200 | } | ||
| 1217 | 1201 | ||
| 1218 | case ComplexReferenceChildType.Module: | 1202 | featuresToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, wixComplexReferenceRow.Parent, wixComplexReferenceRow.IsPrimary)); |
| 1219 | connection = modulesToFeatures[wixComplexReferenceRow.Child]; | 1203 | break; |
| 1220 | if (null == connection) | ||
| 1221 | { | ||
| 1222 | modulesToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, wixComplexReferenceRow.Parent, wixComplexReferenceRow.IsPrimary)); | ||
| 1223 | } | ||
| 1224 | else if (wixComplexReferenceRow.IsPrimary) | ||
| 1225 | { | ||
| 1226 | if (connection.IsExplicitPrimaryFeature) | ||
| 1227 | { | ||
| 1228 | this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id))); | ||
| 1229 | continue; | ||
| 1230 | } | ||
| 1231 | else | ||
| 1232 | { | ||
| 1233 | connection.ConnectFeatures.Add(connection.PrimaryFeature); // move the guessed primary feature to the list of connects | ||
| 1234 | connection.PrimaryFeature = wixComplexReferenceRow.Parent; // set the new primary feature | ||
| 1235 | connection.IsExplicitPrimaryFeature = true; // and make sure we remember that we set it so we can fail if we try to set it again | ||
| 1236 | } | ||
| 1237 | } | ||
| 1238 | else | ||
| 1239 | { | ||
| 1240 | connection.ConnectFeatures.Add(wixComplexReferenceRow.Parent); | ||
| 1241 | } | ||
| 1242 | break; | ||
| 1243 | 1204 | ||
| 1244 | default: | 1205 | case ComplexReferenceChildType.Module: |
| 1245 | throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType))); | 1206 | connection = modulesToFeatures[wixComplexReferenceRow.Child]; |
| 1207 | if (null == connection) | ||
| 1208 | { | ||
| 1209 | modulesToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, wixComplexReferenceRow.Parent, wixComplexReferenceRow.IsPrimary)); | ||
| 1210 | } | ||
| 1211 | else if (wixComplexReferenceRow.IsPrimary) | ||
| 1212 | { | ||
| 1213 | if (connection.IsExplicitPrimaryFeature) | ||
| 1214 | { | ||
| 1215 | this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id))); | ||
| 1216 | continue; | ||
| 1217 | } | ||
| 1218 | else | ||
| 1219 | { | ||
| 1220 | connection.ConnectFeatures.Add(connection.PrimaryFeature); // move the guessed primary feature to the list of connects | ||
| 1221 | connection.PrimaryFeature = wixComplexReferenceRow.Parent; // set the new primary feature | ||
| 1222 | connection.IsExplicitPrimaryFeature = true; // and make sure we remember that we set it so we can fail if we try to set it again | ||
| 1223 | } | ||
| 1224 | } | ||
| 1225 | else | ||
| 1226 | { | ||
| 1227 | connection.ConnectFeatures.Add(wixComplexReferenceRow.Parent); | ||
| 1246 | } | 1228 | } |
| 1247 | break; | 1229 | break; |
| 1248 | 1230 | ||
| 1249 | case ComplexReferenceParentType.Module: | 1231 | default: |
| 1250 | switch (wixComplexReferenceRow.ChildType) | 1232 | throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType))); |
| 1251 | { | 1233 | } |
| 1252 | case ComplexReferenceChildType.Component: | 1234 | break; |
| 1253 | if (componentsToModules.ContainsKey(wixComplexReferenceRow.Child)) | ||
| 1254 | { | ||
| 1255 | this.OnMessage(ErrorMessages.ComponentReferencedTwice(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.Child)); | ||
| 1256 | continue; | ||
| 1257 | } | ||
| 1258 | else | ||
| 1259 | { | ||
| 1260 | componentsToModules.Add(wixComplexReferenceRow.Child, wixComplexReferenceRow); // should always be new | ||
| 1261 | 1235 | ||
| 1262 | // add a row to the ModuleComponents table | 1236 | case ComplexReferenceParentType.Module: |
| 1263 | var moduleComponent = new ModuleComponentsTuple(); | 1237 | switch (wixComplexReferenceRow.ChildType) |
| 1264 | moduleComponent.Component = wixComplexReferenceRow.Child; | 1238 | { |
| 1265 | moduleComponent.ModuleID = wixComplexReferenceRow.Parent; | 1239 | case ComplexReferenceChildType.Component: |
| 1266 | moduleComponent.Language = Convert.ToInt32(wixComplexReferenceRow.ParentLanguage); | 1240 | if (componentsToModules.ContainsKey(wixComplexReferenceRow.Child)) |
| 1267 | } | 1241 | { |
| 1242 | this.OnMessage(ErrorMessages.ComponentReferencedTwice(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.Child)); | ||
| 1243 | continue; | ||
| 1244 | } | ||
| 1245 | else | ||
| 1246 | { | ||
| 1247 | componentsToModules.Add(wixComplexReferenceRow.Child, wixComplexReferenceRow); // should always be new | ||
| 1268 | 1248 | ||
| 1269 | // index the component for finding orphaned records | 1249 | // add a row to the ModuleComponents table |
| 1270 | string componentSymbolName = String.Concat("Component:", wixComplexReferenceRow.Child); | 1250 | var moduleComponent = new ModuleComponentsTuple(); |
| 1271 | referencedComponents.Add(componentSymbolName); | 1251 | moduleComponent.Component = wixComplexReferenceRow.Child; |
| 1252 | moduleComponent.ModuleID = wixComplexReferenceRow.Parent; | ||
| 1253 | moduleComponent.Language = Convert.ToInt32(wixComplexReferenceRow.ParentLanguage); | ||
| 1254 | } | ||
| 1272 | 1255 | ||
| 1273 | break; | 1256 | // index the component for finding orphaned records |
| 1257 | var componentSymbolName = String.Concat("Component:", wixComplexReferenceRow.Child); | ||
| 1258 | referencedComponents.Add(componentSymbolName); | ||
| 1274 | 1259 | ||
| 1275 | default: | ||
| 1276 | throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType))); | ||
| 1277 | } | ||
| 1278 | break; | 1260 | break; |
| 1279 | 1261 | ||
| 1280 | case ComplexReferenceParentType.Patch: | 1262 | default: |
| 1281 | switch (wixComplexReferenceRow.ChildType) | 1263 | throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType))); |
| 1282 | { | 1264 | } |
| 1283 | case ComplexReferenceChildType.PatchFamily: | 1265 | break; |
| 1284 | case ComplexReferenceChildType.PatchFamilyGroup: | ||
| 1285 | break; | ||
| 1286 | 1266 | ||
| 1287 | default: | 1267 | case ComplexReferenceParentType.Patch: |
| 1288 | throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType))); | 1268 | switch (wixComplexReferenceRow.ChildType) |
| 1289 | } | 1269 | { |
| 1270 | case ComplexReferenceChildType.PatchFamily: | ||
| 1271 | case ComplexReferenceChildType.PatchFamilyGroup: | ||
| 1290 | break; | 1272 | break; |
| 1291 | 1273 | ||
| 1292 | case ComplexReferenceParentType.Product: | 1274 | default: |
| 1293 | switch (wixComplexReferenceRow.ChildType) | 1275 | throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType))); |
| 1294 | { | 1276 | } |
| 1295 | case ComplexReferenceChildType.Feature: | 1277 | break; |
| 1296 | connection = featuresToFeatures[wixComplexReferenceRow.Child]; | ||
| 1297 | if (null != connection) | ||
| 1298 | { | ||
| 1299 | this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id))); | ||
| 1300 | continue; | ||
| 1301 | } | ||
| 1302 | |||
| 1303 | featuresToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, null, wixComplexReferenceRow.IsPrimary)); | ||
| 1304 | break; | ||
| 1305 | 1278 | ||
| 1306 | default: | 1279 | case ComplexReferenceParentType.Product: |
| 1307 | throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType))); | 1280 | switch (wixComplexReferenceRow.ChildType) |
| 1281 | { | ||
| 1282 | case ComplexReferenceChildType.Feature: | ||
| 1283 | connection = featuresToFeatures[wixComplexReferenceRow.Child]; | ||
| 1284 | if (null != connection) | ||
| 1285 | { | ||
| 1286 | this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id))); | ||
| 1287 | continue; | ||
| 1308 | } | 1288 | } |
| 1289 | |||
| 1290 | featuresToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, null, wixComplexReferenceRow.IsPrimary)); | ||
| 1309 | break; | 1291 | break; |
| 1310 | 1292 | ||
| 1311 | default: | 1293 | default: |
| 1312 | // Note: Groups have been processed before getting here so they are not handled by any case above. | 1294 | throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType))); |
| 1313 | throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceParentType), wixComplexReferenceRow.ParentType))); | 1295 | } |
| 1296 | break; | ||
| 1297 | |||
| 1298 | default: | ||
| 1299 | // Note: Groups have been processed before getting here so they are not handled by any case above. | ||
| 1300 | throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceParentType), wixComplexReferenceRow.ParentType))); | ||
| 1314 | } | 1301 | } |
| 1315 | } | 1302 | } |
| 1316 | 1303 | ||
| @@ -1341,7 +1328,7 @@ namespace WixToolset.Core | |||
| 1341 | foreach (var section in sections) | 1328 | foreach (var section in sections) |
| 1342 | { | 1329 | { |
| 1343 | // Count down because we'll sometimes remove items from the list. | 1330 | // Count down because we'll sometimes remove items from the list. |
| 1344 | for (int i = section.Tuples.Count - 1; i >= 0; --i) | 1331 | for (var i = section.Tuples.Count - 1; i >= 0; --i) |
| 1345 | { | 1332 | { |
| 1346 | // Only process the "grouping parents" such as FeatureGroup, ComponentGroup, Feature, | 1333 | // Only process the "grouping parents" such as FeatureGroup, ComponentGroup, Feature, |
| 1347 | // and Module. Non-grouping complex references are simple and | 1334 | // and Module. Non-grouping complex references are simple and |
| @@ -1354,7 +1341,7 @@ namespace WixToolset.Core | |||
| 1354 | ComplexReferenceParentType.PatchFamilyGroup == wixComplexReferenceRow.ParentType || | 1341 | ComplexReferenceParentType.PatchFamilyGroup == wixComplexReferenceRow.ParentType || |
| 1355 | ComplexReferenceParentType.Product == wixComplexReferenceRow.ParentType)) | 1342 | ComplexReferenceParentType.Product == wixComplexReferenceRow.ParentType)) |
| 1356 | { | 1343 | { |
| 1357 | var parentTypeAndId = CombineTypeAndId(wixComplexReferenceRow.ParentType, wixComplexReferenceRow.Parent); | 1344 | var parentTypeAndId = this.CombineTypeAndId(wixComplexReferenceRow.ParentType, wixComplexReferenceRow.Parent); |
| 1358 | 1345 | ||
| 1359 | // Group all complex references with a common parent | 1346 | // Group all complex references with a common parent |
| 1360 | // together so we can find them quickly while processing in | 1347 | // together so we can find them quickly while processing in |
| @@ -1402,7 +1389,7 @@ namespace WixToolset.Core | |||
| 1402 | // complex references should all be flattened. | 1389 | // complex references should all be flattened. |
| 1403 | var keys = parentGroupsNeedingProcessing.Keys.ToList(); | 1390 | var keys = parentGroupsNeedingProcessing.Keys.ToList(); |
| 1404 | 1391 | ||
| 1405 | foreach (string key in keys) | 1392 | foreach (var key in keys) |
| 1406 | { | 1393 | { |
| 1407 | if (parentGroupsNeedingProcessing.ContainsKey(key)) | 1394 | if (parentGroupsNeedingProcessing.ContainsKey(key)) |
| 1408 | { | 1395 | { |
| @@ -1466,14 +1453,14 @@ namespace WixToolset.Core | |||
| 1466 | foreach (var wixComplexReferenceRow in referencesToParent) | 1453 | foreach (var wixComplexReferenceRow in referencesToParent) |
| 1467 | { | 1454 | { |
| 1468 | Debug.Assert(ComplexReferenceParentType.ComponentGroup == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.FeatureGroup == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.Feature == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.Module == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.Product == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.PatchFamilyGroup == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.Patch == wixComplexReferenceRow.ParentType); | 1455 | Debug.Assert(ComplexReferenceParentType.ComponentGroup == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.FeatureGroup == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.Feature == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.Module == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.Product == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.PatchFamilyGroup == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.Patch == wixComplexReferenceRow.ParentType); |
| 1469 | Debug.Assert(parentTypeAndId == CombineTypeAndId(wixComplexReferenceRow.ParentType, wixComplexReferenceRow.Parent)); | 1456 | Debug.Assert(parentTypeAndId == this.CombineTypeAndId(wixComplexReferenceRow.ParentType, wixComplexReferenceRow.Parent)); |
| 1470 | 1457 | ||
| 1471 | // We are only interested processing when the child is a group. | 1458 | // We are only interested processing when the child is a group. |
| 1472 | if ((ComplexReferenceChildType.ComponentGroup == wixComplexReferenceRow.ChildType) || | 1459 | if ((ComplexReferenceChildType.ComponentGroup == wixComplexReferenceRow.ChildType) || |
| 1473 | (ComplexReferenceChildType.FeatureGroup == wixComplexReferenceRow.ChildType) || | 1460 | (ComplexReferenceChildType.FeatureGroup == wixComplexReferenceRow.ChildType) || |
| 1474 | (ComplexReferenceChildType.PatchFamilyGroup == wixComplexReferenceRow.ChildType)) | 1461 | (ComplexReferenceChildType.PatchFamilyGroup == wixComplexReferenceRow.ChildType)) |
| 1475 | { | 1462 | { |
| 1476 | string childTypeAndId = CombineTypeAndId(wixComplexReferenceRow.ChildType, wixComplexReferenceRow.Child); | 1463 | var childTypeAndId = this.CombineTypeAndId(wixComplexReferenceRow.ChildType, wixComplexReferenceRow.Child); |
| 1477 | if (loopDetector.Contains(childTypeAndId)) | 1464 | if (loopDetector.Contains(childTypeAndId)) |
| 1478 | { | 1465 | { |
| 1479 | // Create a comma delimited list of the references that participate in the | 1466 | // Create a comma delimited list of the references that participate in the |
| @@ -1531,7 +1518,7 @@ namespace WixToolset.Core | |||
| 1531 | // duplicate complex references that occurred during the merge. | 1518 | // duplicate complex references that occurred during the merge. |
| 1532 | referencesToParent.AddRange(allNewChildComplexReferences); | 1519 | referencesToParent.AddRange(allNewChildComplexReferences); |
| 1533 | referencesToParent.Sort(ComplexReferenceComparision); | 1520 | referencesToParent.Sort(ComplexReferenceComparision); |
| 1534 | for (int i = referencesToParent.Count - 1; i >= 0; --i) | 1521 | for (var i = referencesToParent.Count - 1; i >= 0; --i) |
| 1535 | { | 1522 | { |
| 1536 | var wixComplexReferenceRow = referencesToParent[i]; | 1523 | var wixComplexReferenceRow = referencesToParent[i]; |
| 1537 | 1524 | ||
| @@ -1716,7 +1703,7 @@ namespace WixToolset.Core | |||
| 1716 | 1703 | ||
| 1717 | if (emptyGuid == featureId) | 1704 | if (emptyGuid == featureId) |
| 1718 | { | 1705 | { |
| 1719 | ConnectToFeature connection = connectToFeatures[connectionId]; | 1706 | var connection = connectToFeatures[connectionId]; |
| 1720 | 1707 | ||
| 1721 | if (null == connection) | 1708 | if (null == connection) |
| 1722 | { | 1709 | { |
diff --git a/src/WixToolset.Core/PreprocessContext.cs b/src/WixToolset.Core/PreprocessContext.cs index 151506e2..749bf213 100644 --- a/src/WixToolset.Core/PreprocessContext.cs +++ b/src/WixToolset.Core/PreprocessContext.cs | |||
| @@ -21,9 +21,9 @@ namespace WixToolset.Core | |||
| 21 | 21 | ||
| 22 | public Platform Platform { get; set; } | 22 | public Platform Platform { get; set; } |
| 23 | 23 | ||
| 24 | public IList<string> IncludeSearchPaths { get; set; } | 24 | public IEnumerable<string> IncludeSearchPaths { get; set; } |
| 25 | 25 | ||
| 26 | public string SourceFile { get; set; } | 26 | public string SourcePath { get; set; } |
| 27 | 27 | ||
| 28 | public IDictionary<string, string> Variables { get; set; } | 28 | public IDictionary<string, string> Variables { get; set; } |
| 29 | 29 | ||
diff --git a/src/WixToolset.Core/Preprocessor.cs b/src/WixToolset.Core/Preprocessor.cs index 9f0ab1bb..5a9cf115 100644 --- a/src/WixToolset.Core/Preprocessor.cs +++ b/src/WixToolset.Core/Preprocessor.cs | |||
| @@ -6,7 +6,6 @@ namespace WixToolset.Core | |||
| 6 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
| 7 | using System.Globalization; | 7 | using System.Globalization; |
| 8 | using System.IO; | 8 | using System.IO; |
| 9 | using System.Linq; | ||
| 10 | using System.Text; | 9 | using System.Text; |
| 11 | using System.Text.RegularExpressions; | 10 | using System.Text.RegularExpressions; |
| 12 | using System.Xml; | 11 | using System.Xml; |
| @@ -20,7 +19,7 @@ namespace WixToolset.Core | |||
| 20 | /// <summary> | 19 | /// <summary> |
| 21 | /// Preprocessor object | 20 | /// Preprocessor object |
| 22 | /// </summary> | 21 | /// </summary> |
| 23 | internal class Preprocessor | 22 | internal class Preprocessor : IPreprocessor |
| 24 | { | 23 | { |
| 25 | private static readonly Regex DefineRegex = new Regex(@"^\s*(?<varName>.+?)\s*(=\s*(?<varValue>.+?)\s*)?$", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.ExplicitCapture); | 24 | private static readonly Regex DefineRegex = new Regex(@"^\s*(?<varName>.+?)\s*(=\s*(?<varValue>.+?)\s*)?$", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.ExplicitCapture); |
| 26 | private static readonly Regex PragmaRegex = new Regex(@"^\s*(?<pragmaName>.+?)(?<pragmaValue>[\s\(].+?)?$", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.ExplicitCapture); | 25 | private static readonly Regex PragmaRegex = new Regex(@"^\s*(?<pragmaName>.+?)(?<pragmaValue>[\s\(].+?)?$", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.ExplicitCapture); |
| @@ -30,6 +29,7 @@ namespace WixToolset.Core | |||
| 30 | ValidationFlags = System.Xml.Schema.XmlSchemaValidationFlags.None, | 29 | ValidationFlags = System.Xml.Schema.XmlSchemaValidationFlags.None, |
| 31 | XmlResolver = null, | 30 | XmlResolver = null, |
| 32 | }; | 31 | }; |
| 32 | |||
| 33 | private static readonly XmlReaderSettings FragmentXmlReaderSettings = new XmlReaderSettings() | 33 | private static readonly XmlReaderSettings FragmentXmlReaderSettings = new XmlReaderSettings() |
| 34 | { | 34 | { |
| 35 | ConformanceLevel = ConformanceLevel.Fragment, | 35 | ConformanceLevel = ConformanceLevel.Fragment, |
| @@ -44,14 +44,6 @@ namespace WixToolset.Core | |||
| 44 | this.Messaging = this.ServiceProvider.GetService<IMessaging>(); | 44 | this.Messaging = this.ServiceProvider.GetService<IMessaging>(); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | public IEnumerable<string> IncludeSearchPaths { get; set; } | ||
| 48 | |||
| 49 | public Platform Platform { get; set; } | ||
| 50 | |||
| 51 | public string SourcePath { get; set; } | ||
| 52 | |||
| 53 | public IDictionary<string, string> Variables { get; set; } | ||
| 54 | |||
| 55 | private IServiceProvider ServiceProvider { get; } | 47 | private IServiceProvider ServiceProvider { get; } |
| 56 | 48 | ||
| 57 | private IMessaging Messaging { get; } | 49 | private IMessaging Messaging { get; } |
| @@ -108,19 +100,21 @@ namespace WixToolset.Core | |||
| 108 | /// </summary> | 100 | /// </summary> |
| 109 | /// <param name="context">The preprocessing context.</param> | 101 | /// <param name="context">The preprocessing context.</param> |
| 110 | /// <returns>XDocument with the postprocessed data.</returns> | 102 | /// <returns>XDocument with the postprocessed data.</returns> |
| 111 | public XDocument Execute() | 103 | public XDocument Preprocess(IPreprocessContext context) |
| 112 | { | 104 | { |
| 113 | this.Context = this.CreateContext(); | 105 | this.Context = context; |
| 106 | this.Context.CurrentSourceLineNumber = new SourceLineNumber(context.SourcePath); | ||
| 107 | this.Context.Variables = this.Context.Variables == null ? new Dictionary<string, string>() : new Dictionary<string, string>(this.Context.Variables); | ||
| 114 | 108 | ||
| 115 | this.PreProcess(); | 109 | this.PreProcess(); |
| 116 | 110 | ||
| 117 | XDocument document; | 111 | XDocument document; |
| 118 | using (XmlReader reader = XmlReader.Create(this.Context.SourceFile, DocumentXmlReaderSettings)) | 112 | using (var reader = XmlReader.Create(this.Context.SourcePath, DocumentXmlReaderSettings)) |
| 119 | { | 113 | { |
| 120 | document = this.Process(reader); | 114 | document = this.Process(reader); |
| 121 | } | 115 | } |
| 122 | 116 | ||
| 123 | return PostProcess(document); | 117 | return this.PostProcess(document); |
| 124 | } | 118 | } |
| 125 | 119 | ||
| 126 | /// <summary> | 120 | /// <summary> |
| @@ -129,21 +123,23 @@ namespace WixToolset.Core | |||
| 129 | /// <param name="context">The preprocessing context.</param> | 123 | /// <param name="context">The preprocessing context.</param> |
| 130 | /// <param name="reader">XmlReader to processing the context.</param> | 124 | /// <param name="reader">XmlReader to processing the context.</param> |
| 131 | /// <returns>XDocument with the postprocessed data.</returns> | 125 | /// <returns>XDocument with the postprocessed data.</returns> |
| 132 | public XDocument Execute(XmlReader reader) | 126 | public XDocument Preprocess(IPreprocessContext context, XmlReader reader) |
| 133 | { | 127 | { |
| 134 | if (String.IsNullOrEmpty(this.SourcePath) && !String.IsNullOrEmpty(reader.BaseURI)) | 128 | if (String.IsNullOrEmpty(context.SourcePath) && !String.IsNullOrEmpty(reader.BaseURI)) |
| 135 | { | 129 | { |
| 136 | var uri = new Uri(reader.BaseURI); | 130 | var uri = new Uri(reader.BaseURI); |
| 137 | this.SourcePath = uri.AbsolutePath; | 131 | context.SourcePath = uri.AbsolutePath; |
| 138 | } | 132 | } |
| 139 | 133 | ||
| 140 | this.Context = this.CreateContext(); | 134 | this.Context = context; |
| 135 | this.Context.CurrentSourceLineNumber = new SourceLineNumber(context.SourcePath); | ||
| 136 | this.Context.Variables = this.Context.Variables == null ? new Dictionary<string, string>() : new Dictionary<string, string>(this.Context.Variables); | ||
| 141 | 137 | ||
| 142 | this.PreProcess(); | 138 | this.PreProcess(); |
| 143 | 139 | ||
| 144 | var document = this.Process(reader); | 140 | var document = this.Process(reader); |
| 145 | 141 | ||
| 146 | return PostProcess(document); | 142 | return this.PostProcess(document); |
| 147 | } | 143 | } |
| 148 | 144 | ||
| 149 | /// <summary> | 145 | /// <summary> |
| @@ -160,13 +156,13 @@ namespace WixToolset.Core | |||
| 160 | this.CurrentFileStack.Push(this.Helper.GetVariableValue(this.Context, "sys", "SOURCEFILEDIR")); | 156 | this.CurrentFileStack.Push(this.Helper.GetVariableValue(this.Context, "sys", "SOURCEFILEDIR")); |
| 161 | 157 | ||
| 162 | // Process the reader into the output. | 158 | // Process the reader into the output. |
| 163 | XDocument output = new XDocument(); | 159 | var output = new XDocument(); |
| 164 | try | 160 | try |
| 165 | { | 161 | { |
| 166 | this.PreprocessReader(false, reader, output, 0); | 162 | this.PreprocessReader(false, reader, output, 0); |
| 167 | 163 | ||
| 168 | // Fire event with post-processed document. | 164 | // Fire event with post-processed document. |
| 169 | this.ProcessedStream?.Invoke(this, new ProcessedStreamEventArgs(this.Context.SourceFile, output)); | 165 | this.ProcessedStream?.Invoke(this, new ProcessedStreamEventArgs(this.Context.SourcePath, output)); |
| 170 | } | 166 | } |
| 171 | catch (XmlException e) | 167 | catch (XmlException e) |
| 172 | { | 168 | { |
| @@ -221,8 +217,8 @@ namespace WixToolset.Core | |||
| 221 | return false; | 217 | return false; |
| 222 | } | 218 | } |
| 223 | 219 | ||
| 224 | int numQuotes = 0; | 220 | var numQuotes = 0; |
| 225 | int tmpIndex = 0; | 221 | var tmpIndex = 0; |
| 226 | while (-1 != (tmpIndex = expression.IndexOf('\"', tmpIndex, index - tmpIndex))) | 222 | while (-1 != (tmpIndex = expression.IndexOf('\"', tmpIndex, index - tmpIndex))) |
| 227 | { | 223 | { |
| 228 | numQuotes++; | 224 | numQuotes++; |
| @@ -250,26 +246,26 @@ namespace WixToolset.Core | |||
| 250 | expression = expression.ToUpperInvariant(); | 246 | expression = expression.ToUpperInvariant(); |
| 251 | switch (operation) | 247 | switch (operation) |
| 252 | { | 248 | { |
| 253 | case PreprocessorOperation.Not: | 249 | case PreprocessorOperation.Not: |
| 254 | if (expression.StartsWith("NOT ", StringComparison.Ordinal) || expression.StartsWith("NOT(", StringComparison.Ordinal)) | 250 | if (expression.StartsWith("NOT ", StringComparison.Ordinal) || expression.StartsWith("NOT(", StringComparison.Ordinal)) |
| 255 | { | 251 | { |
| 256 | return true; | 252 | return true; |
| 257 | } | 253 | } |
| 258 | break; | 254 | break; |
| 259 | case PreprocessorOperation.And: | 255 | case PreprocessorOperation.And: |
| 260 | if (expression.StartsWith("AND ", StringComparison.Ordinal) || expression.StartsWith("AND(", StringComparison.Ordinal)) | 256 | if (expression.StartsWith("AND ", StringComparison.Ordinal) || expression.StartsWith("AND(", StringComparison.Ordinal)) |
| 261 | { | 257 | { |
| 262 | return true; | 258 | return true; |
| 263 | } | 259 | } |
| 264 | break; | 260 | break; |
| 265 | case PreprocessorOperation.Or: | 261 | case PreprocessorOperation.Or: |
| 266 | if (expression.StartsWith("OR ", StringComparison.Ordinal) || expression.StartsWith("OR(", StringComparison.Ordinal)) | 262 | if (expression.StartsWith("OR ", StringComparison.Ordinal) || expression.StartsWith("OR(", StringComparison.Ordinal)) |
| 267 | { | 263 | { |
| 268 | return true; | 264 | return true; |
| 269 | } | 265 | } |
| 270 | break; | 266 | break; |
| 271 | default: | 267 | default: |
| 272 | break; | 268 | break; |
| 273 | } | 269 | } |
| 274 | return false; | 270 | return false; |
| 275 | } | 271 | } |
| @@ -283,11 +279,11 @@ namespace WixToolset.Core | |||
| 283 | /// <param name="offset">Original offset for the line numbers being processed.</param> | 279 | /// <param name="offset">Original offset for the line numbers being processed.</param> |
| 284 | private void PreprocessReader(bool include, XmlReader reader, XContainer container, int offset) | 280 | private void PreprocessReader(bool include, XmlReader reader, XContainer container, int offset) |
| 285 | { | 281 | { |
| 286 | XContainer currentContainer = container; | 282 | var currentContainer = container; |
| 287 | Stack<XContainer> containerStack = new Stack<XContainer>(); | 283 | var containerStack = new Stack<XContainer>(); |
| 288 | 284 | ||
| 289 | IfContext ifContext = new IfContext(true, true, IfState.Unknown); // start by assuming we want to keep the nodes in the source code | 285 | var ifContext = new IfContext(true, true, IfState.Unknown); // start by assuming we want to keep the nodes in the source code |
| 290 | Stack<IfContext> ifStack = new Stack<IfContext>(); | 286 | var ifStack = new Stack<IfContext>(); |
| 291 | 287 | ||
| 292 | // process the reader into the writer | 288 | // process the reader into the writer |
| 293 | while (reader.Read()) | 289 | while (reader.Read()) |
| @@ -300,102 +296,102 @@ namespace WixToolset.Core | |||
| 300 | // check for changes in conditional processing | 296 | // check for changes in conditional processing |
| 301 | if (XmlNodeType.ProcessingInstruction == reader.NodeType) | 297 | if (XmlNodeType.ProcessingInstruction == reader.NodeType) |
| 302 | { | 298 | { |
| 303 | bool ignore = false; | 299 | var ignore = false; |
| 304 | string name = null; | 300 | string name = null; |
| 305 | 301 | ||
| 306 | switch (reader.LocalName) | 302 | switch (reader.LocalName) |
| 307 | { | 303 | { |
| 308 | case "if": | 304 | case "if": |
| 309 | ifStack.Push(ifContext); | 305 | ifStack.Push(ifContext); |
| 310 | if (ifContext.IsTrue) | 306 | if (ifContext.IsTrue) |
| 311 | { | 307 | { |
| 312 | ifContext = new IfContext(ifContext.IsTrue & ifContext.Active, this.EvaluateExpression(reader.Value), IfState.If); | 308 | ifContext = new IfContext(ifContext.IsTrue & ifContext.Active, this.EvaluateExpression(reader.Value), IfState.If); |
| 313 | } | 309 | } |
| 314 | else // Use a default IfContext object so we don't try to evaluate the expression if the context isn't true | 310 | else // Use a default IfContext object so we don't try to evaluate the expression if the context isn't true |
| 315 | { | 311 | { |
| 316 | ifContext = new IfContext(); | 312 | ifContext = new IfContext(); |
| 317 | } | 313 | } |
| 318 | ignore = true; | 314 | ignore = true; |
| 319 | break; | 315 | break; |
| 320 | 316 | ||
| 321 | case "ifdef": | 317 | case "ifdef": |
| 322 | ifStack.Push(ifContext); | 318 | ifStack.Push(ifContext); |
| 323 | name = reader.Value.Trim(); | 319 | name = reader.Value.Trim(); |
| 324 | if (ifContext.IsTrue) | 320 | if (ifContext.IsTrue) |
| 325 | { | 321 | { |
| 326 | ifContext = new IfContext(ifContext.IsTrue & ifContext.Active, (null != this.Helper.GetVariableValue(this.Context, name, true)), IfState.If); | 322 | ifContext = new IfContext(ifContext.IsTrue & ifContext.Active, (null != this.Helper.GetVariableValue(this.Context, name, true)), IfState.If); |
| 327 | } | 323 | } |
| 328 | else // Use a default IfContext object so we don't try to evaluate the expression if the context isn't true | 324 | else // Use a default IfContext object so we don't try to evaluate the expression if the context isn't true |
| 329 | { | 325 | { |
| 330 | ifContext = new IfContext(); | 326 | ifContext = new IfContext(); |
| 331 | } | 327 | } |
| 332 | ignore = true; | 328 | ignore = true; |
| 333 | this.IfDef?.Invoke(this, new IfDefEventArgs(sourceLineNumbers, true, ifContext.IsTrue, name)); | 329 | this.IfDef?.Invoke(this, new IfDefEventArgs(sourceLineNumbers, true, ifContext.IsTrue, name)); |
| 334 | break; | 330 | break; |
| 335 | 331 | ||
| 336 | case "ifndef": | 332 | case "ifndef": |
| 337 | ifStack.Push(ifContext); | 333 | ifStack.Push(ifContext); |
| 338 | name = reader.Value.Trim(); | 334 | name = reader.Value.Trim(); |
| 339 | if (ifContext.IsTrue) | 335 | if (ifContext.IsTrue) |
| 340 | { | 336 | { |
| 341 | ifContext = new IfContext(ifContext.IsTrue & ifContext.Active, (null == this.Helper.GetVariableValue(this.Context, name, true)), IfState.If); | 337 | ifContext = new IfContext(ifContext.IsTrue & ifContext.Active, (null == this.Helper.GetVariableValue(this.Context, name, true)), IfState.If); |
| 342 | } | 338 | } |
| 343 | else // Use a default IfContext object so we don't try to evaluate the expression if the context isn't true | 339 | else // Use a default IfContext object so we don't try to evaluate the expression if the context isn't true |
| 344 | { | 340 | { |
| 345 | ifContext = new IfContext(); | 341 | ifContext = new IfContext(); |
| 346 | } | 342 | } |
| 347 | ignore = true; | 343 | ignore = true; |
| 348 | this.IfDef?.Invoke(this, new IfDefEventArgs(sourceLineNumbers, false, !ifContext.IsTrue, name)); | 344 | this.IfDef?.Invoke(this, new IfDefEventArgs(sourceLineNumbers, false, !ifContext.IsTrue, name)); |
| 349 | break; | 345 | break; |
| 350 | 346 | ||
| 351 | case "elseif": | 347 | case "elseif": |
| 352 | if (0 == ifStack.Count) | 348 | if (0 == ifStack.Count) |
| 353 | { | 349 | { |
| 354 | throw new WixException(ErrorMessages.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "elseif")); | 350 | throw new WixException(ErrorMessages.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "elseif")); |
| 355 | } | 351 | } |
| 356 | 352 | ||
| 357 | if (IfState.If != ifContext.IfState && IfState.ElseIf != ifContext.IfState) | 353 | if (IfState.If != ifContext.IfState && IfState.ElseIf != ifContext.IfState) |
| 358 | { | 354 | { |
| 359 | throw new WixException(ErrorMessages.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "elseif")); | 355 | throw new WixException(ErrorMessages.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "elseif")); |
| 360 | } | 356 | } |
| 361 | 357 | ||
| 362 | ifContext.IfState = IfState.ElseIf; // we're now in an elseif | 358 | ifContext.IfState = IfState.ElseIf; // we're now in an elseif |
| 363 | if (!ifContext.WasEverTrue) // if we've never evaluated the if context to true, then we can try this test | 359 | if (!ifContext.WasEverTrue) // if we've never evaluated the if context to true, then we can try this test |
| 364 | { | 360 | { |
| 365 | ifContext.IsTrue = this.EvaluateExpression(reader.Value); | 361 | ifContext.IsTrue = this.EvaluateExpression(reader.Value); |
| 366 | } | 362 | } |
| 367 | else if (ifContext.IsTrue) | 363 | else if (ifContext.IsTrue) |
| 368 | { | 364 | { |
| 369 | ifContext.IsTrue = false; | 365 | ifContext.IsTrue = false; |
| 370 | } | 366 | } |
| 371 | ignore = true; | 367 | ignore = true; |
| 372 | break; | 368 | break; |
| 373 | 369 | ||
| 374 | case "else": | 370 | case "else": |
| 375 | if (0 == ifStack.Count) | 371 | if (0 == ifStack.Count) |
| 376 | { | 372 | { |
| 377 | throw new WixException(ErrorMessages.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "else")); | 373 | throw new WixException(ErrorMessages.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "else")); |
| 378 | } | 374 | } |
| 379 | 375 | ||
| 380 | if (IfState.If != ifContext.IfState && IfState.ElseIf != ifContext.IfState) | 376 | if (IfState.If != ifContext.IfState && IfState.ElseIf != ifContext.IfState) |
| 381 | { | 377 | { |
| 382 | throw new WixException(ErrorMessages.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "else")); | 378 | throw new WixException(ErrorMessages.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "else")); |
| 383 | } | 379 | } |
| 384 | 380 | ||
| 385 | ifContext.IfState = IfState.Else; // we're now in an else | 381 | ifContext.IfState = IfState.Else; // we're now in an else |
| 386 | ifContext.IsTrue = !ifContext.WasEverTrue; // if we were never true, we can be true now | 382 | ifContext.IsTrue = !ifContext.WasEverTrue; // if we were never true, we can be true now |
| 387 | ignore = true; | 383 | ignore = true; |
| 388 | break; | 384 | break; |
| 389 | 385 | ||
| 390 | case "endif": | 386 | case "endif": |
| 391 | if (0 == ifStack.Count) | 387 | if (0 == ifStack.Count) |
| 392 | { | 388 | { |
| 393 | throw new WixException(ErrorMessages.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "endif")); | 389 | throw new WixException(ErrorMessages.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "endif")); |
| 394 | } | 390 | } |
| 395 | 391 | ||
| 396 | ifContext = (IfContext)ifStack.Pop(); | 392 | ifContext = ifStack.Pop(); |
| 397 | ignore = true; | 393 | ignore = true; |
| 398 | break; | 394 | break; |
| 399 | } | 395 | } |
| 400 | 396 | ||
| 401 | if (ignore) // ignore this node since we just handled it above | 397 | if (ignore) // ignore this node since we just handled it above |
| @@ -411,134 +407,134 @@ namespace WixToolset.Core | |||
| 411 | 407 | ||
| 412 | switch (reader.NodeType) | 408 | switch (reader.NodeType) |
| 413 | { | 409 | { |
| 414 | case XmlNodeType.XmlDeclaration: | 410 | case XmlNodeType.XmlDeclaration: |
| 415 | XDocument document = currentContainer as XDocument; | 411 | var document = currentContainer as XDocument; |
| 416 | if (null != document) | 412 | if (null != document) |
| 413 | { | ||
| 414 | document.Declaration = new XDeclaration(null, null, null); | ||
| 415 | while (reader.MoveToNextAttribute()) | ||
| 417 | { | 416 | { |
| 418 | document.Declaration = new XDeclaration(null, null, null); | 417 | switch (reader.LocalName) |
| 419 | while (reader.MoveToNextAttribute()) | ||
| 420 | { | 418 | { |
| 421 | switch (reader.LocalName) | 419 | case "version": |
| 422 | { | 420 | document.Declaration.Version = reader.Value; |
| 423 | case "version": | ||
| 424 | document.Declaration.Version = reader.Value; | ||
| 425 | break; | ||
| 426 | |||
| 427 | case "encoding": | ||
| 428 | document.Declaration.Encoding = reader.Value; | ||
| 429 | break; | ||
| 430 | |||
| 431 | case "standalone": | ||
| 432 | document.Declaration.Standalone = reader.Value; | ||
| 433 | break; | ||
| 434 | } | ||
| 435 | } | ||
| 436 | |||
| 437 | } | ||
| 438 | //else | ||
| 439 | //{ | ||
| 440 | // display an error? Can this happen? | ||
| 441 | //} | ||
| 442 | break; | ||
| 443 | |||
| 444 | case XmlNodeType.ProcessingInstruction: | ||
| 445 | switch (reader.LocalName) | ||
| 446 | { | ||
| 447 | case "define": | ||
| 448 | this.PreprocessDefine(reader.Value); | ||
| 449 | break; | ||
| 450 | |||
| 451 | case "error": | ||
| 452 | this.PreprocessError(reader.Value); | ||
| 453 | break; | ||
| 454 | |||
| 455 | case "warning": | ||
| 456 | this.PreprocessWarning(reader.Value); | ||
| 457 | break; | 421 | break; |
| 458 | 422 | ||
| 459 | case "undef": | 423 | case "encoding": |
| 460 | this.PreprocessUndef(reader.Value); | 424 | document.Declaration.Encoding = reader.Value; |
| 461 | break; | 425 | break; |
| 462 | 426 | ||
| 463 | case "include": | 427 | case "standalone": |
| 464 | this.UpdateCurrentLineNumber(reader, offset); | 428 | document.Declaration.Standalone = reader.Value; |
| 465 | this.PreprocessInclude(reader.Value, currentContainer); | ||
| 466 | break; | 429 | break; |
| 430 | } | ||
| 431 | } | ||
| 467 | 432 | ||
| 468 | case "foreach": | 433 | } |
| 469 | this.PreprocessForeach(reader, currentContainer, offset); | 434 | //else |
| 470 | break; | 435 | //{ |
| 471 | 436 | // display an error? Can this happen? | |
| 472 | case "endforeach": // endforeach is handled in PreprocessForeach, so seeing it here is an error | 437 | //} |
| 473 | throw new WixException(ErrorMessages.UnmatchedPreprocessorInstruction(sourceLineNumbers, "foreach", "endforeach")); | 438 | break; |
| 474 | |||
| 475 | case "pragma": | ||
| 476 | this.PreprocessPragma(reader.Value, currentContainer); | ||
| 477 | break; | ||
| 478 | 439 | ||
| 479 | default: | 440 | case XmlNodeType.ProcessingInstruction: |
| 480 | // unknown processing instructions are currently ignored | 441 | switch (reader.LocalName) |
| 481 | break; | 442 | { |
| 482 | } | 443 | case "define": |
| 444 | this.PreprocessDefine(reader.Value); | ||
| 483 | break; | 445 | break; |
| 484 | 446 | ||
| 485 | case XmlNodeType.Element: | 447 | case "error": |
| 486 | if (0 < this.IncludeNextStack.Count && this.IncludeNextStack.Peek()) | 448 | this.PreprocessError(reader.Value); |
| 487 | { | 449 | break; |
| 488 | if ("Include" != reader.LocalName) | ||
| 489 | { | ||
| 490 | this.Messaging.Write(ErrorMessages.InvalidDocumentElement(sourceLineNumbers, reader.Name, "include", "Include")); | ||
| 491 | } | ||
| 492 | 450 | ||
| 493 | this.IncludeNextStack.Pop(); | 451 | case "warning": |
| 494 | this.IncludeNextStack.Push(false); | 452 | this.PreprocessWarning(reader.Value); |
| 495 | break; | 453 | break; |
| 496 | } | ||
| 497 | 454 | ||
| 498 | var empty = reader.IsEmptyElement; | 455 | case "undef": |
| 499 | var ns = XNamespace.Get(reader.NamespaceURI); | 456 | this.PreprocessUndef(reader.Value); |
| 500 | var element = new XElement(ns + reader.LocalName); | 457 | break; |
| 501 | currentContainer.Add(element); | ||
| 502 | 458 | ||
| 459 | case "include": | ||
| 503 | this.UpdateCurrentLineNumber(reader, offset); | 460 | this.UpdateCurrentLineNumber(reader, offset); |
| 504 | element.AddAnnotation(sourceLineNumbers); | 461 | this.PreprocessInclude(reader.Value, currentContainer); |
| 462 | break; | ||
| 505 | 463 | ||
| 506 | while (reader.MoveToNextAttribute()) | 464 | case "foreach": |
| 507 | { | 465 | this.PreprocessForeach(reader, currentContainer, offset); |
| 508 | var value = this.Helper.PreprocessString(this.Context, reader.Value); | 466 | break; |
| 509 | 467 | ||
| 510 | var attribNamespace = XNamespace.Get(reader.NamespaceURI); | 468 | case "endforeach": // endforeach is handled in PreprocessForeach, so seeing it here is an error |
| 511 | attribNamespace = XNamespace.Xmlns == attribNamespace && reader.LocalName.Equals("xmlns") ? XNamespace.None : attribNamespace; | 469 | throw new WixException(ErrorMessages.UnmatchedPreprocessorInstruction(sourceLineNumbers, "foreach", "endforeach")); |
| 512 | 470 | ||
| 513 | element.Add(new XAttribute(attribNamespace + reader.LocalName, value)); | 471 | case "pragma": |
| 514 | } | 472 | this.PreprocessPragma(reader.Value, currentContainer); |
| 473 | break; | ||
| 515 | 474 | ||
| 516 | if (!empty) | 475 | default: |
| 517 | { | 476 | // unknown processing instructions are currently ignored |
| 518 | containerStack.Push(currentContainer); | ||
| 519 | currentContainer = element; | ||
| 520 | } | ||
| 521 | break; | 477 | break; |
| 478 | } | ||
| 479 | break; | ||
| 522 | 480 | ||
| 523 | case XmlNodeType.EndElement: | 481 | case XmlNodeType.Element: |
| 524 | if (0 < reader.Depth || !include) | 482 | if (0 < this.IncludeNextStack.Count && this.IncludeNextStack.Peek()) |
| 483 | { | ||
| 484 | if ("Include" != reader.LocalName) | ||
| 525 | { | 485 | { |
| 526 | currentContainer = containerStack.Pop(); | 486 | this.Messaging.Write(ErrorMessages.InvalidDocumentElement(sourceLineNumbers, reader.Name, "include", "Include")); |
| 527 | } | 487 | } |
| 528 | break; | ||
| 529 | 488 | ||
| 530 | case XmlNodeType.Text: | 489 | this.IncludeNextStack.Pop(); |
| 531 | string postprocessedText = this.Helper.PreprocessString(this.Context, reader.Value); | 490 | this.IncludeNextStack.Push(false); |
| 532 | currentContainer.Add(postprocessedText); | ||
| 533 | break; | 491 | break; |
| 492 | } | ||
| 534 | 493 | ||
| 535 | case XmlNodeType.CDATA: | 494 | var empty = reader.IsEmptyElement; |
| 536 | string postprocessedValue = this.Helper.PreprocessString(this.Context, reader.Value); | 495 | var ns = XNamespace.Get(reader.NamespaceURI); |
| 537 | currentContainer.Add(new XCData(postprocessedValue)); | 496 | var element = new XElement(ns + reader.LocalName); |
| 538 | break; | 497 | currentContainer.Add(element); |
| 539 | 498 | ||
| 540 | default: | 499 | this.UpdateCurrentLineNumber(reader, offset); |
| 541 | break; | 500 | element.AddAnnotation(sourceLineNumbers); |
| 501 | |||
| 502 | while (reader.MoveToNextAttribute()) | ||
| 503 | { | ||
| 504 | var value = this.Helper.PreprocessString(this.Context, reader.Value); | ||
| 505 | |||
| 506 | var attribNamespace = XNamespace.Get(reader.NamespaceURI); | ||
| 507 | attribNamespace = XNamespace.Xmlns == attribNamespace && reader.LocalName.Equals("xmlns") ? XNamespace.None : attribNamespace; | ||
| 508 | |||
| 509 | element.Add(new XAttribute(attribNamespace + reader.LocalName, value)); | ||
| 510 | } | ||
| 511 | |||
| 512 | if (!empty) | ||
| 513 | { | ||
| 514 | containerStack.Push(currentContainer); | ||
| 515 | currentContainer = element; | ||
| 516 | } | ||
| 517 | break; | ||
| 518 | |||
| 519 | case XmlNodeType.EndElement: | ||
| 520 | if (0 < reader.Depth || !include) | ||
| 521 | { | ||
| 522 | currentContainer = containerStack.Pop(); | ||
| 523 | } | ||
| 524 | break; | ||
| 525 | |||
| 526 | case XmlNodeType.Text: | ||
| 527 | var postprocessedText = this.Helper.PreprocessString(this.Context, reader.Value); | ||
| 528 | currentContainer.Add(postprocessedText); | ||
| 529 | break; | ||
| 530 | |||
| 531 | case XmlNodeType.CDATA: | ||
| 532 | var postprocessedValue = this.Helper.PreprocessString(this.Context, reader.Value); | ||
| 533 | currentContainer.Add(new XCData(postprocessedValue)); | ||
| 534 | break; | ||
| 535 | |||
| 536 | default: | ||
| 537 | break; | ||
| 542 | } | 538 | } |
| 543 | } | 539 | } |
| 544 | 540 | ||
| @@ -652,7 +648,7 @@ namespace WixToolset.Core | |||
| 652 | throw new WixException(ErrorMessages.FileNotFound(sourceLineNumbers, includePath, "include")); | 648 | throw new WixException(ErrorMessages.FileNotFound(sourceLineNumbers, includePath, "include")); |
| 653 | } | 649 | } |
| 654 | 650 | ||
| 655 | using (XmlReader reader = XmlReader.Create(includeFile, DocumentXmlReaderSettings)) | 651 | using (var reader = XmlReader.Create(includeFile, DocumentXmlReaderSettings)) |
| 656 | { | 652 | { |
| 657 | this.PushInclude(includeFile); | 653 | this.PushInclude(includeFile); |
| 658 | 654 | ||
| @@ -689,13 +685,13 @@ namespace WixToolset.Core | |||
| 689 | } | 685 | } |
| 690 | 686 | ||
| 691 | // parse out the variable name | 687 | // parse out the variable name |
| 692 | string varName = reader.Value.Substring(0, indexOfInToken).Trim(); | 688 | var varName = reader.Value.Substring(0, indexOfInToken).Trim(); |
| 693 | string varValuesString = reader.Value.Substring(indexOfInToken + 4).Trim(); | 689 | var varValuesString = reader.Value.Substring(indexOfInToken + 4).Trim(); |
| 694 | 690 | ||
| 695 | // preprocess the variable values string because it might be a variable itself | 691 | // preprocess the variable values string because it might be a variable itself |
| 696 | varValuesString = this.Helper.PreprocessString(this.Context, varValuesString); | 692 | varValuesString = this.Helper.PreprocessString(this.Context, varValuesString); |
| 697 | 693 | ||
| 698 | string[] varValues = varValuesString.Split(';'); | 694 | var varValues = varValuesString.Split(';'); |
| 699 | 695 | ||
| 700 | // go through all the empty strings | 696 | // go through all the empty strings |
| 701 | while (reader.Read() && XmlNodeType.Whitespace == reader.NodeType) | 697 | while (reader.Read() && XmlNodeType.Whitespace == reader.NodeType) |
| @@ -703,44 +699,44 @@ namespace WixToolset.Core | |||
| 703 | } | 699 | } |
| 704 | 700 | ||
| 705 | // get the offset of this xml fragment (for some reason its always off by 1) | 701 | // get the offset of this xml fragment (for some reason its always off by 1) |
| 706 | IXmlLineInfo lineInfoReader = reader as IXmlLineInfo; | 702 | var lineInfoReader = reader as IXmlLineInfo; |
| 707 | if (null != lineInfoReader) | 703 | if (null != lineInfoReader) |
| 708 | { | 704 | { |
| 709 | offset += lineInfoReader.LineNumber - 1; | 705 | offset += lineInfoReader.LineNumber - 1; |
| 710 | } | 706 | } |
| 711 | 707 | ||
| 712 | XmlTextReader textReader = reader as XmlTextReader; | 708 | var textReader = reader as XmlTextReader; |
| 713 | // dump the xml to a string (maintaining whitespace if possible) | 709 | // dump the xml to a string (maintaining whitespace if possible) |
| 714 | if (null != textReader) | 710 | if (null != textReader) |
| 715 | { | 711 | { |
| 716 | textReader.WhitespaceHandling = WhitespaceHandling.All; | 712 | textReader.WhitespaceHandling = WhitespaceHandling.All; |
| 717 | } | 713 | } |
| 718 | 714 | ||
| 719 | StringBuilder fragmentBuilder = new StringBuilder(); | 715 | var fragmentBuilder = new StringBuilder(); |
| 720 | int nestedForeachCount = 1; | 716 | var nestedForeachCount = 1; |
| 721 | while (nestedForeachCount != 0) | 717 | while (nestedForeachCount != 0) |
| 722 | { | 718 | { |
| 723 | if (reader.NodeType == XmlNodeType.ProcessingInstruction) | 719 | if (reader.NodeType == XmlNodeType.ProcessingInstruction) |
| 724 | { | 720 | { |
| 725 | switch (reader.LocalName) | 721 | switch (reader.LocalName) |
| 726 | { | 722 | { |
| 727 | case "foreach": | 723 | case "foreach": |
| 728 | ++nestedForeachCount; | 724 | ++nestedForeachCount; |
| 729 | // Output the foreach statement | 725 | // Output the foreach statement |
| 730 | fragmentBuilder.AppendFormat("<?foreach {0}?>", reader.Value); | 726 | fragmentBuilder.AppendFormat("<?foreach {0}?>", reader.Value); |
| 731 | break; | 727 | break; |
| 732 | 728 | ||
| 733 | case "endforeach": | 729 | case "endforeach": |
| 734 | --nestedForeachCount; | 730 | --nestedForeachCount; |
| 735 | if (0 != nestedForeachCount) | 731 | if (0 != nestedForeachCount) |
| 736 | { | 732 | { |
| 737 | fragmentBuilder.Append("<?endforeach ?>"); | 733 | fragmentBuilder.Append("<?endforeach ?>"); |
| 738 | } | 734 | } |
| 739 | break; | 735 | break; |
| 740 | 736 | ||
| 741 | default: | 737 | default: |
| 742 | fragmentBuilder.AppendFormat("<?{0} {1}?>", reader.LocalName, reader.Value); | 738 | fragmentBuilder.AppendFormat("<?{0} {1}?>", reader.LocalName, reader.Value); |
| 743 | break; | 739 | break; |
| 744 | } | 740 | } |
| 745 | } | 741 | } |
| 746 | else if (reader.NodeType == XmlNodeType.Element) | 742 | else if (reader.NodeType == XmlNodeType.Element) |
| @@ -764,7 +760,7 @@ namespace WixToolset.Core | |||
| 764 | using (var fragmentStream = new MemoryStream(Encoding.UTF8.GetBytes(fragmentBuilder.ToString()))) | 760 | using (var fragmentStream = new MemoryStream(Encoding.UTF8.GetBytes(fragmentBuilder.ToString()))) |
| 765 | { | 761 | { |
| 766 | // process each iteration, updating the variable's value each time | 762 | // process each iteration, updating the variable's value each time |
| 767 | foreach (string varValue in varValues) | 763 | foreach (var varValue in varValues) |
| 768 | { | 764 | { |
| 769 | using (var loopReader = XmlReader.Create(fragmentStream, FragmentXmlReaderSettings)) | 765 | using (var loopReader = XmlReader.Create(fragmentStream, FragmentXmlReaderSettings)) |
| 770 | { | 766 | { |
| @@ -801,7 +797,7 @@ namespace WixToolset.Core | |||
| 801 | } | 797 | } |
| 802 | 798 | ||
| 803 | // resolve other variables in the pragma argument(s) | 799 | // resolve other variables in the pragma argument(s) |
| 804 | string pragmaArgs = this.Helper.PreprocessString(this.Context, match.Groups["pragmaValue"].Value).Trim(); | 800 | var pragmaArgs = this.Helper.PreprocessString(this.Context, match.Groups["pragmaValue"].Value).Trim(); |
| 805 | 801 | ||
| 806 | try | 802 | try |
| 807 | { | 803 | { |
| @@ -823,7 +819,7 @@ namespace WixToolset.Core | |||
| 823 | private string GetNextToken(string originalExpression, ref string expression, out bool stringLiteral) | 819 | private string GetNextToken(string originalExpression, ref string expression, out bool stringLiteral) |
| 824 | { | 820 | { |
| 825 | stringLiteral = false; | 821 | stringLiteral = false; |
| 826 | string token = String.Empty; | 822 | var token = String.Empty; |
| 827 | expression = expression.Trim(); | 823 | expression = expression.Trim(); |
| 828 | if (0 == expression.Length) | 824 | if (0 == expression.Length) |
| 829 | { | 825 | { |
| @@ -833,7 +829,7 @@ namespace WixToolset.Core | |||
| 833 | if (expression.StartsWith("\"", StringComparison.Ordinal)) | 829 | if (expression.StartsWith("\"", StringComparison.Ordinal)) |
| 834 | { | 830 | { |
| 835 | stringLiteral = true; | 831 | stringLiteral = true; |
| 836 | int endingQuotes = expression.IndexOf('\"', 1); | 832 | var endingQuotes = expression.IndexOf('\"', 1); |
| 837 | if (-1 == endingQuotes) | 833 | if (-1 == endingQuotes) |
| 838 | { | 834 | { |
| 839 | throw new WixException(ErrorMessages.UnmatchedQuotesInExpression(this.Context.CurrentSourceLineNumber, originalExpression)); | 835 | throw new WixException(ErrorMessages.UnmatchedQuotesInExpression(this.Context.CurrentSourceLineNumber, originalExpression)); |
| @@ -848,9 +844,9 @@ namespace WixToolset.Core | |||
| 848 | else if (expression.StartsWith("$(", StringComparison.Ordinal)) | 844 | else if (expression.StartsWith("$(", StringComparison.Ordinal)) |
| 849 | { | 845 | { |
| 850 | // Find the ending paren of the expression | 846 | // Find the ending paren of the expression |
| 851 | int endingParen = -1; | 847 | var endingParen = -1; |
| 852 | int openedCount = 1; | 848 | var openedCount = 1; |
| 853 | for (int i = 2; i < expression.Length; i++) | 849 | for (var i = 2; i < expression.Length; i++) |
| 854 | { | 850 | { |
| 855 | if ('(' == expression[i]) | 851 | if ('(' == expression[i]) |
| 856 | { | 852 | { |
| @@ -881,14 +877,14 @@ namespace WixToolset.Core | |||
| 881 | { | 877 | { |
| 882 | // Cut the token off at the next equal, space, inequality operator, | 878 | // Cut the token off at the next equal, space, inequality operator, |
| 883 | // or end of string, whichever comes first | 879 | // or end of string, whichever comes first |
| 884 | int space = expression.IndexOf(" ", StringComparison.Ordinal); | 880 | var space = expression.IndexOf(" ", StringComparison.Ordinal); |
| 885 | int equals = expression.IndexOf("=", StringComparison.Ordinal); | 881 | var equals = expression.IndexOf("=", StringComparison.Ordinal); |
| 886 | int lessThan = expression.IndexOf("<", StringComparison.Ordinal); | 882 | var lessThan = expression.IndexOf("<", StringComparison.Ordinal); |
| 887 | int lessThanEquals = expression.IndexOf("<=", StringComparison.Ordinal); | 883 | var lessThanEquals = expression.IndexOf("<=", StringComparison.Ordinal); |
| 888 | int greaterThan = expression.IndexOf(">", StringComparison.Ordinal); | 884 | var greaterThan = expression.IndexOf(">", StringComparison.Ordinal); |
| 889 | int greaterThanEquals = expression.IndexOf(">=", StringComparison.Ordinal); | 885 | var greaterThanEquals = expression.IndexOf(">=", StringComparison.Ordinal); |
| 890 | int notEquals = expression.IndexOf("!=", StringComparison.Ordinal); | 886 | var notEquals = expression.IndexOf("!=", StringComparison.Ordinal); |
| 891 | int equalsNoCase = expression.IndexOf("~=", StringComparison.Ordinal); | 887 | var equalsNoCase = expression.IndexOf("~=", StringComparison.Ordinal); |
| 892 | int closingIndex; | 888 | int closingIndex; |
| 893 | 889 | ||
| 894 | if (space == -1) | 890 | if (space == -1) |
| @@ -970,7 +966,7 @@ namespace WixToolset.Core | |||
| 970 | { | 966 | { |
| 971 | // By default it's a literal and will only be evaluated if it | 967 | // By default it's a literal and will only be evaluated if it |
| 972 | // matches the variable format | 968 | // matches the variable format |
| 973 | string varValue = variable; | 969 | var varValue = variable; |
| 974 | 970 | ||
| 975 | if (variable.StartsWith("$(", StringComparison.Ordinal)) | 971 | if (variable.StartsWith("$(", StringComparison.Ordinal)) |
| 976 | { | 972 | { |
| @@ -1008,8 +1004,7 @@ namespace WixToolset.Core | |||
| 1008 | /// <param name="rightValue">Right side value from expression.</param> | 1004 | /// <param name="rightValue">Right side value from expression.</param> |
| 1009 | private void GetNameValuePair(string originalExpression, ref string expression, out string leftValue, out string operation, out string rightValue) | 1005 | private void GetNameValuePair(string originalExpression, ref string expression, out string leftValue, out string operation, out string rightValue) |
| 1010 | { | 1006 | { |
| 1011 | bool stringLiteral; | 1007 | leftValue = this.GetNextToken(originalExpression, ref expression, out var stringLiteral); |
| 1012 | leftValue = this.GetNextToken(originalExpression, ref expression, out stringLiteral); | ||
| 1013 | 1008 | ||
| 1014 | // If it wasn't a string literal, evaluate it | 1009 | // If it wasn't a string literal, evaluate it |
| 1015 | if (!stringLiteral) | 1010 | if (!stringLiteral) |
| @@ -1060,14 +1055,10 @@ namespace WixToolset.Core | |||
| 1060 | private bool EvaluateAtomicExpression(string originalExpression, ref string expression) | 1055 | private bool EvaluateAtomicExpression(string originalExpression, ref string expression) |
| 1061 | { | 1056 | { |
| 1062 | // Quick test to see if the first token is a variable | 1057 | // Quick test to see if the first token is a variable |
| 1063 | bool startsWithVariable = expression.StartsWith("$(", StringComparison.Ordinal); | 1058 | var startsWithVariable = expression.StartsWith("$(", StringComparison.Ordinal); |
| 1064 | 1059 | this.GetNameValuePair(originalExpression, ref expression, out var leftValue, out var operation, out var rightValue); | |
| 1065 | string leftValue; | ||
| 1066 | string rightValue; | ||
| 1067 | string operation; | ||
| 1068 | this.GetNameValuePair(originalExpression, ref expression, out leftValue, out operation, out rightValue); | ||
| 1069 | 1060 | ||
| 1070 | bool expressionValue = false; | 1061 | var expressionValue = false; |
| 1071 | 1062 | ||
| 1072 | // If the variables don't exist, they were evaluated to null | 1063 | // If the variables don't exist, they were evaluated to null |
| 1073 | if (null == leftValue || null == rightValue) | 1064 | if (null == leftValue || null == rightValue) |
| @@ -1168,8 +1159,8 @@ namespace WixToolset.Core | |||
| 1168 | } | 1159 | } |
| 1169 | 1160 | ||
| 1170 | // search for the end of the expression with the matching paren | 1161 | // search for the end of the expression with the matching paren |
| 1171 | int openParenIndex = 0; | 1162 | var openParenIndex = 0; |
| 1172 | int closeParenIndex = 1; | 1163 | var closeParenIndex = 1; |
| 1173 | while (openParenIndex != -1 && openParenIndex < closeParenIndex) | 1164 | while (openParenIndex != -1 && openParenIndex < closeParenIndex) |
| 1174 | { | 1165 | { |
| 1175 | closeParenIndex = expression.IndexOf(')', closeParenIndex); | 1166 | closeParenIndex = expression.IndexOf(')', closeParenIndex); |
| @@ -1214,17 +1205,17 @@ namespace WixToolset.Core | |||
| 1214 | { | 1205 | { |
| 1215 | switch (operation) | 1206 | switch (operation) |
| 1216 | { | 1207 | { |
| 1217 | case PreprocessorOperation.And: | 1208 | case PreprocessorOperation.And: |
| 1218 | currentValue = currentValue && prevResult; | 1209 | currentValue = currentValue && prevResult; |
| 1219 | break; | 1210 | break; |
| 1220 | case PreprocessorOperation.Or: | 1211 | case PreprocessorOperation.Or: |
| 1221 | currentValue = currentValue || prevResult; | 1212 | currentValue = currentValue || prevResult; |
| 1222 | break; | 1213 | break; |
| 1223 | case PreprocessorOperation.Not: | 1214 | case PreprocessorOperation.Not: |
| 1224 | currentValue = !currentValue; | 1215 | currentValue = !currentValue; |
| 1225 | break; | 1216 | break; |
| 1226 | default: | 1217 | default: |
| 1227 | throw new WixException(ErrorMessages.UnexpectedPreprocessorOperator(this.Context.CurrentSourceLineNumber, operation.ToString())); | 1218 | throw new WixException(ErrorMessages.UnexpectedPreprocessorOperator(this.Context.CurrentSourceLineNumber, operation.ToString())); |
| 1228 | } | 1219 | } |
| 1229 | } | 1220 | } |
| 1230 | 1221 | ||
| @@ -1235,7 +1226,7 @@ namespace WixToolset.Core | |||
| 1235 | /// <returns>Boolean result of expression.</returns> | 1226 | /// <returns>Boolean result of expression.</returns> |
| 1236 | private bool EvaluateExpression(string expression) | 1227 | private bool EvaluateExpression(string expression) |
| 1237 | { | 1228 | { |
| 1238 | string tmpExpression = expression; | 1229 | var tmpExpression = expression; |
| 1239 | return this.EvaluateExpressionRecurse(expression, ref tmpExpression, PreprocessorOperation.And, true); | 1230 | return this.EvaluateExpressionRecurse(expression, ref tmpExpression, PreprocessorOperation.And, true); |
| 1240 | } | 1231 | } |
| 1241 | 1232 | ||
| @@ -1269,7 +1260,7 @@ namespace WixToolset.Core | |||
| 1269 | /// <returns>Boolean to indicate if the expression is true or false</returns> | 1260 | /// <returns>Boolean to indicate if the expression is true or false</returns> |
| 1270 | private bool EvaluateExpressionRecurse(string originalExpression, ref string expression, PreprocessorOperation prevResultOperation, bool prevResult) | 1261 | private bool EvaluateExpressionRecurse(string originalExpression, ref string expression, PreprocessorOperation prevResultOperation, bool prevResult) |
| 1271 | { | 1262 | { |
| 1272 | bool expressionValue = false; | 1263 | var expressionValue = false; |
| 1273 | expression = expression.Trim(); | 1264 | expression = expression.Trim(); |
| 1274 | if (expression.Length == 0) | 1265 | if (expression.Length == 0) |
| 1275 | { | 1266 | { |
| @@ -1279,8 +1270,7 @@ namespace WixToolset.Core | |||
| 1279 | // If the expression starts with parenthesis, evaluate it | 1270 | // If the expression starts with parenthesis, evaluate it |
| 1280 | if (expression.IndexOf('(') == 0) | 1271 | if (expression.IndexOf('(') == 0) |
| 1281 | { | 1272 | { |
| 1282 | int endSubExpressionIndex; | 1273 | var subExpression = this.GetParenthesisExpression(originalExpression, expression, out var endSubExpressionIndex); |
| 1283 | string subExpression = this.GetParenthesisExpression(originalExpression, expression, out endSubExpressionIndex); | ||
| 1284 | expressionValue = this.EvaluateExpressionRecurse(originalExpression, ref subExpression, PreprocessorOperation.And, true); | 1274 | expressionValue = this.EvaluateExpressionRecurse(originalExpression, ref subExpression, PreprocessorOperation.And, true); |
| 1285 | 1275 | ||
| 1286 | // Now get the rest of the expression that hasn't been evaluated | 1276 | // Now get the rest of the expression that hasn't been evaluated |
| @@ -1337,10 +1327,10 @@ namespace WixToolset.Core | |||
| 1337 | /// <param name="offset">This is the artificial offset of the line numbers from the reader. Used for the foreach processing.</param> | 1327 | /// <param name="offset">This is the artificial offset of the line numbers from the reader. Used for the foreach processing.</param> |
| 1338 | private void UpdateCurrentLineNumber(XmlReader reader, int offset) | 1328 | private void UpdateCurrentLineNumber(XmlReader reader, int offset) |
| 1339 | { | 1329 | { |
| 1340 | IXmlLineInfo lineInfoReader = reader as IXmlLineInfo; | 1330 | var lineInfoReader = reader as IXmlLineInfo; |
| 1341 | if (null != lineInfoReader) | 1331 | if (null != lineInfoReader) |
| 1342 | { | 1332 | { |
| 1343 | int newLine = lineInfoReader.LineNumber + offset; | 1333 | var newLine = lineInfoReader.LineNumber + offset; |
| 1344 | 1334 | ||
| 1345 | if (this.Context.CurrentSourceLineNumber.LineNumber != newLine) | 1335 | if (this.Context.CurrentSourceLineNumber.LineNumber != newLine) |
| 1346 | { | 1336 | { |
| @@ -1435,19 +1425,6 @@ namespace WixToolset.Core | |||
| 1435 | return finalIncludePath; | 1425 | return finalIncludePath; |
| 1436 | } | 1426 | } |
| 1437 | 1427 | ||
| 1438 | private IPreprocessContext CreateContext() | ||
| 1439 | { | ||
| 1440 | var context = this.ServiceProvider.GetService<IPreprocessContext>(); | ||
| 1441 | context.Extensions = this.ServiceProvider.GetService<IExtensionManager>().Create<IPreprocessorExtension>(); | ||
| 1442 | context.CurrentSourceLineNumber = new SourceLineNumber(this.SourcePath); | ||
| 1443 | context.Platform = this.Platform; | ||
| 1444 | context.IncludeSearchPaths = this.IncludeSearchPaths?.ToList() ?? new List<string>(); | ||
| 1445 | context.SourceFile = this.SourcePath; | ||
| 1446 | context.Variables = new Dictionary<string, string>(this.Variables); | ||
| 1447 | |||
| 1448 | return context; | ||
| 1449 | } | ||
| 1450 | |||
| 1451 | private void PreProcess() | 1428 | private void PreProcess() |
| 1452 | { | 1429 | { |
| 1453 | foreach (var extension in this.Context.Extensions) | 1430 | foreach (var extension in this.Context.Extensions) |
diff --git a/src/WixToolset.Core/Resolver.cs b/src/WixToolset.Core/Resolver.cs index 12cb375b..98101f16 100644 --- a/src/WixToolset.Core/Resolver.cs +++ b/src/WixToolset.Core/Resolver.cs | |||
| @@ -15,7 +15,7 @@ namespace WixToolset.Core | |||
| 15 | /// <summary> | 15 | /// <summary> |
| 16 | /// Resolver for the WiX toolset. | 16 | /// Resolver for the WiX toolset. |
| 17 | /// </summary> | 17 | /// </summary> |
| 18 | internal class Resolver | 18 | internal class Resolver : IResolver |
| 19 | { | 19 | { |
| 20 | internal Resolver(IServiceProvider serviceProvider) | 20 | internal Resolver(IServiceProvider serviceProvider) |
| 21 | { | 21 | { |
| @@ -38,21 +38,10 @@ namespace WixToolset.Core | |||
| 38 | 38 | ||
| 39 | public IEnumerable<string> FilterCultures { get; set; } | 39 | public IEnumerable<string> FilterCultures { get; set; } |
| 40 | 40 | ||
| 41 | public ResolveResult Execute() | 41 | public ResolveResult Resolve(IResolveContext context) |
| 42 | { | 42 | { |
| 43 | var extensionManager = this.ServiceProvider.GetService<IExtensionManager>(); | 43 | |
| 44 | 44 | foreach (var extension in context.Extensions) | |
| 45 | var context = this.ServiceProvider.GetService<IResolveContext>(); | ||
| 46 | context.BindPaths = this.BindPaths; | ||
| 47 | context.Extensions = extensionManager.Create<IResolverExtension>(); | ||
| 48 | context.ExtensionData = extensionManager.Create<IExtensionData>(); | ||
| 49 | context.FilterCultures = this.FilterCultures; | ||
| 50 | context.IntermediateFolder = this.IntermediateFolder; | ||
| 51 | context.IntermediateRepresentation = this.IntermediateRepresentation; | ||
| 52 | context.Localizations = this.Localizations; | ||
| 53 | context.VariableResolver = new WixVariableResolver(this.Messaging); | ||
| 54 | |||
| 55 | foreach (IResolverExtension extension in context.Extensions) | ||
| 56 | { | 45 | { |
| 57 | extension.PreResolve(context); | 46 | extension.PreResolve(context); |
| 58 | } | 47 | } |
| @@ -64,11 +53,11 @@ namespace WixToolset.Core | |||
| 64 | 53 | ||
| 65 | this.LocalizeUI(context); | 54 | this.LocalizeUI(context); |
| 66 | 55 | ||
| 67 | resolveResult = this.Resolve(context); | 56 | resolveResult = this.DoResolve(context); |
| 68 | } | 57 | } |
| 69 | finally | 58 | finally |
| 70 | { | 59 | { |
| 71 | foreach (IResolverExtension extension in context.Extensions) | 60 | foreach (var extension in context.Extensions) |
| 72 | { | 61 | { |
| 73 | extension.PostResolve(resolveResult); | 62 | extension.PostResolve(resolveResult); |
| 74 | } | 63 | } |
| @@ -77,7 +66,7 @@ namespace WixToolset.Core | |||
| 77 | return resolveResult; | 66 | return resolveResult; |
| 78 | } | 67 | } |
| 79 | 68 | ||
| 80 | private ResolveResult Resolve(IResolveContext context) | 69 | private ResolveResult DoResolve(IResolveContext context) |
| 81 | { | 70 | { |
| 82 | var buildingPatch = context.IntermediateRepresentation.Sections.Any(s => s.Type == SectionType.Patch); | 71 | var buildingPatch = context.IntermediateRepresentation.Sections.Any(s => s.Type == SectionType.Patch); |
| 83 | 72 | ||
diff --git a/src/WixToolset.Core/WixToolsetServiceProvider.cs b/src/WixToolset.Core/WixToolsetServiceProvider.cs index f4a9f78d..83b9356d 100644 --- a/src/WixToolset.Core/WixToolsetServiceProvider.cs +++ b/src/WixToolset.Core/WixToolsetServiceProvider.cs | |||
| @@ -32,12 +32,23 @@ namespace WixToolset.Core | |||
| 32 | this.AddService<ICommandLineParser>((provider, singletons) => new CommandLineParser(provider)); | 32 | this.AddService<ICommandLineParser>((provider, singletons) => new CommandLineParser(provider)); |
| 33 | this.AddService<IPreprocessContext>((provider, singletons) => new PreprocessContext(provider)); | 33 | this.AddService<IPreprocessContext>((provider, singletons) => new PreprocessContext(provider)); |
| 34 | this.AddService<ICompileContext>((provider, singletons) => new CompileContext(provider)); | 34 | this.AddService<ICompileContext>((provider, singletons) => new CompileContext(provider)); |
| 35 | this.AddService<ILibraryContext>((provider, singletons) => new LibraryContext(provider)); | ||
| 35 | this.AddService<ILinkContext>((provider, singletons) => new LinkContext(provider)); | 36 | this.AddService<ILinkContext>((provider, singletons) => new LinkContext(provider)); |
| 36 | this.AddService<IResolveContext>((provider, singletons) => new ResolveContext(provider)); | 37 | this.AddService<IResolveContext>((provider, singletons) => new ResolveContext(provider)); |
| 37 | this.AddService<IBindContext>((provider, singletons) => new BindContext(provider)); | 38 | this.AddService<IBindContext>((provider, singletons) => new BindContext(provider)); |
| 39 | this.AddService<IDecompileContext>((provider, singletons) => new DecompileContext(provider)); | ||
| 38 | this.AddService<ILayoutContext>((provider, singletons) => new LayoutContext(provider)); | 40 | this.AddService<ILayoutContext>((provider, singletons) => new LayoutContext(provider)); |
| 39 | this.AddService<IInscribeContext>((provider, singletons) => new InscribeContext(provider)); | 41 | this.AddService<IInscribeContext>((provider, singletons) => new InscribeContext(provider)); |
| 40 | 42 | ||
| 43 | this.AddService<IBinder>((provider, singletons) => new Binder(provider)); | ||
| 44 | this.AddService<ICompiler>((provider, singletons) => new Compiler(provider)); | ||
| 45 | this.AddService<IDecompiler>((provider, singletons) => new Decompiler(provider)); | ||
| 46 | this.AddService<ILayoutCreator>((provider, singletons) => new LayoutCreator(provider)); | ||
| 47 | this.AddService<IPreprocessor>((provider, singletons) => new Preprocessor(provider)); | ||
| 48 | this.AddService<ILibrarian>((provider, singletons) => new Librarian(provider)); | ||
| 49 | this.AddService<ILinker>((provider, singletons) => new Linker(provider)); | ||
| 50 | this.AddService<IResolver>((provider, singletons) => new Resolver(provider)); | ||
| 51 | |||
| 41 | // Internal implementations. | 52 | // Internal implementations. |
| 42 | this.AddService<ILocalizer>((provider, singletons) => new Localizer(provider)); | 53 | this.AddService<ILocalizer>((provider, singletons) => new Localizer(provider)); |
| 43 | } | 54 | } |
