/// <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="symbol">Symbol being referenced.</param> /// <returns>List of symbols accessible by referencing section.</returns> private IList <Symbol> DetermineAccessibleSymbols(IntermediateSection referencingSection, Symbol symbol) { List <Symbol> symbols = new List <Symbol>(); if (this.AccessibleSymbol(referencingSection, symbol)) { symbols.Add(symbol); } foreach (Symbol dupe in symbol.PossiblyConflictingSymbols) { // don't count overridable WixActionTuples WixActionTuple symbolAction = symbol.Row as WixActionTuple; WixActionTuple dupeAction = dupe.Row as WixActionTuple; if (symbolAction?.Overridable != dupeAction?.Overridable) { continue; } if (this.AccessibleSymbol(referencingSection, dupe)) { symbols.Add(dupe); } } foreach (Symbol dupe in symbol.RedundantSymbols) { if (this.AccessibleSymbol(referencingSection, dupe)) { symbols.Add(dupe); } } return(symbols); }
private RelativeActions GetRelativeActions(WixActionTuple action) { if (!this.RelativeActionsForActions.TryGetValue(action.Id.Id, out var relativeActions)) { relativeActions = new RelativeActions(); this.RelativeActionsForActions.Add(action.Id.Id, relativeActions); } return(relativeActions); }
private bool ContainsChildActionRow(WixActionTuple childTuple, WixActionTuple parentTuple) { var result = false; if (this.RelativeActionsForActions.TryGetValue(childTuple.Id.Id, out var relativeActions)) { result = relativeActions.NextActions.Any(a => a.SequenceTable == parentTuple.SequenceTable && a.Id.Id == parentTuple.Id.Id) || relativeActions.PreviousActions.Any(a => a.SequenceTable == parentTuple.SequenceTable && a.Id.Id == parentTuple.Id.Id); } return(result); }
/// <summary> /// Sequence an action before or after a standard action. /// </summary> /// <param name="actionRow">The action row to be sequenced.</param> /// <param name="requiredActionRows">Collection of actions which must be included.</param> private void SequenceActionRow(WixActionTuple actionRow, Dictionary <string, WixActionTuple> requiredActionRows) { var after = false; if (actionRow.After != null) { after = true; } else if (actionRow.Before == null) { throw new InvalidOperationException("Found an ActionRow with no Sequence, Before, or After column set."); } var parentActionName = (after ? actionRow.After : actionRow.Before); var parentActionKey = actionRow.SequenceTable.ToString() + "/" + parentActionName; if (!requiredActionRows.TryGetValue(parentActionKey, out var parentActionRow)) { // If the missing parent action is a standard action (with a suggested sequence number), add it. if (this.StandardActionsById.TryGetValue(parentActionKey, out parentActionRow)) { // Create a clone to avoid modifying the static copy of the object. // TODO: consider this: parentActionRow = parentActionRow.Clone(); requiredActionRows.Add(parentActionRow.Id.Id, parentActionRow); } else { throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, "Found an ActionRow with a non-existent {0} action: {1}.", (after ? "After" : "Before"), parentActionName)); } } else if (actionRow == parentActionRow || this.ContainsChildActionRow(actionRow, parentActionRow)) // cycle detected { throw new WixException(ErrorMessages.ActionCircularDependency(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, parentActionRow.Action)); } // Add this action to the appropriate list of dependent action rows. var relativeActions = this.GetRelativeActions(parentActionRow); var relatedRows = (after ? relativeActions.NextActions : relativeActions.PreviousActions); relatedRows.Add(actionRow); }
private RelativeActions GetAllRelativeActionsForSequenceType(SequenceTable sequenceType, WixActionTuple action) { var relativeActions = new RelativeActions(); if (this.RelativeActionsForActions.TryGetValue(action.Id.Id, out var actionRelatives)) { this.RecurseRelativeActionsForSequenceType(sequenceType, actionRelatives.PreviousActions, relativeActions.PreviousActions); this.RecurseRelativeActionsForSequenceType(sequenceType, actionRelatives.NextActions, relativeActions.NextActions); } return(relativeActions); }
private void AddWixActionTuple(WixActionTuple tuple, Output output) { // Get the table definition for the action (and ensure the proper table exists for a module). TableDefinition sequenceTableDefinition = null; switch (tuple.SequenceTable) { case SequenceTable.AdminExecuteSequence: if (OutputType.Module == output.Type) { output.EnsureTable(this.TableDefinitions["AdminExecuteSequence"]); sequenceTableDefinition = this.TableDefinitions["ModuleAdminExecuteSequence"]; } else { sequenceTableDefinition = this.TableDefinitions["AdminExecuteSequence"]; } break; case SequenceTable.AdminUISequence: if (OutputType.Module == output.Type) { output.EnsureTable(this.TableDefinitions["AdminUISequence"]); sequenceTableDefinition = this.TableDefinitions["ModuleAdminUISequence"]; } else { sequenceTableDefinition = this.TableDefinitions["AdminUISequence"]; } break; case SequenceTable.AdvtExecuteSequence: if (OutputType.Module == output.Type) { output.EnsureTable(this.TableDefinitions["AdvtExecuteSequence"]); sequenceTableDefinition = this.TableDefinitions["ModuleAdvtExecuteSequence"]; } else { sequenceTableDefinition = this.TableDefinitions["AdvtExecuteSequence"]; } break; case SequenceTable.InstallExecuteSequence: if (OutputType.Module == output.Type) { output.EnsureTable(this.TableDefinitions["InstallExecuteSequence"]); sequenceTableDefinition = this.TableDefinitions["ModuleInstallExecuteSequence"]; } else { sequenceTableDefinition = this.TableDefinitions["InstallExecuteSequence"]; } break; case SequenceTable.InstallUISequence: if (OutputType.Module == output.Type) { output.EnsureTable(this.TableDefinitions["InstallUISequence"]); sequenceTableDefinition = this.TableDefinitions["ModuleInstallUISequence"]; } else { sequenceTableDefinition = this.TableDefinitions["InstallUISequence"]; } break; } // create the action sequence row in the output var sequenceTable = output.EnsureTable(sequenceTableDefinition); var row = sequenceTable.CreateRow(tuple.SourceLineNumbers); if (SectionType.Module == this.Section.Type) { row[0] = tuple.Action; if (0 != tuple.Sequence) { row[1] = tuple.Sequence; } else { bool after = (null == tuple.Before); row[2] = after ? tuple.After : tuple.Before; row[3] = after ? 1 : 0; } row[4] = tuple.Condition; } else { row[0] = tuple.Action; row[1] = tuple.Condition; row[2] = tuple.Sequence; } }