/// <summary> /// Adds a duplicate symbol that is redundant. /// </summary> /// <param name="symbolWithSection">Symbol with section that is redundant of this symbol.</param> public void AddRedundant(SymbolWithSection symbolWithSection) { if (null == this.redundants) { this.redundants = new HashSet <SymbolWithSection>(); } this.redundants.Add(symbolWithSection); }
/// <summary> /// Adds a duplicate symbol with sections that is a possible conflict. /// </summary> /// <param name="symbolWithSection">Symbol with section that is a possible conflict of this symbol.</param> public void AddPossibleConflict(SymbolWithSection symbolWithSection) { if (null == this.possibleConflicts) { this.possibleConflicts = new HashSet <SymbolWithSection>(); } this.possibleConflicts.Add(symbolWithSection); }
/// <summary> /// Determine if a single symbol is accessible by the referencing section. /// </summary> /// <param name="referencingSection">Section referencing the symbol.</param> /// <param name="symbolWithSection">Symbol being referenced.</param> /// <returns>True if symbol is accessible.</returns> private bool AccessibleSymbol(IntermediateSection referencingSection, SymbolWithSection symbolWithSection) { switch (symbolWithSection.Access) { case AccessModifier.Public: return(true); case AccessModifier.Internal: return(symbolWithSection.Section.CompilationId.Equals(referencingSection.CompilationId) || (null != symbolWithSection.Section.LibraryId && symbolWithSection.Section.LibraryId.Equals(referencingSection.LibraryId))); case AccessModifier.Protected: return(symbolWithSection.Section.CompilationId.Equals(referencingSection.CompilationId)); case AccessModifier.Private: return(referencingSection == symbolWithSection.Section); default: throw new ArgumentOutOfRangeException(nameof(symbolWithSection.Access)); } }
/// <summary> /// Determine if a single symbol is accessible by the referencing section. /// </summary> /// <param name="referencingSection">Section referencing the symbol.</param> /// <param name="symbolWithSection">Symbol being referenced.</param> /// <returns>True if symbol is accessible.</returns> private bool AccessibleSymbol(IntermediateSection referencingSection, SymbolWithSection symbolWithSection) { switch (symbolWithSection.Access) { case AccessModifier.Global: return(true); case AccessModifier.Library: return(symbolWithSection.Section.CompilationId == referencingSection.CompilationId || (null != symbolWithSection.Section.LibraryId && symbolWithSection.Section.LibraryId == referencingSection.LibraryId)); case AccessModifier.File: return(symbolWithSection.Section.CompilationId == referencingSection.CompilationId); case AccessModifier.Section: return(referencingSection == symbolWithSection.Section); default: throw new ArgumentOutOfRangeException(nameof(symbolWithSection.Access)); } }
/// <summary> /// Determine if the symbol and any of its duplicates are accessbile by referencing section. /// </summary> /// <param name="referencingSection">Section referencing the symbol.</param> /// <param name="symbolWithSection">Symbol being referenced.</param> /// <returns>List of symbols accessible by referencing section.</returns> private List <SymbolWithSection> DetermineAccessibleSymbols(IntermediateSection referencingSection, SymbolWithSection symbolWithSection) { var accessibleSymbols = new List <SymbolWithSection>(); if (this.AccessibleSymbol(referencingSection, symbolWithSection)) { accessibleSymbols.Add(symbolWithSection); } foreach (var dupe in symbolWithSection.PossiblyConflicts) { // don't count overridable WixActionSymbols var symbolAction = symbolWithSection.Symbol as WixActionSymbol; var dupeAction = dupe.Symbol as WixActionSymbol; if (symbolAction?.Overridable != dupeAction?.Overridable) { continue; } if (this.AccessibleSymbol(referencingSection, dupe)) { accessibleSymbols.Add(dupe); } } foreach (var dupe in symbolWithSection.Redundants) { if (this.AccessibleSymbol(referencingSection, dupe)) { accessibleSymbols.Add(dupe); } } return(accessibleSymbols); }
public void Execute() { var symbolsByName = new Dictionary <string, SymbolWithSection>(); var possibleConflicts = new HashSet <SymbolWithSection>(); if (!Enum.TryParse(this.ExpectedOutputType.ToString(), out SectionType expectedEntrySectionType)) { expectedEntrySectionType = SectionType.Unknown; } foreach (var section in this.Sections) { // Try to find the one and only entry section. if (SectionType.Product == section.Type || SectionType.Module == section.Type || SectionType.PatchCreation == section.Type || SectionType.Patch == section.Type || SectionType.Bundle == section.Type) { // TODO: remove this? //if (SectionType.Unknown != expectedEntrySectionType && section.Type != expectedEntrySectionType) //{ // string outputExtension = Output.GetExtension(this.ExpectedOutputType); // this.Messaging.Write(WixWarnings.UnexpectedEntrySection(section.SourceLineNumbers, section.Type.ToString(), expectedEntrySectionType.ToString(), outputExtension)); //} if (null == this.EntrySection) { this.EntrySection = section; } else { this.Messaging.Write(ErrorMessages.MultipleEntrySections(this.EntrySection.Symbols.FirstOrDefault()?.SourceLineNumbers, this.EntrySection.Id, section.Id)); this.Messaging.Write(ErrorMessages.MultipleEntrySections2(section.Symbols.FirstOrDefault()?.SourceLineNumbers)); } } // Load all the symbols from the section's tables that create symbols. foreach (var symbol in section.Symbols.Where(t => t.Id != null)) { var symbolWithSection = new SymbolWithSection(section, symbol); if (!symbolsByName.TryGetValue(symbolWithSection.Name, out var existingSymbol)) { symbolsByName.Add(symbolWithSection.Name, symbolWithSection); } else // uh-oh, duplicate symbols. { // If the duplicate symbols are both private directories, there is a chance that they // point to identical symbols. Identical directory symbols are redundant and will not cause // conflicts. if (AccessModifier.Private == existingSymbol.Access && AccessModifier.Private == symbolWithSection.Access && SymbolDefinitionType.Directory == existingSymbol.Symbol.Definition.Type && existingSymbol.Symbol.IsIdentical(symbolWithSection.Symbol)) { // Ensure identical symbol's symbol is marked redundant to ensure (should the symbol be // referenced into the final output) it will not add duplicate primary keys during // the .IDT importing. //symbol.Row.Redundant = true; - TODO: remove this existingSymbol.AddRedundant(symbolWithSection); } else { existingSymbol.AddPossibleConflict(symbolWithSection); possibleConflicts.Add(existingSymbol); } } } } this.SymbolsByName = symbolsByName; this.PossibleConflicts = possibleConflicts; }