diff options
Diffstat (limited to '')
-rw-r--r-- | src/WixToolset.Core/Preprocessor.cs | 136 |
1 files changed, 91 insertions, 45 deletions
diff --git a/src/WixToolset.Core/Preprocessor.cs b/src/WixToolset.Core/Preprocessor.cs index 53d60c87..6733f493 100644 --- a/src/WixToolset.Core/Preprocessor.cs +++ b/src/WixToolset.Core/Preprocessor.cs | |||
@@ -14,6 +14,7 @@ namespace WixToolset.Core | |||
14 | using WixToolset.Extensibility; | 14 | using WixToolset.Extensibility; |
15 | using WixToolset.Core.Preprocess; | 15 | using WixToolset.Core.Preprocess; |
16 | using WixToolset.Extensibility.Services; | 16 | using WixToolset.Extensibility.Services; |
17 | using System.Linq; | ||
17 | 18 | ||
18 | /// <summary> | 19 | /// <summary> |
19 | /// Preprocessor object | 20 | /// Preprocessor object |
@@ -35,6 +36,21 @@ namespace WixToolset.Core | |||
35 | XmlResolver = null, | 36 | XmlResolver = null, |
36 | }; | 37 | }; |
37 | 38 | ||
39 | public Preprocessor(IServiceProvider serviceProvider) | ||
40 | { | ||
41 | this.ServiceProvider = serviceProvider; | ||
42 | } | ||
43 | |||
44 | public IEnumerable<string> IncludeSearchPaths { get; set; } | ||
45 | |||
46 | public Platform Platform { get; set; } | ||
47 | |||
48 | public string SourcePath { get; set; } | ||
49 | |||
50 | public IDictionary<string, string> Variables { get; set; } | ||
51 | |||
52 | private IServiceProvider ServiceProvider { get; } | ||
53 | |||
38 | private IPreprocessContext Context { get; set; } | 54 | private IPreprocessContext Context { get; set; } |
39 | 55 | ||
40 | private Stack<string> CurrentFileStack { get; } = new Stack<string>(); | 56 | private Stack<string> CurrentFileStack { get; } = new Stack<string>(); |
@@ -87,14 +103,19 @@ namespace WixToolset.Core | |||
87 | /// </summary> | 103 | /// </summary> |
88 | /// <param name="context">The preprocessing context.</param> | 104 | /// <param name="context">The preprocessing context.</param> |
89 | /// <returns>XDocument with the postprocessed data.</returns> | 105 | /// <returns>XDocument with the postprocessed data.</returns> |
90 | public XDocument Process(IPreprocessContext context) | 106 | public XDocument Execute() |
91 | { | 107 | { |
92 | this.Context = context ?? throw new ArgumentNullException(nameof(context)); | 108 | this.Context = this.CreateContext(); |
109 | |||
110 | this.PreProcess(); | ||
93 | 111 | ||
94 | using (XmlReader reader = XmlReader.Create(context.SourceFile, DocumentXmlReaderSettings)) | 112 | XDocument document; |
113 | using (XmlReader reader = XmlReader.Create(this.Context.SourceFile, DocumentXmlReaderSettings)) | ||
95 | { | 114 | { |
96 | return Process(context, reader); | 115 | document = this.Process(reader); |
97 | } | 116 | } |
117 | |||
118 | return PostProcess(document); | ||
98 | } | 119 | } |
99 | 120 | ||
100 | /// <summary> | 121 | /// <summary> |
@@ -103,46 +124,32 @@ namespace WixToolset.Core | |||
103 | /// <param name="context">The preprocessing context.</param> | 124 | /// <param name="context">The preprocessing context.</param> |
104 | /// <param name="reader">XmlReader to processing the context.</param> | 125 | /// <param name="reader">XmlReader to processing the context.</param> |
105 | /// <returns>XDocument with the postprocessed data.</returns> | 126 | /// <returns>XDocument with the postprocessed data.</returns> |
106 | public XDocument Process(IPreprocessContext context, XmlReader reader) | 127 | public XDocument Execute(XmlReader reader) |
107 | { | 128 | { |
108 | if (this.Context == null) | 129 | if (String.IsNullOrEmpty(this.SourcePath) && !String.IsNullOrEmpty(reader.BaseURI)) |
109 | { | ||
110 | this.Context = context ?? throw new ArgumentNullException(nameof(context)); | ||
111 | } | ||
112 | else if (this.Context != context) | ||
113 | { | ||
114 | throw new ArgumentException(nameof(context)); | ||
115 | } | ||
116 | |||
117 | if (String.IsNullOrEmpty(this.Context.SourceFile) && !String.IsNullOrEmpty(reader.BaseURI)) | ||
118 | { | 130 | { |
119 | var uri = new Uri(reader.BaseURI); | 131 | var uri = new Uri(reader.BaseURI); |
120 | this.Context.SourceFile = uri.AbsolutePath; | 132 | this.SourcePath = uri.AbsolutePath; |
121 | } | 133 | } |
122 | 134 | ||
123 | this.Context.CurrentSourceLineNumber = new SourceLineNumber(this.Context.SourceFile); | 135 | this.Context = this.CreateContext(); |
124 | 136 | ||
125 | this.Helper = this.Context.ServiceProvider.GetService<IPreprocessHelper>(); | 137 | this.PreProcess(); |
126 | 138 | ||
127 | foreach (var extension in this.Context.Extensions) | 139 | var document = this.Process(reader); |
128 | { | ||
129 | if (null != extension.Prefixes) | ||
130 | { | ||
131 | foreach (string prefix in extension.Prefixes) | ||
132 | { | ||
133 | if (!this.ExtensionsByPrefix.TryGetValue(prefix, out var collidingExtension)) | ||
134 | { | ||
135 | this.ExtensionsByPrefix.Add(prefix, extension); | ||
136 | } | ||
137 | else | ||
138 | { | ||
139 | this.Context.Messaging.Write(ErrorMessages.DuplicateExtensionPreprocessorType(extension.GetType().ToString(), prefix, collidingExtension.GetType().ToString())); | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | 140 | ||
144 | extension.PrePreprocess(context); | 141 | return PostProcess(document); |
145 | } | 142 | } |
143 | |||
144 | /// <summary> | ||
145 | /// Preprocesses a file. | ||
146 | /// </summary> | ||
147 | /// <param name="context">The preprocessing context.</param> | ||
148 | /// <param name="reader">XmlReader to processing the context.</param> | ||
149 | /// <returns>XDocument with the postprocessed data.</returns> | ||
150 | private XDocument Process(XmlReader reader) | ||
151 | { | ||
152 | this.Helper = this.ServiceProvider.GetService<IPreprocessHelper>(); | ||
146 | 153 | ||
147 | this.CurrentFileStack.Clear(); | 154 | this.CurrentFileStack.Clear(); |
148 | this.CurrentFileStack.Push(this.Helper.GetVariableValue(this.Context, "sys", "SOURCEFILEDIR")); | 155 | this.CurrentFileStack.Push(this.Helper.GetVariableValue(this.Context, "sys", "SOURCEFILEDIR")); |
@@ -161,14 +168,6 @@ namespace WixToolset.Core | |||
161 | this.UpdateCurrentLineNumber(reader, 0); | 168 | this.UpdateCurrentLineNumber(reader, 0); |
162 | throw new WixException(ErrorMessages.InvalidXml(this.Context.CurrentSourceLineNumber, "source", e.Message)); | 169 | throw new WixException(ErrorMessages.InvalidXml(this.Context.CurrentSourceLineNumber, "source", e.Message)); |
163 | } | 170 | } |
164 | finally | ||
165 | { | ||
166 | // Finalize the preprocessing. | ||
167 | foreach (var extension in this.Context.Extensions) | ||
168 | { | ||
169 | extension.PostPreprocess(output); | ||
170 | } | ||
171 | } | ||
172 | 171 | ||
173 | return this.Context.Messaging.EncounteredError ? null : output; | 172 | return this.Context.Messaging.EncounteredError ? null : output; |
174 | } | 173 | } |
@@ -1404,7 +1403,7 @@ namespace WixToolset.Core | |||
1404 | { | 1403 | { |
1405 | // build a string to test the directory containing the source file first | 1404 | // build a string to test the directory containing the source file first |
1406 | var currentFolder = this.CurrentFileStack.Peek(); | 1405 | var currentFolder = this.CurrentFileStack.Peek(); |
1407 | var includeTestPath = Path.Combine(Path.GetDirectoryName(currentFolder) , includePath); | 1406 | var includeTestPath = Path.Combine(Path.GetDirectoryName(currentFolder), includePath); |
1408 | 1407 | ||
1409 | // test the source file directory | 1408 | // test the source file directory |
1410 | if (File.Exists(includeTestPath)) | 1409 | if (File.Exists(includeTestPath)) |
@@ -1428,5 +1427,52 @@ namespace WixToolset.Core | |||
1428 | 1427 | ||
1429 | return finalIncludePath; | 1428 | return finalIncludePath; |
1430 | } | 1429 | } |
1430 | |||
1431 | private IPreprocessContext CreateContext() | ||
1432 | { | ||
1433 | var context = this.ServiceProvider.GetService<IPreprocessContext>(); | ||
1434 | context.Messaging = this.ServiceProvider.GetService<IMessaging>(); | ||
1435 | context.Extensions = this.ServiceProvider.GetService<IExtensionManager>().Create<IPreprocessorExtension>(); | ||
1436 | context.CurrentSourceLineNumber = new SourceLineNumber(this.SourcePath); | ||
1437 | context.Platform = this.Platform; | ||
1438 | context.IncludeSearchPaths = this.IncludeSearchPaths?.ToList() ?? new List<string>(); | ||
1439 | context.SourceFile = this.SourcePath; | ||
1440 | context.Variables = new Dictionary<string, string>(this.Variables); | ||
1441 | |||
1442 | return context; | ||
1443 | } | ||
1444 | |||
1445 | private void PreProcess() | ||
1446 | { | ||
1447 | foreach (var extension in this.Context.Extensions) | ||
1448 | { | ||
1449 | if (extension.Prefixes != null) | ||
1450 | { | ||
1451 | foreach (var prefix in extension.Prefixes) | ||
1452 | { | ||
1453 | if (!this.ExtensionsByPrefix.TryGetValue(prefix, out var collidingExtension)) | ||
1454 | { | ||
1455 | this.ExtensionsByPrefix.Add(prefix, extension); | ||
1456 | } | ||
1457 | else | ||
1458 | { | ||
1459 | this.Context.Messaging.Write(ErrorMessages.DuplicateExtensionPreprocessorType(extension.GetType().ToString(), prefix, collidingExtension.GetType().ToString())); | ||
1460 | } | ||
1461 | } | ||
1462 | } | ||
1463 | |||
1464 | extension.PrePreprocess(this.Context); | ||
1465 | } | ||
1466 | } | ||
1467 | |||
1468 | private XDocument PostProcess(XDocument document) | ||
1469 | { | ||
1470 | foreach (var extension in this.Context.Extensions) | ||
1471 | { | ||
1472 | extension.PostPreprocess(document); | ||
1473 | } | ||
1474 | |||
1475 | return document; | ||
1476 | } | ||
1431 | } | 1477 | } |
1432 | } | 1478 | } |