diff options
author | Rob Mensching <rob@firegiant.com> | 2017-11-01 10:59:45 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2017-11-01 10:59:45 -0700 |
commit | 2bb37beda887d120a0ddabf874ad25357101faa1 (patch) | |
tree | c35e97b03274b86cfc9ff7fd2caeee211165a140 /src/WixToolset.Core/Link | |
parent | df7413aeed3aea3425dff20ae0c8b1be3a3ab525 (diff) | |
download | wix-2bb37beda887d120a0ddabf874ad25357101faa1.tar.gz wix-2bb37beda887d120a0ddabf874ad25357101faa1.tar.bz2 wix-2bb37beda887d120a0ddabf874ad25357101faa1.zip |
Update to WiX Intermediate Representation
Diffstat (limited to 'src/WixToolset.Core/Link')
7 files changed, 277 insertions, 212 deletions
diff --git a/src/WixToolset.Core/Link/ConnectToFeature.cs b/src/WixToolset.Core/Link/ConnectToFeature.cs index 6e046b89..bc85426a 100644 --- a/src/WixToolset.Core/Link/ConnectToFeature.cs +++ b/src/WixToolset.Core/Link/ConnectToFeature.cs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | namespace WixToolset.Link | 3 | namespace WixToolset.Link |
4 | { | 4 | { |
5 | using System.Collections.Specialized; | 5 | using System.Collections.Generic; |
6 | using WixToolset.Data; | 6 | using WixToolset.Data; |
7 | 7 | ||
8 | /// <summary> | 8 | /// <summary> |
@@ -10,19 +10,12 @@ namespace WixToolset.Link | |||
10 | /// </summary> | 10 | /// </summary> |
11 | public sealed class ConnectToFeature | 11 | public sealed class ConnectToFeature |
12 | { | 12 | { |
13 | private Section section; | ||
14 | private string childId; | ||
15 | |||
16 | private string primaryFeature; | ||
17 | private bool explicitPrimaryFeature; | ||
18 | private StringCollection connectFeatures; | ||
19 | |||
20 | /// <summary> | 13 | /// <summary> |
21 | /// Creates a new connect to feature. | 14 | /// Creates a new connect to feature. |
22 | /// </summary> | 15 | /// </summary> |
23 | /// <param name="section">Section this connect belongs to.</param> | 16 | /// <param name="section">Section this connect belongs to.</param> |
24 | /// <param name="childId">Id of the child.</param> | 17 | /// <param name="childId">Id of the child.</param> |
25 | public ConnectToFeature(Section section, string childId) : | 18 | public ConnectToFeature(IntermediateSection section, string childId) : |
26 | this(section, childId, null, false) | 19 | this(section, childId, null, false) |
27 | { | 20 | { |
28 | } | 21 | } |
@@ -34,62 +27,43 @@ namespace WixToolset.Link | |||
34 | /// <param name="childId">Id of the child.</param> | 27 | /// <param name="childId">Id of the child.</param> |
35 | /// <param name="primaryFeature">Sets the primary feature for the connection.</param> | 28 | /// <param name="primaryFeature">Sets the primary feature for the connection.</param> |
36 | /// <param name="explicitPrimaryFeature">Sets if this is explicit primary.</param> | 29 | /// <param name="explicitPrimaryFeature">Sets if this is explicit primary.</param> |
37 | public ConnectToFeature(Section section, string childId, string primaryFeature, bool explicitPrimaryFeature) | 30 | public ConnectToFeature(IntermediateSection section, string childId, string primaryFeature, bool explicitPrimaryFeature) |
38 | { | 31 | { |
39 | this.section = section; | 32 | this.Section = section; |
40 | this.childId = childId; | 33 | this.ChildId = childId; |
41 | 34 | ||
42 | this.primaryFeature = primaryFeature; | 35 | this.PrimaryFeature = primaryFeature; |
43 | this.explicitPrimaryFeature = explicitPrimaryFeature; | 36 | this.IsExplicitPrimaryFeature = explicitPrimaryFeature; |
44 | |||
45 | this.connectFeatures = new StringCollection(); | ||
46 | } | 37 | } |
47 | 38 | ||
48 | /// <summary> | 39 | /// <summary> |
49 | /// Gets the section. | 40 | /// Gets the section. |
50 | /// </summary> | 41 | /// </summary> |
51 | /// <value>Section.</value> | 42 | /// <value>Section.</value> |
52 | public Section Section | 43 | public IntermediateSection Section { get; } |
53 | { | ||
54 | get { return this.section; } | ||
55 | } | ||
56 | 44 | ||
57 | /// <summary> | 45 | /// <summary> |
58 | /// Gets the child identifier. | 46 | /// Gets the child identifier. |
59 | /// </summary> | 47 | /// </summary> |
60 | /// <value>The child identifier.</value> | 48 | /// <value>The child identifier.</value> |
61 | public string ChildId | 49 | public string ChildId { get; } |
62 | { | ||
63 | get { return this.childId; } | ||
64 | } | ||
65 | 50 | ||
66 | /// <summary> | 51 | /// <summary> |
67 | /// Gets or sets if the flag for if the primary feature was set explicitly. | 52 | /// Gets or sets if the flag for if the primary feature was set explicitly. |
68 | /// </summary> | 53 | /// </summary> |
69 | /// <value>The flag for if the primary feature was set explicitly.</value> | 54 | /// <value>The flag for if the primary feature was set explicitly.</value> |
70 | public bool IsExplicitPrimaryFeature | 55 | public bool IsExplicitPrimaryFeature { get; set; } |
71 | { | ||
72 | get { return this.explicitPrimaryFeature; } | ||
73 | set { this.explicitPrimaryFeature = value; } | ||
74 | } | ||
75 | 56 | ||
76 | /// <summary> | 57 | /// <summary> |
77 | /// Gets or sets the primary feature. | 58 | /// Gets or sets the primary feature. |
78 | /// </summary> | 59 | /// </summary> |
79 | /// <value>The primary feature.</value> | 60 | /// <value>The primary feature.</value> |
80 | public string PrimaryFeature | 61 | public string PrimaryFeature { get; set; } |
81 | { | ||
82 | get { return this.primaryFeature; } | ||
83 | set { this.primaryFeature = value; } | ||
84 | } | ||
85 | 62 | ||
86 | /// <summary> | 63 | /// <summary> |
87 | /// Gets the features connected to. | 64 | /// Gets the features connected to. |
88 | /// </summary> | 65 | /// </summary> |
89 | /// <value>Features connected to.</value> | 66 | /// <value>Features connected to.</value> |
90 | public StringCollection ConnectFeatures | 67 | public List<string> ConnectFeatures { get; } = new List<string>(); |
91 | { | ||
92 | get { return this.connectFeatures; } | ||
93 | } | ||
94 | } | 68 | } |
95 | } | 69 | } |
diff --git a/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs b/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs index effb06e4..00613ca1 100644 --- a/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs +++ b/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs | |||
@@ -1,6 +1,6 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. |
2 | 2 | ||
3 | namespace WixToolset.Link | 3 | namespace WixToolset.Core.Link |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
@@ -9,13 +9,13 @@ namespace WixToolset.Link | |||
9 | 9 | ||
10 | internal class FindEntrySectionAndLoadSymbolsCommand : ICommand | 10 | internal class FindEntrySectionAndLoadSymbolsCommand : ICommand |
11 | { | 11 | { |
12 | private IEnumerable<Section> sections; | 12 | public FindEntrySectionAndLoadSymbolsCommand(IEnumerable<IntermediateSection> sections) |
13 | |||
14 | public FindEntrySectionAndLoadSymbolsCommand(IEnumerable<Section> sections) | ||
15 | { | 13 | { |
16 | this.sections = sections; | 14 | this.Sections = sections; |
17 | } | 15 | } |
18 | 16 | ||
17 | private IEnumerable<IntermediateSection> Sections { get; } | ||
18 | |||
19 | /// <summary> | 19 | /// <summary> |
20 | /// Sets the expected entry output type, based on output file extension provided to the linker. | 20 | /// Sets the expected entry output type, based on output file extension provided to the linker. |
21 | /// </summary> | 21 | /// </summary> |
@@ -24,13 +24,16 @@ namespace WixToolset.Link | |||
24 | /// <summary> | 24 | /// <summary> |
25 | /// Gets the located entry section after the command is executed. | 25 | /// Gets the located entry section after the command is executed. |
26 | /// </summary> | 26 | /// </summary> |
27 | public Section EntrySection { get; private set; } | 27 | public IntermediateSection EntrySection { get; private set; } |
28 | 28 | ||
29 | /// <summary> | 29 | /// <summary> |
30 | /// Gets the collection of loaded symbols. | 30 | /// Gets the collection of loaded symbols. |
31 | /// </summary> | 31 | /// </summary> |
32 | public IDictionary<string, Symbol> Symbols { get; private set; } | 32 | public IDictionary<string, Symbol> Symbols { get; private set; } |
33 | 33 | ||
34 | /// <summary> | ||
35 | /// Gets the collection of possibly conflicting symbols. | ||
36 | /// </summary> | ||
34 | public IEnumerable<Symbol> PossiblyConflictingSymbols { get; private set; } | 37 | public IEnumerable<Symbol> PossiblyConflictingSymbols { get; private set; } |
35 | 38 | ||
36 | public void Execute() | 39 | public void Execute() |
@@ -38,22 +41,22 @@ namespace WixToolset.Link | |||
38 | Dictionary<string, Symbol> symbols = new Dictionary<string, Symbol>(); | 41 | Dictionary<string, Symbol> symbols = new Dictionary<string, Symbol>(); |
39 | HashSet<Symbol> possibleConflicts = new HashSet<Symbol>(); | 42 | HashSet<Symbol> possibleConflicts = new HashSet<Symbol>(); |
40 | 43 | ||
41 | SectionType expectedEntrySectionType; | 44 | if (!Enum.TryParse(this.ExpectedOutputType.ToString(), out SectionType expectedEntrySectionType)) |
42 | if (!Enum.TryParse<SectionType>(this.ExpectedOutputType.ToString(), out expectedEntrySectionType)) | ||
43 | { | 45 | { |
44 | expectedEntrySectionType = SectionType.Unknown; | 46 | expectedEntrySectionType = SectionType.Unknown; |
45 | } | 47 | } |
46 | 48 | ||
47 | foreach (Section section in this.sections) | 49 | foreach (var section in this.Sections) |
48 | { | 50 | { |
49 | // Try to find the one and only entry section. | 51 | // Try to find the one and only entry section. |
50 | if (SectionType.Product == section.Type || SectionType.Module == section.Type || SectionType.PatchCreation == section.Type || SectionType.Patch == section.Type || SectionType.Bundle == section.Type) | 52 | if (SectionType.Product == section.Type || SectionType.Module == section.Type || SectionType.PatchCreation == section.Type || SectionType.Patch == section.Type || SectionType.Bundle == section.Type) |
51 | { | 53 | { |
52 | if (SectionType.Unknown != expectedEntrySectionType && section.Type != expectedEntrySectionType) | 54 | // TODO: remove this? |
53 | { | 55 | //if (SectionType.Unknown != expectedEntrySectionType && section.Type != expectedEntrySectionType) |
54 | string outputExtension = Output.GetExtension(this.ExpectedOutputType); | 56 | //{ |
55 | Messaging.Instance.OnMessage(WixWarnings.UnexpectedEntrySection(section.SourceLineNumbers, section.Type.ToString(), expectedEntrySectionType.ToString(), outputExtension)); | 57 | // string outputExtension = Output.GetExtension(this.ExpectedOutputType); |
56 | } | 58 | // Messaging.Instance.OnMessage(WixWarnings.UnexpectedEntrySection(section.SourceLineNumbers, section.Type.ToString(), expectedEntrySectionType.ToString(), outputExtension)); |
59 | //} | ||
57 | 60 | ||
58 | if (null == this.EntrySection) | 61 | if (null == this.EntrySection) |
59 | { | 62 | { |
@@ -61,42 +64,38 @@ namespace WixToolset.Link | |||
61 | } | 64 | } |
62 | else | 65 | else |
63 | { | 66 | { |
64 | Messaging.Instance.OnMessage(WixErrors.MultipleEntrySections(this.EntrySection.SourceLineNumbers, this.EntrySection.Id, section.Id)); | 67 | Messaging.Instance.OnMessage(WixErrors.MultipleEntrySections(this.EntrySection.Tuples.FirstOrDefault()?.SourceLineNumbers, this.EntrySection.Id, section.Id)); |
65 | Messaging.Instance.OnMessage(WixErrors.MultipleEntrySections2(section.SourceLineNumbers)); | 68 | Messaging.Instance.OnMessage(WixErrors.MultipleEntrySections2(section.Tuples.FirstOrDefault()?.SourceLineNumbers)); |
66 | } | 69 | } |
67 | } | 70 | } |
68 | 71 | ||
69 | // Load all the symbols from the section's tables that create symbols. | 72 | // Load all the symbols from the section's tables that create symbols. |
70 | foreach (Table table in section.Tables.Where(t => t.Definition.CreateSymbols)) | 73 | foreach (var row in section.Tuples.Where(t => t.Id != null)) |
71 | { | 74 | { |
72 | foreach (Row row in table.Rows) | 75 | var symbol = new Symbol(section, row); |
73 | { | ||
74 | Symbol symbol = new Symbol(row); | ||
75 | 76 | ||
76 | Symbol existingSymbol; | 77 | if (!symbols.TryGetValue(symbol.Name, out var existingSymbol)) |
77 | if (!symbols.TryGetValue(symbol.Name, out existingSymbol)) | 78 | { |
79 | symbols.Add(symbol.Name, symbol); | ||
80 | } | ||
81 | else // uh-oh, duplicate symbols. | ||
82 | { | ||
83 | // If the duplicate symbols are both private directories, there is a chance that they | ||
84 | // point to identical tuples. Identical directory tuples are redundant and will not cause | ||
85 | // conflicts. | ||
86 | if (AccessModifier.Private == existingSymbol.Access && AccessModifier.Private == symbol.Access && | ||
87 | TupleDefinitionType.Directory == existingSymbol.Row.Definition.Type && existingSymbol.Row.IsIdentical(symbol.Row)) | ||
78 | { | 88 | { |
79 | symbols.Add(symbol.Name, symbol); | 89 | // Ensure identical symbol's tuple is marked redundant to ensure (should the tuple be |
90 | // referenced into the final output) it will not add duplicate primary keys during | ||
91 | // the .IDT importing. | ||
92 | //symbol.Row.Redundant = true; - TODO: remove this | ||
93 | existingSymbol.AddRedundant(symbol); | ||
80 | } | 94 | } |
81 | else // uh-oh, duplicate symbols. | 95 | else |
82 | { | 96 | { |
83 | // If the duplicate symbols are both private directories, there is a chance that they | 97 | existingSymbol.AddPossibleConflict(symbol); |
84 | // point to identical rows. Identical directory rows are redundant and will not cause | 98 | possibleConflicts.Add(existingSymbol); |
85 | // conflicts. | ||
86 | if (AccessModifier.Private == existingSymbol.Access && AccessModifier.Private == symbol.Access && | ||
87 | "Directory" == existingSymbol.Row.Table.Name && existingSymbol.Row.IsIdentical(symbol.Row)) | ||
88 | { | ||
89 | // Ensure identical symbol's row is marked redundant to ensure (should the row be | ||
90 | // referenced into the final output) it will not add duplicate primary keys during | ||
91 | // the .IDT importing. | ||
92 | symbol.Row.Redundant = true; | ||
93 | existingSymbol.AddRedundant(symbol); | ||
94 | } | ||
95 | else | ||
96 | { | ||
97 | existingSymbol.AddPossibleConflict(symbol); | ||
98 | possibleConflicts.Add(existingSymbol); | ||
99 | } | ||
100 | } | 99 | } |
101 | } | 100 | } |
102 | } | 101 | } |
diff --git a/src/WixToolset.Core/Link/IntermediateTupleExtensions.cs b/src/WixToolset.Core/Link/IntermediateTupleExtensions.cs new file mode 100644 index 00000000..c4c12e81 --- /dev/null +++ b/src/WixToolset.Core/Link/IntermediateTupleExtensions.cs | |||
@@ -0,0 +1,26 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | namespace WixToolset.Core.Link | ||
4 | { | ||
5 | using WixToolset.Data; | ||
6 | |||
7 | internal static class IntermediateTupleExtensions | ||
8 | { | ||
9 | public static bool IsIdentical(this IntermediateTuple first, IntermediateTuple second) | ||
10 | { | ||
11 | var identical = (first.Definition.Type == second.Definition.Type && | ||
12 | first.Definition.Name == second.Definition.Name && | ||
13 | first.Definition.FieldDefinitions.Length == second.Definition.FieldDefinitions.Length); | ||
14 | |||
15 | for (int i = 0; identical && i < first.Definition.FieldDefinitions.Length; ++i) | ||
16 | { | ||
17 | var firstField = first[i]; | ||
18 | var secondField = second[i]; | ||
19 | |||
20 | identical = (firstField.AsString() == secondField.AsString()); | ||
21 | } | ||
22 | |||
23 | return identical; | ||
24 | } | ||
25 | } | ||
26 | } | ||
diff --git a/src/WixToolset.Core/Link/ReportConflictingSymbolsCommand.cs b/src/WixToolset.Core/Link/ReportConflictingSymbolsCommand.cs index 39c3a5c2..ac0dd7ec 100644 --- a/src/WixToolset.Core/Link/ReportConflictingSymbolsCommand.cs +++ b/src/WixToolset.Core/Link/ReportConflictingSymbolsCommand.cs | |||
@@ -6,17 +6,18 @@ namespace WixToolset.Link | |||
6 | using System.Linq; | 6 | using System.Linq; |
7 | using WixToolset.Data; | 7 | using WixToolset.Data; |
8 | 8 | ||
9 | public class ReportConflictingSymbolsCommand : ICommand | 9 | public class ReportConflictingSymbolsCommand |
10 | { | 10 | { |
11 | private IEnumerable<Symbol> possibleConflicts; | 11 | public ReportConflictingSymbolsCommand(IEnumerable<Symbol> possibleConflicts, IEnumerable<IntermediateSection> resolvedSections) |
12 | private IEnumerable<Section> resolvedSections; | ||
13 | |||
14 | public ReportConflictingSymbolsCommand(IEnumerable<Symbol> possibleConflicts, IEnumerable<Section> resolvedSections) | ||
15 | { | 12 | { |
16 | this.possibleConflicts = possibleConflicts; | 13 | this.PossibleConflicts = possibleConflicts; |
17 | this.resolvedSections = resolvedSections; | 14 | this.ResolvedSections = resolvedSections; |
18 | } | 15 | } |
19 | 16 | ||
17 | private IEnumerable<Symbol> PossibleConflicts { get; } | ||
18 | |||
19 | private IEnumerable<IntermediateSection> ResolvedSections { get; } | ||
20 | |||
20 | public void Execute() | 21 | public void Execute() |
21 | { | 22 | { |
22 | // Do a quick check if there are any possibly conflicting symbols that don't come from tables that allow | 23 | // Do a quick check if there are any possibly conflicting symbols that don't come from tables that allow |
@@ -25,10 +26,11 @@ namespace WixToolset.Link | |||
25 | // symbols are in sections we actually referenced. From the resulting set, show an error for each duplicate | 26 | // symbols are in sections we actually referenced. From the resulting set, show an error for each duplicate |
26 | // (aka: conflicting) symbol. This should catch any rows with colliding primary keys (since symbols are based | 27 | // (aka: conflicting) symbol. This should catch any rows with colliding primary keys (since symbols are based |
27 | // on the primary keys of rows). | 28 | // on the primary keys of rows). |
28 | List<Symbol> illegalDuplicates = possibleConflicts.Where(s => "WixAction" != s.Row.Table.Name && "WixVariable" != s.Row.Table.Name).ToList(); | 29 | var illegalDuplicates = this.PossibleConflicts.Where(s => s.Row.Definition.Type != TupleDefinitionType.WixAction && s.Row.Definition.Type != TupleDefinitionType.WixVariable).ToList(); |
29 | if (0 < illegalDuplicates.Count) | 30 | if (0 < illegalDuplicates.Count) |
30 | { | 31 | { |
31 | HashSet<Section> referencedSections = new HashSet<Section>(resolvedSections); | 32 | var referencedSections = new HashSet<IntermediateSection>(this.ResolvedSections); |
33 | |||
32 | foreach (Symbol referencedDuplicateSymbol in illegalDuplicates.Where(s => referencedSections.Contains(s.Section))) | 34 | foreach (Symbol referencedDuplicateSymbol in illegalDuplicates.Where(s => referencedSections.Contains(s.Section))) |
33 | { | 35 | { |
34 | List<Symbol> actuallyReferencedDuplicateSymbols = referencedDuplicateSymbol.PossiblyConflictingSymbols.Where(s => referencedSections.Contains(s.Section)).ToList(); | 36 | List<Symbol> actuallyReferencedDuplicateSymbols = referencedDuplicateSymbol.PossiblyConflictingSymbols.Where(s => referencedSections.Contains(s.Section)).ToList(); |
diff --git a/src/WixToolset.Core/Link/ResolveReferencesCommand.cs b/src/WixToolset.Core/Link/ResolveReferencesCommand.cs index 5a985f3f..9c3b2765 100644 --- a/src/WixToolset.Core/Link/ResolveReferencesCommand.cs +++ b/src/WixToolset.Core/Link/ResolveReferencesCommand.cs | |||
@@ -4,22 +4,21 @@ namespace WixToolset.Link | |||
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
7 | using System.Diagnostics; | ||
8 | using System.Linq; | 7 | using System.Linq; |
9 | using WixToolset.Data; | 8 | using WixToolset.Data; |
10 | using WixToolset.Data.Rows; | 9 | using WixToolset.Data.Tuples; |
11 | 10 | ||
12 | /// <summary> | 11 | /// <summary> |
13 | /// Resolves all the simple references in a section. | 12 | /// Resolves all the simple references in a section. |
14 | /// </summary> | 13 | /// </summary> |
15 | internal class ResolveReferencesCommand : ICommand | 14 | internal class ResolveReferencesCommand : ICommand |
16 | { | 15 | { |
17 | private Section entrySection; | 16 | private IntermediateSection entrySection; |
18 | private IDictionary<string, Symbol> symbols; | 17 | private IDictionary<string, Symbol> symbols; |
19 | private HashSet<Symbol> referencedSymbols; | 18 | private HashSet<Symbol> referencedSymbols; |
20 | private HashSet<Section> resolvedSections; | 19 | private HashSet<IntermediateSection> resolvedSections; |
21 | 20 | ||
22 | public ResolveReferencesCommand(Section entrySection, IDictionary<string, Symbol> symbols) | 21 | public ResolveReferencesCommand(IntermediateSection entrySection, IDictionary<string, Symbol> symbols) |
23 | { | 22 | { |
24 | this.entrySection = entrySection; | 23 | this.entrySection = entrySection; |
25 | this.symbols = symbols; | 24 | this.symbols = symbols; |
@@ -29,14 +28,14 @@ namespace WixToolset.Link | |||
29 | 28 | ||
30 | public IEnumerable<Symbol> ReferencedSymbols { get { return this.referencedSymbols; } } | 29 | public IEnumerable<Symbol> ReferencedSymbols { get { return this.referencedSymbols; } } |
31 | 30 | ||
32 | public IEnumerable<Section> ResolvedSections { get { return this.resolvedSections; } } | 31 | public IEnumerable<IntermediateSection> ResolvedSections { get { return this.resolvedSections; } } |
33 | 32 | ||
34 | /// <summary> | 33 | /// <summary> |
35 | /// Resolves all the simple references in a section. | 34 | /// Resolves all the simple references in a section. |
36 | /// </summary> | 35 | /// </summary> |
37 | public void Execute() | 36 | public void Execute() |
38 | { | 37 | { |
39 | this.resolvedSections = new HashSet<Section>(); | 38 | this.resolvedSections = new HashSet<IntermediateSection>(); |
40 | this.referencedSymbols = new HashSet<Symbol>(); | 39 | this.referencedSymbols = new HashSet<Symbol>(); |
41 | 40 | ||
42 | this.RecursivelyResolveReferences(this.entrySection); | 41 | this.RecursivelyResolveReferences(this.entrySection); |
@@ -47,7 +46,7 @@ namespace WixToolset.Link | |||
47 | /// </summary> | 46 | /// </summary> |
48 | /// <param name="section">Section with references to resolve.</param> | 47 | /// <param name="section">Section with references to resolve.</param> |
49 | /// <remarks>Note: recursive function.</remarks> | 48 | /// <remarks>Note: recursive function.</remarks> |
50 | private void RecursivelyResolveReferences(Section section) | 49 | private void RecursivelyResolveReferences(IntermediateSection section) |
51 | { | 50 | { |
52 | // If we already resolved this section, move on to the next. | 51 | // If we already resolved this section, move on to the next. |
53 | if (!this.resolvedSections.Add(section)) | 52 | if (!this.resolvedSections.Add(section)) |
@@ -59,59 +58,53 @@ namespace WixToolset.Link | |||
59 | // symbols provided. Then recursively call this method to process the | 58 | // symbols provided. Then recursively call this method to process the |
60 | // located symbol's section. All in all this is a very simple depth-first | 59 | // located symbol's section. All in all this is a very simple depth-first |
61 | // search of the references per-section. | 60 | // search of the references per-section. |
62 | Table wixSimpleReferenceTable; | 61 | foreach (var wixSimpleReferenceRow in section.Tuples.OfType<WixSimpleReferenceTuple>()) |
63 | if (section.Tables.TryGetTable("WixSimpleReference", out wixSimpleReferenceTable)) | ||
64 | { | 62 | { |
65 | foreach (WixSimpleReferenceRow wixSimpleReferenceRow in wixSimpleReferenceTable.Rows) | 63 | // If we're building a Merge Module, ignore all references to the Media table |
64 | // because Merge Modules don't have Media tables. | ||
65 | if (this.BuildingMergeModule && wixSimpleReferenceRow.Definition.Type == TupleDefinitionType.Media) | ||
66 | { | 66 | { |
67 | Debug.Assert(wixSimpleReferenceRow.Section == section); | 67 | continue; |
68 | } | ||
68 | 69 | ||
69 | // If we're building a Merge Module, ignore all references to the Media table | 70 | if (!this.symbols.TryGetValue(wixSimpleReferenceRow.SymbolicName, out var symbol)) |
70 | // because Merge Modules don't have Media tables. | 71 | { |
71 | if (this.BuildingMergeModule && "Media" == wixSimpleReferenceRow.TableName) | 72 | Messaging.Instance.OnMessage(WixErrors.UnresolvedReference(wixSimpleReferenceRow.SourceLineNumbers, wixSimpleReferenceRow.SymbolicName)); |
73 | } | ||
74 | else // see if the symbol (and any of its duplicates) are appropriately accessible. | ||
75 | { | ||
76 | IList<Symbol> accessible = DetermineAccessibleSymbols(section, symbol); | ||
77 | if (!accessible.Any()) | ||
72 | { | 78 | { |
73 | continue; | 79 | Messaging.Instance.OnMessage(WixErrors.UnresolvedReference(wixSimpleReferenceRow.SourceLineNumbers, wixSimpleReferenceRow.SymbolicName, symbol.Access)); |
74 | } | 80 | } |
75 | 81 | else if (1 == accessible.Count) | |
76 | Symbol symbol; | ||
77 | if (!this.symbols.TryGetValue(wixSimpleReferenceRow.SymbolicName, out symbol)) | ||
78 | { | 82 | { |
79 | Messaging.Instance.OnMessage(WixErrors.UnresolvedReference(wixSimpleReferenceRow.SourceLineNumbers, wixSimpleReferenceRow.SymbolicName)); | 83 | var accessibleSymbol = accessible[0]; |
84 | this.referencedSymbols.Add(accessibleSymbol); | ||
85 | |||
86 | if (null != accessibleSymbol.Section) | ||
87 | { | ||
88 | RecursivelyResolveReferences(accessibleSymbol.Section); | ||
89 | } | ||
80 | } | 90 | } |
81 | else // see if the symbol (and any of its duplicates) are appropriately accessible. | 91 | else // display errors for the duplicate symbols. |
82 | { | 92 | { |
83 | IList<Symbol> accessible = DetermineAccessibleSymbols(section, symbol); | 93 | var accessibleSymbol = accessible[0]; |
84 | if (!accessible.Any()) | 94 | var referencingSourceLineNumber = wixSimpleReferenceRow.SourceLineNumbers.ToString(); |
95 | |||
96 | if (String.IsNullOrEmpty(referencingSourceLineNumber)) | ||
85 | { | 97 | { |
86 | Messaging.Instance.OnMessage(WixErrors.UnresolvedReference(wixSimpleReferenceRow.SourceLineNumbers, wixSimpleReferenceRow.SymbolicName, symbol.Access)); | 98 | Messaging.Instance.OnMessage(WixErrors.DuplicateSymbol(accessibleSymbol.Row.SourceLineNumbers, accessibleSymbol.Name)); |
87 | } | 99 | } |
88 | else if (1 == accessible.Count) | 100 | else |
89 | { | 101 | { |
90 | Symbol accessibleSymbol = accessible[0]; | 102 | Messaging.Instance.OnMessage(WixErrors.DuplicateSymbol(accessibleSymbol.Row.SourceLineNumbers, accessibleSymbol.Name, referencingSourceLineNumber)); |
91 | this.referencedSymbols.Add(accessibleSymbol); | ||
92 | |||
93 | if (null != accessibleSymbol.Section) | ||
94 | { | ||
95 | RecursivelyResolveReferences(accessibleSymbol.Section); | ||
96 | } | ||
97 | } | 103 | } |
98 | else // display errors for the duplicate symbols. | 104 | |
105 | foreach (Symbol accessibleDuplicate in accessible.Skip(1)) | ||
99 | { | 106 | { |
100 | Symbol accessibleSymbol = accessible[0]; | 107 | Messaging.Instance.OnMessage(WixErrors.DuplicateSymbol2(accessibleDuplicate.Row.SourceLineNumbers)); |
101 | string referencingSourceLineNumber = wixSimpleReferenceRow.SourceLineNumbers.ToString(); | ||
102 | if (String.IsNullOrEmpty(referencingSourceLineNumber)) | ||
103 | { | ||
104 | Messaging.Instance.OnMessage(WixErrors.DuplicateSymbol(accessibleSymbol.Row.SourceLineNumbers, accessibleSymbol.Name)); | ||
105 | } | ||
106 | else | ||
107 | { | ||
108 | Messaging.Instance.OnMessage(WixErrors.DuplicateSymbol(accessibleSymbol.Row.SourceLineNumbers, accessibleSymbol.Name, referencingSourceLineNumber)); | ||
109 | } | ||
110 | |||
111 | foreach (Symbol accessibleDuplicate in accessible.Skip(1)) | ||
112 | { | ||
113 | Messaging.Instance.OnMessage(WixErrors.DuplicateSymbol2(accessibleDuplicate.Row.SourceLineNumbers)); | ||
114 | } | ||
115 | } | 108 | } |
116 | } | 109 | } |
117 | } | 110 | } |
@@ -124,7 +117,7 @@ namespace WixToolset.Link | |||
124 | /// <param name="referencingSection">Section referencing the symbol.</param> | 117 | /// <param name="referencingSection">Section referencing the symbol.</param> |
125 | /// <param name="symbol">Symbol being referenced.</param> | 118 | /// <param name="symbol">Symbol being referenced.</param> |
126 | /// <returns>List of symbols accessible by referencing section.</returns> | 119 | /// <returns>List of symbols accessible by referencing section.</returns> |
127 | private IList<Symbol> DetermineAccessibleSymbols(Section referencingSection, Symbol symbol) | 120 | private IList<Symbol> DetermineAccessibleSymbols(IntermediateSection referencingSection, Symbol symbol) |
128 | { | 121 | { |
129 | List<Symbol> symbols = new List<Symbol>(); | 122 | List<Symbol> symbols = new List<Symbol>(); |
130 | 123 | ||
@@ -158,20 +151,20 @@ namespace WixToolset.Link | |||
158 | /// <param name="referencingSection">Section referencing the symbol.</param> | 151 | /// <param name="referencingSection">Section referencing the symbol.</param> |
159 | /// <param name="symbol">Symbol being referenced.</param> | 152 | /// <param name="symbol">Symbol being referenced.</param> |
160 | /// <returns>True if symbol is accessible.</returns> | 153 | /// <returns>True if symbol is accessible.</returns> |
161 | private bool AccessibleSymbol(Section referencingSection, Symbol symbol) | 154 | private bool AccessibleSymbol(IntermediateSection referencingSection, Symbol symbol) |
162 | { | 155 | { |
163 | switch (symbol.Access) | 156 | switch (symbol.Access) |
164 | { | 157 | { |
165 | case AccessModifier.Public: | 158 | case AccessModifier.Public: |
166 | return true; | 159 | return true; |
167 | case AccessModifier.Internal: | 160 | case AccessModifier.Internal: |
168 | return symbol.Row.Section.IntermediateId.Equals(referencingSection.IntermediateId) || (null != symbol.Row.Section.LibraryId && symbol.Row.Section.LibraryId.Equals(referencingSection.LibraryId)); | 161 | return symbol.Section.CompilationId.Equals(referencingSection.CompilationId) || (null != symbol.Section.LibraryId && symbol.Section.LibraryId.Equals(referencingSection.LibraryId)); |
169 | case AccessModifier.Protected: | 162 | case AccessModifier.Protected: |
170 | return symbol.Row.Section.IntermediateId.Equals(referencingSection.IntermediateId); | 163 | return symbol.Section.CompilationId.Equals(referencingSection.CompilationId); |
171 | case AccessModifier.Private: | 164 | case AccessModifier.Private: |
172 | return referencingSection == symbol.Section; | 165 | return referencingSection == symbol.Section; |
173 | default: | 166 | default: |
174 | throw new InvalidOperationException(); | 167 | throw new ArgumentOutOfRangeException(nameof(symbol.Access)); |
175 | } | 168 | } |
176 | } | 169 | } |
177 | } | 170 | } |
diff --git a/src/WixToolset.Core/Link/WixComplexReferenceTupleExtensions.cs b/src/WixToolset.Core/Link/WixComplexReferenceTupleExtensions.cs new file mode 100644 index 00000000..80cafa50 --- /dev/null +++ b/src/WixToolset.Core/Link/WixComplexReferenceTupleExtensions.cs | |||
@@ -0,0 +1,73 @@ | |||
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.Link | ||
4 | { | ||
5 | using System; | ||
6 | using WixToolset.Data.Tuples; | ||
7 | |||
8 | internal static class WixComplexReferenceTupleExtensions | ||
9 | { | ||
10 | /// <summary> | ||
11 | /// Creates a shallow copy of the ComplexReference. | ||
12 | /// </summary> | ||
13 | /// <returns>A shallow copy of the ComplexReference.</returns> | ||
14 | public static WixComplexReferenceTuple Clone(this WixComplexReferenceTuple source) | ||
15 | { | ||
16 | var clone = new WixComplexReferenceTuple(source.SourceLineNumbers, source.Id); | ||
17 | clone.ParentType = source.ParentType; | ||
18 | clone.Parent = source.Parent; | ||
19 | clone.ParentLanguage = source.ParentLanguage; | ||
20 | clone.ChildType = source.ChildType; | ||
21 | clone.Child = source.Child; | ||
22 | clone.IsPrimary = source.IsPrimary; | ||
23 | |||
24 | return clone; | ||
25 | } | ||
26 | |||
27 | /// <summary> | ||
28 | /// Compares two complex references without considering the primary bit. | ||
29 | /// </summary> | ||
30 | /// <param name="obj">Complex reference to compare to.</param> | ||
31 | /// <returns>Zero if the objects are equivalent, negative number if the provided object is less, positive if greater.</returns> | ||
32 | public static int CompareToWithoutConsideringPrimary(this WixComplexReferenceTuple tuple, WixComplexReferenceTuple other) | ||
33 | { | ||
34 | var comparison = tuple.ChildType - other.ChildType; | ||
35 | if (0 == comparison) | ||
36 | { | ||
37 | comparison = String.Compare(tuple.Child, other.Child, StringComparison.Ordinal); | ||
38 | if (0 == comparison) | ||
39 | { | ||
40 | comparison = tuple.ParentType - other.ParentType; | ||
41 | if (0 == comparison) | ||
42 | { | ||
43 | string thisParentLanguage = null == tuple.ParentLanguage ? String.Empty : tuple.ParentLanguage; | ||
44 | string otherParentLanguage = null == other.ParentLanguage ? String.Empty : other.ParentLanguage; | ||
45 | comparison = String.Compare(thisParentLanguage, otherParentLanguage, StringComparison.Ordinal); | ||
46 | if (0 == comparison) | ||
47 | { | ||
48 | comparison = String.Compare(tuple.Parent, other.Parent, StringComparison.Ordinal); | ||
49 | } | ||
50 | } | ||
51 | } | ||
52 | } | ||
53 | |||
54 | return comparison; | ||
55 | } | ||
56 | |||
57 | /// <summary> | ||
58 | /// Changes all of the parent references to point to the passed in parent reference. | ||
59 | /// </summary> | ||
60 | /// <param name="parent">New parent complex reference.</param> | ||
61 | public static void Reparent(this WixComplexReferenceTuple tuple, WixComplexReferenceTuple parent) | ||
62 | { | ||
63 | tuple.Parent = parent.Parent; | ||
64 | tuple.ParentLanguage = parent.ParentLanguage; | ||
65 | tuple.ParentType = parent.ParentType; | ||
66 | |||
67 | if (!tuple.IsPrimary) | ||
68 | { | ||
69 | tuple.IsPrimary = parent.IsPrimary; | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | } | ||
diff --git a/src/WixToolset.Core/Link/WixGroupingOrdering.cs b/src/WixToolset.Core/Link/WixGroupingOrdering.cs index fc0ce43b..4dd1596c 100644 --- a/src/WixToolset.Core/Link/WixGroupingOrdering.cs +++ b/src/WixToolset.Core/Link/WixGroupingOrdering.cs | |||
@@ -12,13 +12,13 @@ namespace WixToolset.Link | |||
12 | using System.Text; | 12 | using System.Text; |
13 | using WixToolset.Extensibility; | 13 | using WixToolset.Extensibility; |
14 | using WixToolset.Data; | 14 | using WixToolset.Data; |
15 | using WixToolset.Data.Tuples; | ||
15 | 16 | ||
16 | /// <summary> | 17 | /// <summary> |
17 | /// Grouping and Ordering class of the WiX toolset. | 18 | /// Grouping and Ordering class of the WiX toolset. |
18 | /// </summary> | 19 | /// </summary> |
19 | internal sealed class WixGroupingOrdering : IMessageHandler | 20 | internal sealed class WixGroupingOrdering : IMessageHandler |
20 | { | 21 | { |
21 | private Output output; | ||
22 | private IMessageHandler messageHandler; | 22 | private IMessageHandler messageHandler; |
23 | private List<string> groupTypes; | 23 | private List<string> groupTypes; |
24 | private List<string> itemTypes; | 24 | private List<string> itemTypes; |
@@ -34,9 +34,9 @@ namespace WixToolset.Link | |||
34 | /// <param name="messageHandler">Handler for any error messages.</param> | 34 | /// <param name="messageHandler">Handler for any error messages.</param> |
35 | /// <param name="groupTypes">Group types to include.</param> | 35 | /// <param name="groupTypes">Group types to include.</param> |
36 | /// <param name="itemTypes">Item types to include.</param> | 36 | /// <param name="itemTypes">Item types to include.</param> |
37 | public WixGroupingOrdering(Output output, IMessageHandler messageHandler) | 37 | public WixGroupingOrdering(IntermediateSection entrySections, IMessageHandler messageHandler) |
38 | { | 38 | { |
39 | this.output = output; | 39 | this.EntrySection = entrySections; |
40 | this.messageHandler = messageHandler; | 40 | this.messageHandler = messageHandler; |
41 | 41 | ||
42 | this.rowsUsed = new List<int>(); | 42 | this.rowsUsed = new List<int>(); |
@@ -44,6 +44,8 @@ namespace WixToolset.Link | |||
44 | this.encounteredError = false; | 44 | this.encounteredError = false; |
45 | } | 45 | } |
46 | 46 | ||
47 | private IntermediateSection EntrySection { get; } | ||
48 | |||
47 | /// <summary> | 49 | /// <summary> |
48 | /// Switches a WixGroupingOrdering object to operate on a new set of groups/items. | 50 | /// Switches a WixGroupingOrdering object to operate on a new set of groups/items. |
49 | /// </summary> | 51 | /// </summary> |
@@ -91,8 +93,7 @@ namespace WixToolset.Link | |||
91 | { | 93 | { |
92 | Debug.Assert(this.groupTypes.Contains(parentType)); | 94 | Debug.Assert(this.groupTypes.Contains(parentType)); |
93 | 95 | ||
94 | List<Item> orderedItems; | 96 | this.CreateOrderedList(parentType, parentId, out var orderedItems); |
95 | this.CreateOrderedList(parentType, parentId, out orderedItems); | ||
96 | if (this.encounteredError) | 97 | if (this.encounteredError) |
97 | { | 98 | { |
98 | return; | 99 | return; |
@@ -170,15 +171,16 @@ namespace WixToolset.Link | |||
170 | /// </summary> | 171 | /// </summary> |
171 | public void RemoveUsedGroupRows() | 172 | public void RemoveUsedGroupRows() |
172 | { | 173 | { |
173 | List<int> sortedIndexes = this.rowsUsed.Distinct().OrderByDescending(i => i).ToList(); | 174 | var sortedIndexes = this.rowsUsed.Distinct().OrderByDescending(i => i).ToList(); |
174 | 175 | ||
175 | Table wixGroupTable = this.output.Tables["WixGroup"]; | 176 | //Table wixGroupTable = this.output.Tables["WixGroup"]; |
176 | Debug.Assert(null != wixGroupTable); | 177 | //Debug.Assert(null != wixGroupTable); |
177 | Debug.Assert(sortedIndexes[0] < wixGroupTable.Rows.Count); | 178 | //Debug.Assert(sortedIndexes[0] < wixGroupTable.Rows.Count); |
178 | 179 | ||
179 | foreach (int rowIndex in sortedIndexes) | 180 | foreach (int rowIndex in sortedIndexes) |
180 | { | 181 | { |
181 | wixGroupTable.Rows.RemoveAt(rowIndex); | 182 | //wixGroupTable.Rows.RemoveAt(rowIndex); |
183 | this.EntrySection.Tuples.RemoveAt(rowIndex); | ||
182 | } | 184 | } |
183 | } | 185 | } |
184 | 186 | ||
@@ -194,16 +196,15 @@ namespace WixToolset.Link | |||
194 | // does WiX (although they do, currently). We probably want to "upgrade" this to a new | 196 | // does WiX (although they do, currently). We probably want to "upgrade" this to a new |
195 | // table that includes a sequence number, and then change the code that uses ordered | 197 | // table that includes a sequence number, and then change the code that uses ordered |
196 | // groups to read from that table instead. | 198 | // groups to read from that table instead. |
197 | Table wixGroupTable = this.output.Tables["WixGroup"]; | ||
198 | Debug.Assert(null != wixGroupTable); | ||
199 | |||
200 | foreach (Item item in orderedItems) | 199 | foreach (Item item in orderedItems) |
201 | { | 200 | { |
202 | Row row = wixGroupTable.CreateRow(item.Row.SourceLineNumbers); | 201 | var row = new WixGroupTuple(item.Row.SourceLineNumbers); |
203 | row[0] = parentId; | 202 | row.ParentId = parentId; |
204 | row[1] = parentType; | 203 | row.ParentType = (ComplexReferenceParentType)Enum.Parse(typeof(ComplexReferenceParentType), parentType); |
205 | row[2] = item.Id; | 204 | row.ChildId = item.Id; |
206 | row[3] = item.Type; | 205 | row.ChildType = (ComplexReferenceChildType)Enum.Parse(typeof(ComplexReferenceChildType), item.Type); |
206 | |||
207 | this.EntrySection.Tuples.Add(row); | ||
207 | } | 208 | } |
208 | } | 209 | } |
209 | 210 | ||
@@ -254,47 +255,47 @@ namespace WixToolset.Link | |||
254 | /// </summary> | 255 | /// </summary> |
255 | private void LoadGroups() | 256 | private void LoadGroups() |
256 | { | 257 | { |
257 | Table wixGroupTable = this.output.Tables["WixGroup"]; | 258 | //Table wixGroupTable = this.output.Tables["WixGroup"]; |
258 | if (null == wixGroupTable || 0 == wixGroupTable.Rows.Count) | 259 | //if (null == wixGroupTable || 0 == wixGroupTable.Rows.Count) |
259 | { | 260 | //{ |
260 | // TODO: Change message name to make it *not* Bundle specific? | 261 | // // TODO: Change message name to make it *not* Bundle specific? |
261 | this.OnMessage(WixErrors.MissingBundleInformation("WixGroup")); | 262 | // this.OnMessage(WixErrors.MissingBundleInformation("WixGroup")); |
262 | } | 263 | //} |
263 | 264 | ||
264 | // Collect all of the groups | 265 | // Collect all of the groups |
265 | for (int rowIndex = 0; rowIndex < wixGroupTable.Rows.Count; ++rowIndex) | 266 | for (int rowIndex = 0; rowIndex < this.EntrySection.Tuples.Count; ++rowIndex) |
266 | { | 267 | { |
267 | Row row = wixGroupTable.Rows[rowIndex]; | 268 | if (this.EntrySection.Tuples[rowIndex] is WixGroupTuple row) |
268 | string rowParentName = (string)row[0]; | ||
269 | string rowParentType = (string)row[1]; | ||
270 | string rowChildName = (string)row[2]; | ||
271 | string rowChildType = (string)row[3]; | ||
272 | |||
273 | // If this row specifies a parent or child type that's not in our | ||
274 | // lists, we assume it's not a row that we're concerned about. | ||
275 | if (!this.groupTypes.Contains(rowParentType) || | ||
276 | !this.itemTypes.Contains(rowChildType)) | ||
277 | { | 269 | { |
278 | continue; | 270 | var rowParentName = row.ParentId; |
279 | } | 271 | var rowParentType = row.ParentType.ToString(); |
272 | var rowChildName = row.ChildId; | ||
273 | var rowChildType = row.ChildType.ToString(); | ||
274 | |||
275 | // If this row specifies a parent or child type that's not in our | ||
276 | // lists, we assume it's not a row that we're concerned about. | ||
277 | if (!this.groupTypes.Contains(rowParentType) || | ||
278 | !this.itemTypes.Contains(rowChildType)) | ||
279 | { | ||
280 | continue; | ||
281 | } | ||
280 | 282 | ||
281 | this.rowsUsed.Add(rowIndex); | 283 | this.rowsUsed.Add(rowIndex); |
282 | 284 | ||
283 | Item parentItem; | 285 | if (!this.items.TryGetValue(rowParentType, rowParentName, out var parentItem)) |
284 | if (!this.items.TryGetValue(rowParentType, rowParentName, out parentItem)) | 286 | { |
285 | { | 287 | parentItem = new Item(row, rowParentType, rowParentName); |
286 | parentItem = new Item(row, rowParentType, rowParentName); | 288 | this.items.Add(parentItem); |
287 | this.items.Add(parentItem); | 289 | } |
288 | } | ||
289 | 290 | ||
290 | Item childItem; | 291 | if (!this.items.TryGetValue(rowChildType, rowChildName, out var childItem)) |
291 | if (!this.items.TryGetValue(rowChildType, rowChildName, out childItem)) | 292 | { |
292 | { | 293 | childItem = new Item(row, rowChildType, rowChildName); |
293 | childItem = new Item(row, rowChildType, rowChildName); | 294 | this.items.Add(childItem); |
294 | this.items.Add(childItem); | 295 | } |
295 | } | ||
296 | 296 | ||
297 | parentItem.ChildItems.Add(childItem); | 297 | parentItem.ChildItems.Add(childItem); |
298 | } | ||
298 | } | 299 | } |
299 | } | 300 | } |
300 | 301 | ||
@@ -374,19 +375,19 @@ namespace WixToolset.Link | |||
374 | /// </summary> | 375 | /// </summary> |
375 | private void LoadOrdering() | 376 | private void LoadOrdering() |
376 | { | 377 | { |
377 | Table wixOrderingTable = output.Tables["WixOrdering"]; | 378 | //Table wixOrderingTable = output.Tables["WixOrdering"]; |
378 | if (null == wixOrderingTable || 0 == wixOrderingTable.Rows.Count) | 379 | //if (null == wixOrderingTable || 0 == wixOrderingTable.Rows.Count) |
379 | { | 380 | //{ |
380 | // TODO: Do we need a message here? | 381 | // // TODO: Do we need a message here? |
381 | return; | 382 | // return; |
382 | } | 383 | //} |
383 | 384 | ||
384 | foreach (Row row in wixOrderingTable.Rows) | 385 | foreach (var row in this.EntrySection.Tuples.OfType<WixOrderingTuple>()) |
385 | { | 386 | { |
386 | string rowItemType = (string)row[0]; | 387 | var rowItemType = row.ItemType; |
387 | string rowItemName = (string)row[1]; | 388 | var rowItemName = row.ItemId_; |
388 | string rowDependsOnType = (string)row[2]; | 389 | var rowDependsOnType = row.DependsOnType; |
389 | string rowDependsOnName = (string)row[3]; | 390 | var rowDependsOnName = row.DependsOnId_; |
390 | 391 | ||
391 | // If this row specifies some other (unknown) type in either | 392 | // If this row specifies some other (unknown) type in either |
392 | // position, we assume it's not a row that we're concerned about. | 393 | // position, we assume it's not a row that we're concerned about. |
@@ -397,15 +398,12 @@ namespace WixToolset.Link | |||
397 | continue; | 398 | continue; |
398 | } | 399 | } |
399 | 400 | ||
400 | Item item = null; | 401 | if (!this.items.TryGetValue(rowItemType, rowItemName, out var item)) |
401 | Item dependsOn = null; | ||
402 | |||
403 | if (!this.items.TryGetValue(rowItemType, rowItemName, out item)) | ||
404 | { | 402 | { |
405 | this.OnMessage(WixErrors.IdentifierNotFound(rowItemType, rowItemName)); | 403 | this.OnMessage(WixErrors.IdentifierNotFound(rowItemType, rowItemName)); |
406 | } | 404 | } |
407 | 405 | ||
408 | if (!this.items.TryGetValue(rowDependsOnType, rowDependsOnName, out dependsOn)) | 406 | if (!this.items.TryGetValue(rowDependsOnType, rowDependsOnName, out var dependsOn)) |
409 | { | 407 | { |
410 | this.OnMessage(WixErrors.IdentifierNotFound(rowDependsOnType, rowDependsOnName)); | 408 | this.OnMessage(WixErrors.IdentifierNotFound(rowDependsOnType, rowDependsOnName)); |
411 | } | 409 | } |
@@ -540,7 +538,7 @@ namespace WixToolset.Link | |||
540 | private ItemCollection beforeItems; // for checking for circular references | 538 | private ItemCollection beforeItems; // for checking for circular references |
541 | private bool flattenedAfterItems; | 539 | private bool flattenedAfterItems; |
542 | 540 | ||
543 | public Item(Row row, string type, string id) | 541 | public Item(IntermediateTuple row, string type, string id) |
544 | { | 542 | { |
545 | this.Row = row; | 543 | this.Row = row; |
546 | this.Type = type; | 544 | this.Type = type; |
@@ -553,7 +551,7 @@ namespace WixToolset.Link | |||
553 | flattenedAfterItems = false; | 551 | flattenedAfterItems = false; |
554 | } | 552 | } |
555 | 553 | ||
556 | public Row Row { get; private set; } | 554 | public IntermediateTuple Row { get; private set; } |
557 | public string Type { get; private set; } | 555 | public string Type { get; private set; } |
558 | public string Id { get; private set; } | 556 | public string Id { get; private set; } |
559 | public string Key { get; private set; } | 557 | public string Key { get; private set; } |
@@ -718,7 +716,7 @@ namespace WixToolset.Link | |||
718 | return -1; | 716 | return -1; |
719 | } | 717 | } |
720 | 718 | ||
721 | return string.CompareOrdinal(x.Id, y.Id); | 719 | return String.CompareOrdinal(x.Id, y.Id); |
722 | } | 720 | } |
723 | } | 721 | } |
724 | } | 722 | } |