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 | } | ||
