diff options
author | Rob Mensching <rob@firegiant.com> | 2017-12-30 17:09:15 -0800 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2017-12-30 17:09:15 -0800 |
commit | c5190ae74ab8fe13609362efce88fa4b8cc24f34 (patch) | |
tree | e7762224afad491c37b70bab13756552c72fdd26 /src/WixToolset.Core/Linker.cs | |
parent | d4f73e72985dc2f36e4228358f4dc9b6114414ab (diff) | |
download | wix-c5190ae74ab8fe13609362efce88fa4b8cc24f34.tar.gz wix-c5190ae74ab8fe13609362efce88fa4b8cc24f34.tar.bz2 wix-c5190ae74ab8fe13609362efce88fa4b8cc24f34.zip |
Fix resolution of localizations that are embedded in intermediates
Diffstat (limited to 'src/WixToolset.Core/Linker.cs')
-rw-r--r-- | src/WixToolset.Core/Linker.cs | 420 |
1 files changed, 220 insertions, 200 deletions
diff --git a/src/WixToolset.Core/Linker.cs b/src/WixToolset.Core/Linker.cs index 79ddd30a..db2514fb 100644 --- a/src/WixToolset.Core/Linker.cs +++ b/src/WixToolset.Core/Linker.cs | |||
@@ -32,9 +32,6 @@ namespace WixToolset.Core | |||
32 | { | 32 | { |
33 | this.ServiceProvider = serviceProvider; | 33 | this.ServiceProvider = serviceProvider; |
34 | this.sectionIdOnRows = true; // TODO: what is the correct value for this? | 34 | this.sectionIdOnRows = true; // TODO: what is the correct value for this? |
35 | |||
36 | //this.extensionData = new List<IExtensionData>(); | ||
37 | //this.inspectorExtensions = new List<InspectorExtension>(); | ||
38 | } | 35 | } |
39 | 36 | ||
40 | private IServiceProvider ServiceProvider { get; } | 37 | private IServiceProvider ServiceProvider { get; } |
@@ -78,40 +75,49 @@ namespace WixToolset.Core | |||
78 | this.Context.Extensions = extensionManager.Create<ILinkerExtension>(); | 75 | this.Context.Extensions = extensionManager.Create<ILinkerExtension>(); |
79 | this.Context.ExtensionData = extensionManager.Create<IExtensionData>(); | 76 | this.Context.ExtensionData = extensionManager.Create<IExtensionData>(); |
80 | this.Context.ExpectedOutputType = this.OutputType; | 77 | this.Context.ExpectedOutputType = this.OutputType; |
81 | this.Context.Intermediates = this.Intermediates.Union(this.Libraries).ToList(); | 78 | this.Context.Intermediates = this.Intermediates.Concat(this.Libraries).ToList(); |
82 | this.Context.TupleDefinitionCreator = creator; | 79 | this.Context.TupleDefinitionCreator = creator; |
83 | 80 | ||
84 | var sections = this.Context.Intermediates.SelectMany(i => i.Sections).ToList(); | 81 | foreach (var extension in this.Context.Extensions) |
82 | { | ||
83 | extension.PreLink(this.Context); | ||
84 | } | ||
85 | 85 | ||
86 | // Add sections from the extensions with data. | 86 | Intermediate intermediate = null; |
87 | foreach (var data in this.Context.ExtensionData) | 87 | try |
88 | { | 88 | { |
89 | var library = data.GetLibrary(this.Context.TupleDefinitionCreator); | 89 | var sections = this.Context.Intermediates.SelectMany(i => i.Sections).ToList(); |
90 | var localizations = this.Context.Intermediates.SelectMany(i => i.Localizations).ToList(); | ||
90 | 91 | ||
91 | if (library != null) | 92 | // Add sections from the extensions with data. |
93 | foreach (var data in this.Context.ExtensionData) | ||
92 | { | 94 | { |
93 | sections.AddRange(library.Sections); | 95 | var library = data.GetLibrary(this.Context.TupleDefinitionCreator); |
96 | |||
97 | if (library != null) | ||
98 | { | ||
99 | sections.AddRange(library.Sections); | ||
100 | } | ||
94 | } | 101 | } |
95 | } | ||
96 | 102 | ||
97 | #if MOVE_TO_BACKEND | 103 | #if MOVE_TO_BACKEND |
98 | bool containsModuleSubstitution = false; | 104 | bool containsModuleSubstitution = false; |
99 | bool containsModuleConfiguration = false; | 105 | bool containsModuleConfiguration = false; |
100 | #endif | 106 | #endif |
101 | 107 | ||
102 | //this.activeOutput = null; | 108 | //this.activeOutput = null; |
103 | 109 | ||
104 | //TableDefinitionCollection customTableDefinitions = new TableDefinitionCollection(); | 110 | //TableDefinitionCollection customTableDefinitions = new TableDefinitionCollection(); |
105 | //IntermediateTuple customRows = new List<IntermediateTuple>(); | 111 | //IntermediateTuple customRows = new List<IntermediateTuple>(); |
106 | 112 | ||
107 | #if MOVE_TO_BACKEND | 113 | #if MOVE_TO_BACKEND |
108 | StringCollection generatedShortFileNameIdentifiers = new StringCollection(); | 114 | StringCollection generatedShortFileNameIdentifiers = new StringCollection(); |
109 | Hashtable generatedShortFileNames = new Hashtable(); | 115 | Hashtable generatedShortFileNames = new Hashtable(); |
110 | #endif | 116 | #endif |
111 | 117 | ||
112 | Hashtable multipleFeatureComponents = new Hashtable(); | 118 | Hashtable multipleFeatureComponents = new Hashtable(); |
113 | 119 | ||
114 | var wixVariables = new Dictionary<string, WixVariableTuple>(); | 120 | var wixVariables = new Dictionary<string, WixVariableTuple>(); |
115 | 121 | ||
116 | #if MOVE_TO_BACKEND | 122 | #if MOVE_TO_BACKEND |
117 | // verify that modularization types match for foreign key relationships | 123 | // verify that modularization types match for foreign key relationships |
@@ -143,114 +149,117 @@ namespace WixToolset.Core | |||
143 | } | 149 | } |
144 | #endif | 150 | #endif |
145 | 151 | ||
146 | // First find the entry section and while processing all sections load all the symbols from all of the sections. | 152 | // First find the entry section and while processing all sections load all the symbols from all of the sections. |
147 | // sections.FindEntrySectionAndLoadSymbols(false, this, expectedOutputType, out entrySection, out allSymbols); | 153 | // sections.FindEntrySectionAndLoadSymbols(false, this, expectedOutputType, out entrySection, out allSymbols); |
148 | var find = new FindEntrySectionAndLoadSymbolsCommand(this.Context.Messaging, sections); | 154 | var find = new FindEntrySectionAndLoadSymbolsCommand(this.Context.Messaging, sections); |
149 | find.ExpectedOutputType = this.Context.ExpectedOutputType; | 155 | find.ExpectedOutputType = this.Context.ExpectedOutputType; |
150 | find.Execute(); | 156 | find.Execute(); |
151 | 157 | ||
152 | // Must have found the entry section by now. | 158 | // Must have found the entry section by now. |
153 | if (null == find.EntrySection) | 159 | if (null == find.EntrySection) |
154 | { | 160 | { |
155 | throw new WixException(ErrorMessages.MissingEntrySection(this.Context.ExpectedOutputType.ToString())); | 161 | throw new WixException(ErrorMessages.MissingEntrySection(this.Context.ExpectedOutputType.ToString())); |
156 | } | 162 | } |
157 | 163 | ||
158 | // Add the missing standard action symbols. | 164 | // Add the missing standard action symbols. |
159 | this.LoadStandardActionSymbols(find.EntrySection, find.Symbols); | 165 | this.LoadStandardActionSymbols(find.EntrySection, find.Symbols); |
160 | 166 | ||
161 | // Resolve the symbol references to find the set of sections we care about for linking. | 167 | // Resolve the symbol references to find the set of sections we care about for linking. |
162 | // Of course, we start with the entry section (that's how it got its name after all). | 168 | // Of course, we start with the entry section (that's how it got its name after all). |
163 | var resolve = new ResolveReferencesCommand(this.Context.Messaging, find.EntrySection, find.Symbols); | 169 | var resolve = new ResolveReferencesCommand(this.Context.Messaging, find.EntrySection, find.Symbols); |
164 | resolve.BuildingMergeModule = (SectionType.Module == find.EntrySection.Type); | 170 | resolve.BuildingMergeModule = (SectionType.Module == find.EntrySection.Type); |
165 | 171 | ||
166 | resolve.Execute(); | 172 | resolve.Execute(); |
167 | 173 | ||
168 | if (this.Context.Messaging.EncounteredError) | 174 | if (this.Context.Messaging.EncounteredError) |
169 | { | 175 | { |
170 | return null; | 176 | return null; |
171 | } | 177 | } |
172 | 178 | ||
173 | // Reset the sections to only those that were resolved then flatten the complex | 179 | // Reset the sections to only those that were resolved then flatten the complex |
174 | // references that particpate in groups. | 180 | // references that particpate in groups. |
175 | sections = resolve.ResolvedSections.ToList(); | 181 | sections = resolve.ResolvedSections.ToList(); |
176 | 182 | ||
177 | this.FlattenSectionsComplexReferences(sections); | 183 | // TODO: consider filtering "localizations" down to only those localizations from |
184 | // intermediates in the sections. | ||
178 | 185 | ||
179 | if (this.Context.Messaging.EncounteredError) | 186 | this.FlattenSectionsComplexReferences(sections); |
180 | { | ||
181 | return null; | ||
182 | } | ||
183 | 187 | ||
184 | // The hard part in linking is processing the complex references. | 188 | if (this.Context.Messaging.EncounteredError) |
185 | var referencedComponents = new HashSet<string>(); | 189 | { |
186 | var componentsToFeatures = new ConnectToFeatureCollection(); | 190 | return null; |
187 | var featuresToFeatures = new ConnectToFeatureCollection(); | 191 | } |
188 | var modulesToFeatures = new ConnectToFeatureCollection(); | ||
189 | this.ProcessComplexReferences(find.EntrySection, sections, referencedComponents, componentsToFeatures, featuresToFeatures, modulesToFeatures); | ||
190 | 192 | ||
191 | if (this.Context.Messaging.EncounteredError) | 193 | // The hard part in linking is processing the complex references. |
192 | { | 194 | var referencedComponents = new HashSet<string>(); |
193 | return null; | 195 | var componentsToFeatures = new ConnectToFeatureCollection(); |
194 | } | 196 | var featuresToFeatures = new ConnectToFeatureCollection(); |
197 | var modulesToFeatures = new ConnectToFeatureCollection(); | ||
198 | this.ProcessComplexReferences(find.EntrySection, sections, referencedComponents, componentsToFeatures, featuresToFeatures, modulesToFeatures); | ||
195 | 199 | ||
196 | // Display an error message for Components that were not referenced by a Feature. | 200 | if (this.Context.Messaging.EncounteredError) |
197 | foreach (var symbol in resolve.ReferencedSymbols.Where(s => s.Row.Definition.Type == TupleDefinitionType.Component)) | ||
198 | { | ||
199 | if (!referencedComponents.Contains(symbol.Name)) | ||
200 | { | 201 | { |
201 | this.OnMessage(ErrorMessages.OrphanedComponent(symbol.Row.SourceLineNumbers, symbol.Row.Id.Id)); | 202 | return null; |
202 | } | 203 | } |
203 | } | ||
204 | 204 | ||
205 | // Report duplicates that would ultimately end up being primary key collisions. | 205 | // Display an error message for Components that were not referenced by a Feature. |
206 | var reportDupes = new ReportConflictingSymbolsCommand(this.Context.Messaging, find.PossiblyConflictingSymbols, resolve.ResolvedSections); | 206 | foreach (var symbol in resolve.ReferencedSymbols.Where(s => s.Row.Definition.Type == TupleDefinitionType.Component)) |
207 | reportDupes.Execute(); | 207 | { |
208 | if (!referencedComponents.Contains(symbol.Name)) | ||
209 | { | ||
210 | this.OnMessage(ErrorMessages.OrphanedComponent(symbol.Row.SourceLineNumbers, symbol.Row.Id.Id)); | ||
211 | } | ||
212 | } | ||
208 | 213 | ||
209 | if (this.Context.Messaging.EncounteredError) | 214 | // Report duplicates that would ultimately end up being primary key collisions. |
210 | { | 215 | var reportDupes = new ReportConflictingSymbolsCommand(this.Context.Messaging, find.PossiblyConflictingSymbols, resolve.ResolvedSections); |
211 | return null; | 216 | reportDupes.Execute(); |
212 | } | ||
213 | 217 | ||
214 | // resolve the feature to feature connects | 218 | if (this.Context.Messaging.EncounteredError) |
215 | this.ResolveFeatureToFeatureConnects(featuresToFeatures, find.Symbols); | 219 | { |
220 | return null; | ||
221 | } | ||
216 | 222 | ||
217 | // start generating OutputTables and OutputRows for all the sections in the output | 223 | // resolve the feature to feature connects |
218 | var ensureTableRows = new List<IntermediateTuple>(); | 224 | this.ResolveFeatureToFeatureConnects(featuresToFeatures, find.Symbols); |
219 | 225 | ||
220 | // Create the section to hold the linked content. | 226 | // start generating OutputTables and OutputRows for all the sections in the output |
221 | var resolvedSection = new IntermediateSection(find.EntrySection.Id, find.EntrySection.Type, find.EntrySection.Codepage); | 227 | var ensureTableRows = new List<IntermediateTuple>(); |
222 | 228 | ||
223 | var sectionCount = 0; | 229 | // Create the section to hold the linked content. |
230 | var resolvedSection = new IntermediateSection(find.EntrySection.Id, find.EntrySection.Type, find.EntrySection.Codepage); | ||
224 | 231 | ||
225 | foreach (var section in sections) | 232 | var sectionCount = 0; |
226 | { | ||
227 | sectionCount++; | ||
228 | 233 | ||
229 | var sectionId = section.Id; | 234 | foreach (var section in sections) |
230 | if (null == sectionId && this.sectionIdOnRows) | ||
231 | { | 235 | { |
232 | sectionId = "wix.section." + sectionCount.ToString(CultureInfo.InvariantCulture); | 236 | sectionCount++; |
233 | } | ||
234 | 237 | ||
235 | foreach (var tuple in section.Tuples) | 238 | var sectionId = section.Id; |
236 | { | 239 | if (null == sectionId && this.sectionIdOnRows) |
237 | var copyTuple = true; // by default, copy tuples. | 240 | { |
241 | sectionId = "wix.section." + sectionCount.ToString(CultureInfo.InvariantCulture); | ||
242 | } | ||
238 | 243 | ||
239 | // handle special tables | 244 | foreach (var tuple in section.Tuples) |
240 | switch (tuple.Definition.Type) | ||
241 | { | 245 | { |
246 | var copyTuple = true; // by default, copy tuples. | ||
247 | |||
248 | // handle special tables | ||
249 | switch (tuple.Definition.Type) | ||
250 | { | ||
242 | #if MOVE_TO_BACKEND | 251 | #if MOVE_TO_BACKEND |
243 | case "AppSearch": | 252 | case "AppSearch": |
244 | this.activeOutput.EnsureTable(this.tableDefinitions["Signature"]); | 253 | this.activeOutput.EnsureTable(this.tableDefinitions["Signature"]); |
245 | break; | 254 | break; |
246 | #endif | 255 | #endif |
247 | 256 | ||
248 | case TupleDefinitionType.Class: | 257 | case TupleDefinitionType.Class: |
249 | if (SectionType.Product == resolvedSection.Type) | 258 | if (SectionType.Product == resolvedSection.Type) |
250 | { | 259 | { |
251 | this.ResolveFeatures(tuple, 2, 11, componentsToFeatures, multipleFeatureComponents); | 260 | this.ResolveFeatures(tuple, 2, 11, componentsToFeatures, multipleFeatureComponents); |
252 | } | 261 | } |
253 | break; | 262 | break; |
254 | 263 | ||
255 | #if MOVE_TO_BACKEND | 264 | #if MOVE_TO_BACKEND |
256 | case "CustomAction": | 265 | case "CustomAction": |
@@ -304,12 +313,12 @@ namespace WixToolset.Core | |||
304 | } | 313 | } |
305 | break; | 314 | break; |
306 | #endif | 315 | #endif |
307 | case TupleDefinitionType.Extension: | 316 | case TupleDefinitionType.Extension: |
308 | if (SectionType.Product == resolvedSection.Type) | 317 | if (SectionType.Product == resolvedSection.Type) |
309 | { | 318 | { |
310 | this.ResolveFeatures(tuple, 1, 4, componentsToFeatures, multipleFeatureComponents); | 319 | this.ResolveFeatures(tuple, 1, 4, componentsToFeatures, multipleFeatureComponents); |
311 | } | 320 | } |
312 | break; | 321 | break; |
313 | 322 | ||
314 | #if MOVE_TO_BACKEND | 323 | #if MOVE_TO_BACKEND |
315 | case TupleDefinitionType.ModuleSubstitution: | 324 | case TupleDefinitionType.ModuleSubstitution: |
@@ -321,12 +330,12 @@ namespace WixToolset.Core | |||
321 | break; | 330 | break; |
322 | #endif | 331 | #endif |
323 | 332 | ||
324 | case TupleDefinitionType.MsiAssembly: | 333 | case TupleDefinitionType.MsiAssembly: |
325 | if (SectionType.Product == resolvedSection.Type) | 334 | if (SectionType.Product == resolvedSection.Type) |
326 | { | 335 | { |
327 | this.ResolveFeatures(tuple, 0, 1, componentsToFeatures, multipleFeatureComponents); | 336 | this.ResolveFeatures(tuple, 0, 1, componentsToFeatures, multipleFeatureComponents); |
328 | } | 337 | } |
329 | break; | 338 | break; |
330 | 339 | ||
331 | #if MOVE_TO_BACKEND | 340 | #if MOVE_TO_BACKEND |
332 | case "ProgId": | 341 | case "ProgId": |
@@ -348,26 +357,26 @@ namespace WixToolset.Core | |||
348 | break; | 357 | break; |
349 | #endif | 358 | #endif |
350 | 359 | ||
351 | case TupleDefinitionType.PublishComponent: | 360 | case TupleDefinitionType.PublishComponent: |
352 | if (SectionType.Product == resolvedSection.Type) | 361 | if (SectionType.Product == resolvedSection.Type) |
353 | { | 362 | { |
354 | this.ResolveFeatures(tuple, 2, 4, componentsToFeatures, multipleFeatureComponents); | 363 | this.ResolveFeatures(tuple, 2, 4, componentsToFeatures, multipleFeatureComponents); |
355 | } | 364 | } |
356 | break; | 365 | break; |
357 | 366 | ||
358 | case TupleDefinitionType.Shortcut: | 367 | case TupleDefinitionType.Shortcut: |
359 | if (SectionType.Product == resolvedSection.Type) | 368 | if (SectionType.Product == resolvedSection.Type) |
360 | { | 369 | { |
361 | this.ResolveFeatures(tuple, 3, 4, componentsToFeatures, multipleFeatureComponents); | 370 | this.ResolveFeatures(tuple, 3, 4, componentsToFeatures, multipleFeatureComponents); |
362 | } | 371 | } |
363 | break; | 372 | break; |
364 | 373 | ||
365 | case TupleDefinitionType.TypeLib: | 374 | case TupleDefinitionType.TypeLib: |
366 | if (SectionType.Product == resolvedSection.Type) | 375 | if (SectionType.Product == resolvedSection.Type) |
367 | { | 376 | { |
368 | this.ResolveFeatures(tuple, 2, 6, componentsToFeatures, multipleFeatureComponents); | 377 | this.ResolveFeatures(tuple, 2, 6, componentsToFeatures, multipleFeatureComponents); |
369 | } | 378 | } |
370 | break; | 379 | break; |
371 | 380 | ||
372 | #if SOLVE_CUSTOM_TABLE | 381 | #if SOLVE_CUSTOM_TABLE |
373 | case "WixCustomTable": | 382 | case "WixCustomTable": |
@@ -385,9 +394,9 @@ namespace WixToolset.Core | |||
385 | break; | 394 | break; |
386 | #endif | 395 | #endif |
387 | 396 | ||
388 | case TupleDefinitionType.WixEnsureTable: | 397 | case TupleDefinitionType.WixEnsureTable: |
389 | ensureTableRows.Add(tuple); | 398 | ensureTableRows.Add(tuple); |
390 | break; | 399 | break; |
391 | 400 | ||
392 | 401 | ||
393 | #if MOVE_TO_BACKEND | 402 | #if MOVE_TO_BACKEND |
@@ -410,66 +419,66 @@ namespace WixToolset.Core | |||
410 | break; | 419 | break; |
411 | #endif | 420 | #endif |
412 | 421 | ||
413 | case TupleDefinitionType.WixMerge: | 422 | case TupleDefinitionType.WixMerge: |
414 | if (SectionType.Product == resolvedSection.Type) | 423 | if (SectionType.Product == resolvedSection.Type) |
415 | { | 424 | { |
416 | this.ResolveFeatures(tuple, 0, 7, modulesToFeatures, null); | 425 | this.ResolveFeatures(tuple, 0, 7, modulesToFeatures, null); |
417 | } | 426 | } |
418 | break; | 427 | break; |
419 | |||
420 | case TupleDefinitionType.WixComplexReference: | ||
421 | copyTuple = false; | ||
422 | break; | ||
423 | 428 | ||
424 | case TupleDefinitionType.WixSimpleReference: | 429 | case TupleDefinitionType.WixComplexReference: |
425 | copyTuple = false; | 430 | copyTuple = false; |
426 | break; | 431 | break; |
427 | 432 | ||
428 | case TupleDefinitionType.WixVariable: | 433 | case TupleDefinitionType.WixSimpleReference: |
429 | // check for colliding values and collect the wix variable rows | 434 | copyTuple = false; |
430 | { | 435 | break; |
431 | var row = (WixVariableTuple)tuple; | ||
432 | 436 | ||
433 | if (wixVariables.TryGetValue(row.WixVariable, out var collidingRow)) | 437 | case TupleDefinitionType.WixVariable: |
438 | // check for colliding values and collect the wix variable rows | ||
434 | { | 439 | { |
435 | if (collidingRow.Overridable && !row.Overridable) | 440 | var row = (WixVariableTuple)tuple; |
441 | |||
442 | if (wixVariables.TryGetValue(row.WixVariable, out var collidingRow)) | ||
436 | { | 443 | { |
437 | wixVariables[row.WixVariable] = row; | 444 | if (collidingRow.Overridable && !row.Overridable) |
445 | { | ||
446 | wixVariables[row.WixVariable] = row; | ||
447 | } | ||
448 | else if (!row.Overridable || (collidingRow.Overridable && row.Overridable)) | ||
449 | { | ||
450 | this.OnMessage(ErrorMessages.WixVariableCollision(row.SourceLineNumbers, row.WixVariable)); | ||
451 | } | ||
438 | } | 452 | } |
439 | else if (!row.Overridable || (collidingRow.Overridable && row.Overridable)) | 453 | else |
440 | { | 454 | { |
441 | this.OnMessage(ErrorMessages.WixVariableCollision(row.SourceLineNumbers, row.WixVariable)); | 455 | wixVariables.Add(row.WixVariable, row); |
442 | } | 456 | } |
443 | } | 457 | } |
444 | else | ||
445 | { | ||
446 | wixVariables.Add(row.WixVariable, row); | ||
447 | } | ||
448 | } | ||
449 | 458 | ||
450 | copyTuple = false; | 459 | copyTuple = false; |
451 | break; | 460 | break; |
452 | } | 461 | } |
453 | 462 | ||
454 | if (copyTuple) | 463 | if (copyTuple) |
455 | { | 464 | { |
456 | resolvedSection.Tuples.Add(tuple); | 465 | resolvedSection.Tuples.Add(tuple); |
466 | } | ||
457 | } | 467 | } |
458 | } | 468 | } |
459 | } | ||
460 | 469 | ||
461 | // copy the module to feature connections into the output | 470 | // copy the module to feature connections into the output |
462 | foreach (ConnectToFeature connectToFeature in modulesToFeatures) | 471 | foreach (ConnectToFeature connectToFeature in modulesToFeatures) |
463 | { | ||
464 | foreach (var feature in connectToFeature.ConnectFeatures) | ||
465 | { | 472 | { |
466 | var row = new WixFeatureModulesTuple(); | 473 | foreach (var feature in connectToFeature.ConnectFeatures) |
467 | row.Feature_ = feature; | 474 | { |
468 | row.WixMerge_ = connectToFeature.ChildId; | 475 | var row = new WixFeatureModulesTuple(); |
476 | row.Feature_ = feature; | ||
477 | row.WixMerge_ = connectToFeature.ChildId; | ||
469 | 478 | ||
470 | resolvedSection.Tuples.Add(row); | 479 | resolvedSection.Tuples.Add(row); |
480 | } | ||
471 | } | 481 | } |
472 | } | ||
473 | 482 | ||
474 | #if MOVE_TO_BACKEND | 483 | #if MOVE_TO_BACKEND |
475 | // ensure the creation of tables that need to exist | 484 | // ensure the creation of tables that need to exist |
@@ -612,24 +621,24 @@ namespace WixToolset.Core | |||
612 | } | 621 | } |
613 | #endif | 622 | #endif |
614 | 623 | ||
615 | //correct the section Id in FeatureComponents table | 624 | //correct the section Id in FeatureComponents table |
616 | if (this.sectionIdOnRows) | 625 | if (this.sectionIdOnRows) |
617 | { | 626 | { |
618 | //var componentSectionIds = new Dictionary<string, string>(); | 627 | //var componentSectionIds = new Dictionary<string, string>(); |
619 | 628 | ||
620 | //foreach (var componentTuple in entrySection.Tuples.OfType<ComponentTuple>()) | 629 | //foreach (var componentTuple in entrySection.Tuples.OfType<ComponentTuple>()) |
621 | //{ | 630 | //{ |
622 | // componentSectionIds.Add(componentTuple.Id.Id, componentTuple.SectionId); | 631 | // componentSectionIds.Add(componentTuple.Id.Id, componentTuple.SectionId); |
623 | //} | 632 | //} |
624 | 633 | ||
625 | //foreach (var featureComponentTuple in entrySection.Tuples.OfType<FeatureComponentsTuple>()) | 634 | //foreach (var featureComponentTuple in entrySection.Tuples.OfType<FeatureComponentsTuple>()) |
626 | //{ | 635 | //{ |
627 | // if (componentSectionIds.TryGetValue(featureComponentTuple.Component_, out var componentSectionId)) | 636 | // if (componentSectionIds.TryGetValue(featureComponentTuple.Component_, out var componentSectionId)) |
628 | // { | 637 | // { |
629 | // featureComponentTuple.SectionId = componentSectionId; | 638 | // featureComponentTuple.SectionId = componentSectionId; |
630 | // } | 639 | // } |
631 | //} | 640 | //} |
632 | } | 641 | } |
633 | 642 | ||
634 | #if MOVE_TO_BACKEND | 643 | #if MOVE_TO_BACKEND |
635 | // add the ModuleSubstitution table to the ModuleIgnoreTable | 644 | // add the ModuleSubstitution table to the ModuleIgnoreTable |
@@ -698,27 +707,38 @@ namespace WixToolset.Core | |||
698 | } | 707 | } |
699 | #endif | 708 | #endif |
700 | 709 | ||
701 | // copy the wix variable rows to the output after all overriding has been accounted for. | 710 | // copy the wix variable rows to the output after all overriding has been accounted for. |
702 | foreach (var row in wixVariables.Values) | 711 | foreach (var row in wixVariables.Values) |
703 | { | 712 | { |
704 | resolvedSection.Tuples.Add(row); | 713 | resolvedSection.Tuples.Add(row); |
705 | } | 714 | } |
706 | 715 | ||
707 | // Bundles have groups of data that must be flattened in a way different from other types. | 716 | // Bundles have groups of data that must be flattened in a way different from other types. |
708 | this.FlattenBundleTables(resolvedSection); | 717 | this.FlattenBundleTables(resolvedSection); |
709 | 718 | ||
710 | if (this.Context.Messaging.EncounteredError) | 719 | if (this.Context.Messaging.EncounteredError) |
711 | { | 720 | { |
712 | return null; | 721 | return null; |
713 | } | 722 | } |
714 | 723 | ||
715 | var output = new Intermediate(resolvedSection.Id, new[] { resolvedSection }, null, null); | 724 | var collate = new CollateLocalizationsCommand(this.Context.Messaging, localizations); |
725 | var localizationsByCulture = collate.Execute(); | ||
726 | |||
727 | intermediate = new Intermediate(resolvedSection.Id, new[] { resolvedSection }, localizationsByCulture, null); | ||
716 | 728 | ||
717 | #if MOVE_TO_BACKEND | 729 | #if MOVE_TO_BACKEND |
718 | this.CheckOutputConsistency(output); | 730 | this.CheckOutputConsistency(output); |
719 | #endif | 731 | #endif |
732 | } | ||
733 | finally | ||
734 | { | ||
735 | foreach (var extension in this.Context.Extensions) | ||
736 | { | ||
737 | extension.PostLink(intermediate); | ||
738 | } | ||
739 | } | ||
720 | 740 | ||
721 | return this.Context.Messaging.EncounteredError ? null : output; | 741 | return this.Context.Messaging.EncounteredError ? null : intermediate; |
722 | } | 742 | } |
723 | 743 | ||
724 | #if SOLVE_CUSTOM_TABLE | 744 | #if SOLVE_CUSTOM_TABLE |