diff options
Diffstat (limited to 'src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs')
-rw-r--r-- | src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs b/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs new file mode 100644 index 00000000..effb06e4 --- /dev/null +++ b/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs | |||
@@ -0,0 +1,109 @@ | |||
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.Link | ||
4 | { | ||
5 | using System; | ||
6 | using System.Collections.Generic; | ||
7 | using System.Linq; | ||
8 | using WixToolset.Data; | ||
9 | |||
10 | internal class FindEntrySectionAndLoadSymbolsCommand : ICommand | ||
11 | { | ||
12 | private IEnumerable<Section> sections; | ||
13 | |||
14 | public FindEntrySectionAndLoadSymbolsCommand(IEnumerable<Section> sections) | ||
15 | { | ||
16 | this.sections = sections; | ||
17 | } | ||
18 | |||
19 | /// <summary> | ||
20 | /// Sets the expected entry output type, based on output file extension provided to the linker. | ||
21 | /// </summary> | ||
22 | public OutputType ExpectedOutputType { private get; set; } | ||
23 | |||
24 | /// <summary> | ||
25 | /// Gets the located entry section after the command is executed. | ||
26 | /// </summary> | ||
27 | public Section EntrySection { get; private set; } | ||
28 | |||
29 | /// <summary> | ||
30 | /// Gets the collection of loaded symbols. | ||
31 | /// </summary> | ||
32 | public IDictionary<string, Symbol> Symbols { get; private set; } | ||
33 | |||
34 | public IEnumerable<Symbol> PossiblyConflictingSymbols { get; private set; } | ||
35 | |||
36 | public void Execute() | ||
37 | { | ||
38 | Dictionary<string, Symbol> symbols = new Dictionary<string, Symbol>(); | ||
39 | HashSet<Symbol> possibleConflicts = new HashSet<Symbol>(); | ||
40 | |||
41 | SectionType expectedEntrySectionType; | ||
42 | if (!Enum.TryParse<SectionType>(this.ExpectedOutputType.ToString(), out expectedEntrySectionType)) | ||
43 | { | ||
44 | expectedEntrySectionType = SectionType.Unknown; | ||
45 | } | ||
46 | |||
47 | foreach (Section section in this.sections) | ||
48 | { | ||
49 | // 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) | ||
51 | { | ||
52 | if (SectionType.Unknown != expectedEntrySectionType && section.Type != expectedEntrySectionType) | ||
53 | { | ||
54 | string outputExtension = Output.GetExtension(this.ExpectedOutputType); | ||
55 | Messaging.Instance.OnMessage(WixWarnings.UnexpectedEntrySection(section.SourceLineNumbers, section.Type.ToString(), expectedEntrySectionType.ToString(), outputExtension)); | ||
56 | } | ||
57 | |||
58 | if (null == this.EntrySection) | ||
59 | { | ||
60 | this.EntrySection = section; | ||
61 | } | ||
62 | else | ||
63 | { | ||
64 | Messaging.Instance.OnMessage(WixErrors.MultipleEntrySections(this.EntrySection.SourceLineNumbers, this.EntrySection.Id, section.Id)); | ||
65 | Messaging.Instance.OnMessage(WixErrors.MultipleEntrySections2(section.SourceLineNumbers)); | ||
66 | } | ||
67 | } | ||
68 | |||
69 | // Load all the symbols from the section's tables that create symbols. | ||
70 | foreach (Table table in section.Tables.Where(t => t.Definition.CreateSymbols)) | ||
71 | { | ||
72 | foreach (Row row in table.Rows) | ||
73 | { | ||
74 | Symbol symbol = new Symbol(row); | ||
75 | |||
76 | Symbol 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 rows. Identical directory rows are redundant and will not cause | ||
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 | } | ||
101 | } | ||
102 | } | ||
103 | } | ||
104 | |||
105 | this.Symbols = symbols; | ||
106 | this.PossiblyConflictingSymbols = possibleConflicts; | ||
107 | } | ||
108 | } | ||
109 | } | ||