/// <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);
        }
Exemplo n.º 3
0
        /// <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));
            }
        }
Exemplo n.º 5
0
        /// <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);
        }
Exemplo n.º 6
0
        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;
        }