aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs')
-rw-r--r--src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs109
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
3namespace 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}