/// <summary> /// Resolves all the simple references in a section. /// </summary> /// <param name="outputType">Parent output type that will get the resolved section collection.</param> /// <param name="allSymbols">Collection of all symbols from loaded intermediates.</param> /// <param name="referencedSymbols">Collection populated during resolution of all symbols referenced during linking.</param> /// <param name="unresolvedReferences">Collection populated during resolution of all references that are left unresolved.</param> /// <param name="messageHandler">Message handler to report any duplicate symbols that may be tripped across.</param> /// <returns>The resolved sections.</returns> internal SectionCollection ResolveReferences( OutputType outputType, SymbolCollection allSymbols, StringCollection referencedSymbols, ArrayList unresolvedReferences, IMessageHandler messageHandler) { SectionCollection sections = new SectionCollection(); RecursivelyResolveReferences(this, outputType, allSymbols, sections, referencedSymbols, unresolvedReferences, messageHandler); return(sections); }
/// <summary> /// Finds the entry section and loads the symbols from an array of intermediates. /// </summary> /// <param name="allowIdenticalRows">Flag specifying whether identical rows are allowed or not.</param> /// <param name="messageHandler">Message handler object to route all errors through.</param> /// <param name="expectedOutputType">Expected entry output type, based on output file extension provided to the linker.</param> /// <param name="entrySection">Located entry section.</param> /// <param name="allSymbols">Collection of symbols loaded.</param> internal void FindEntrySectionAndLoadSymbols( bool allowIdenticalRows, IMessageHandler messageHandler, OutputType expectedOutputType, out Section entrySection, out SymbolCollection allSymbols) { entrySection = null; allSymbols = new SymbolCollection(); string outputExtension = Output.GetExtension(expectedOutputType); SectionType expectedEntrySectionType; try { expectedEntrySectionType = (SectionType)Enum.Parse(typeof(SectionType), expectedOutputType.ToString()); } catch (ArgumentException) { expectedEntrySectionType = SectionType.Unknown; } foreach (Section section in this.collection.Keys) { if (SectionType.Product == section.Type || SectionType.Module == section.Type || SectionType.PatchCreation == section.Type || SectionType.Patch == section.Type || SectionType.Bundle == section.Type) { if (SectionType.Unknown != expectedEntrySectionType && section.Type != expectedEntrySectionType) { messageHandler.OnMessage(WixWarnings.UnexpectedEntrySection(section.SourceLineNumbers, section.Type.ToString(), expectedEntrySectionType.ToString(), outputExtension)); } if (null == entrySection) { entrySection = section; } else { messageHandler.OnMessage(WixErrors.MultipleEntrySections(entrySection.SourceLineNumbers, entrySection.Id, section.Id)); messageHandler.OnMessage(WixErrors.MultipleEntrySections2(section.SourceLineNumbers)); } } foreach (Symbol symbol in section.GetSymbols(messageHandler)) { try { Symbol existingSymbol = allSymbols[symbol.Name]; if (null == existingSymbol) { allSymbols.Add(symbol); } else if (allowIdenticalRows && existingSymbol.Row.IsIdentical(symbol.Row)) { messageHandler.OnMessage(WixWarnings.IdenticalRowWarning(symbol.Row.SourceLineNumbers, existingSymbol.Name)); messageHandler.OnMessage(WixWarnings.IdenticalRowWarning2(existingSymbol.Row.SourceLineNumbers)); } else { allSymbols.AddDuplicate(symbol); } } catch (DuplicateSymbolsException) { // if there is already a duplicate symbol, just // another to the list, don't bother trying to // see if there are any identical symbols allSymbols.AddDuplicate(symbol); } } } }
/// <summary> /// Recursive helper function to resolve all references of passed in section. /// </summary> /// <param name="section">Section with references to resolve.</param> /// <param name="outputType">Parent output type that will get the resolved section collection.</param> /// <param name="allSymbols">All symbols that can be used to resolve section's references.</param> /// <param name="sections">Collection to add sections to during processing.</param> /// <param name="referencedSymbols">Collection populated during resolution of all symbols referenced during linking.</param> /// <param name="unresolvedReferences">Collection populated during resolution of all references that are left unresolved.</param> /// <param name="messageHandler">Message handler to report any duplicate symbols that may be tripped across.</param> /// <remarks>Note: recursive function.</remarks> private static void RecursivelyResolveReferences( Section section, OutputType outputType, SymbolCollection allSymbols, SectionCollection sections, StringCollection referencedSymbols, ArrayList unresolvedReferences, IMessageHandler messageHandler) { // if we already have this section bail if (sections.Contains(section)) { return; } // add the passed in section to the collection of sections sections.Add(section); // process all of the references contained in this section using the collection of // symbols provided. Then recursively call this method to process the // located symbol's section. All in all this is a very simple depth-first // search of the references per-section Table wixSimpleReferenceTable = section.Tables["WixSimpleReference"]; if (null != wixSimpleReferenceTable) { foreach (WixSimpleReferenceRow wixSimpleReferenceRow in wixSimpleReferenceTable.Rows) { // If we're building a Merge Module, ignore all references to the Media table // because Merge Modules don't have Media tables. if (OutputType.Module == outputType && "Media" == wixSimpleReferenceRow.TableName) { continue; } if ("WixAction" == wixSimpleReferenceRow.TableName) { Symbol[] symbols = allSymbols.GetSymbolsForSimpleReference(wixSimpleReferenceRow); if (0 == symbols.Length) { if (null != unresolvedReferences) { unresolvedReferences.Add(new SimpleReferenceSection(section, wixSimpleReferenceRow)); } } else { foreach (Symbol symbol in symbols) { if (null != symbol.Section) { // components are indexed in ResolveComplexReferences if (null != referencedSymbols && null != symbol.Row.TableDefinition.Name && "Component" != symbol.Row.TableDefinition.Name && !referencedSymbols.Contains(symbol.Name)) { referencedSymbols.Add(symbol.Name); } RecursivelyResolveReferences(symbol.Section, outputType, allSymbols, sections, referencedSymbols, unresolvedReferences, messageHandler); } } } } else { Symbol symbol = allSymbols.GetSymbolForSimpleReference(wixSimpleReferenceRow, messageHandler); if (null == symbol) { if (null != unresolvedReferences) { unresolvedReferences.Add(new SimpleReferenceSection(section, wixSimpleReferenceRow)); } } else { // components are indexed in ResolveComplexReferences if (null != referencedSymbols && null != symbol.Row.TableDefinition.Name && "Component" != symbol.Row.TableDefinition.Name && !referencedSymbols.Contains(symbol.Name)) { referencedSymbols.Add(symbol.Name); } RecursivelyResolveReferences(symbol.Section, outputType, allSymbols, sections, referencedSymbols, unresolvedReferences, messageHandler); } } } } }