aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core/Link/ResolveReferencesCommand.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core/Link/ResolveReferencesCommand.cs')
-rw-r--r--src/WixToolset.Core/Link/ResolveReferencesCommand.cs99
1 files changed, 46 insertions, 53 deletions
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 }