@joebigelow / wix-1 / commits / c05d9e61

Fix relative action scheduling

And remove more referneces to "row"

Rob Mensching committed May 23, 2019 at 22:45 UTC c05d9e61d17746ec6e9e072b32fc821543a7cffb
1 file changed +135 -127
src/WixToolset.Core.WindowsInstaller/Bind/SequenceActionsCommand.cs
+135 -127
@@ -31,150 +31,142 @@ namespace WixToolset.Core.WindowsInstaller.Bind
31 public IMessaging Messaging { private get; set; }
32
33 /// <summary>
34 - /// Set sequence numbers for all the actions and create rows in the output object.
34 + /// Set sequence numbers for all the actions and create tuples in the output object.
35 /// </summary>
36 public void Execute()
37 {
38 - var overridableActionRows = new Dictionary<string, WixActionTuple>();
39 - var requiredActionRows = new Dictionary<string, WixActionTuple>();
38 + var requiredActionTuples = new Dictionary<string, WixActionTuple>();
39
40 // Get the standard actions required based on tuples in the section.
42 - var requiredActionIds = this.GetRequiredActionIds();
43 -
44 - foreach (var actionId in requiredActionIds)
45 - {
46 - var standardAction = this.StandardActionsById[actionId];
41 + var overridableActionTuples = this.GetRequiredStandardActions();
42
48 - overridableActionRows.Add(standardAction.Id.Id, standardAction);
49 - }
50 -
51 - // Index all the action rows and look for collisions.
52 - foreach (var actionRow in this.Section.Tuples.OfType<WixActionTuple>())
43 + // Index all the action tuples and look for collisions.
44 + foreach (var actionTuple in this.Section.Tuples.OfType<WixActionTuple>())
45 {
54 - if (actionRow.Overridable) // overridable action
46 + if (actionTuple.Overridable) // overridable action
47 {
56 - if (overridableActionRows.TryGetValue(actionRow.Id.Id, out var collidingActionRow))
48 + if (overridableActionTuples.TryGetValue(actionTuple.Id.Id, out var collidingActionTuple))
49 {
58 - this.Messaging.Write(ErrorMessages.OverridableActionCollision(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action));
59 - if (null != collidingActionRow.SourceLineNumbers)
50 + this.Messaging.Write(ErrorMessages.OverridableActionCollision(actionTuple.SourceLineNumbers, actionTuple.SequenceTable.ToString(), actionTuple.Action));
51 + if (null != collidingActionTuple.SourceLineNumbers)
52 {
61 - this.Messaging.Write(ErrorMessages.OverridableActionCollision2(collidingActionRow.SourceLineNumbers));
53 + this.Messaging.Write(ErrorMessages.OverridableActionCollision2(collidingActionTuple.SourceLineNumbers));
54 }
55 }
56 else
57 {
66 - overridableActionRows.Add(actionRow.Id.Id, actionRow);
58 + overridableActionTuples.Add(actionTuple.Id.Id, actionTuple);
59 }
60 }
61 else // unsequenced or sequenced action.
62 {
63 // Unsequenced action (allowed for certain standard actions).
72 - if (null == actionRow.Before && null == actionRow.After && 0 == actionRow.Sequence)
64 + if (null == actionTuple.Before && null == actionTuple.After && !actionTuple.Sequence.HasValue)
65 {
74 - if (this.StandardActionsById.TryGetValue(actionRow.Id.Id, out var standardAction))
66 + if (this.StandardActionsById.TryGetValue(actionTuple.Id.Id, out var standardAction))
67 {
68 // Populate the sequence from the standard action
77 - actionRow.Sequence = standardAction.Sequence;
69 + actionTuple.Sequence = standardAction.Sequence;
70 }
71 else // not a supported unscheduled action.
72 {
81 - throw new InvalidOperationException("Found an ActionRow with no Sequence, Before, or After column set.");
73 + throw new InvalidOperationException("Found an action with no Sequence, Before, or After column set.");
74 }
75 }
76
85 - if (requiredActionRows.TryGetValue(actionRow.Id.Id, out var collidingActionRow))
77 + if (requiredActionTuples.TryGetValue(actionTuple.Id.Id, out var collidingActionTuple))
78 {
87 - this.Messaging.Write(ErrorMessages.ActionCollision(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action));
88 - if (null != collidingActionRow.SourceLineNumbers)
79 + this.Messaging.Write(ErrorMessages.ActionCollision(actionTuple.SourceLineNumbers, actionTuple.SequenceTable.ToString(), actionTuple.Action));
80 + if (null != collidingActionTuple.SourceLineNumbers)
81 {
90 - this.Messaging.Write(ErrorMessages.ActionCollision2(collidingActionRow.SourceLineNumbers));
82 + this.Messaging.Write(ErrorMessages.ActionCollision2(collidingActionTuple.SourceLineNumbers));
83 }
84 }
85 else
86 {
95 - requiredActionRows.Add(actionRow.Id.Id, actionRow);
87 + requiredActionTuples.Add(actionTuple.Id.Id, actionTuple);
88 }
89 }
90 }
91
100 - // Add the overridable action rows that are not overridden to the required action rows.
101 - foreach (var actionRow in overridableActionRows.Values)
92 + // Add the overridable action tuples that are not overridden to the required action tuples.
93 + foreach (var actionTuple in overridableActionTuples.Values)
94 {
103 - if (!requiredActionRows.ContainsKey(actionRow.Id.Id))
95 + if (!requiredActionTuples.ContainsKey(actionTuple.Id.Id))
96 {
105 - requiredActionRows.Add(actionRow.Id.Id, actionRow);
97 + requiredActionTuples.Add(actionTuple.Id.Id, actionTuple);
98 }
99 }
100
101 // Suppress the required actions that are overridable.
110 - foreach (var suppressActionRow in this.Section.Tuples.OfType<WixSuppressActionTuple>())
102 + foreach (var suppressActionTuple in this.Section.Tuples.OfType<WixSuppressActionTuple>())
103 {
112 - var key = suppressActionRow.Id.Id;
104 + var key = suppressActionTuple.Id.Id;
105
114 - // If there is an overridable row to suppress; suppress it. There is no warning if there
106 + // If there is an overridable tuple to suppress; suppress it. There is no warning if there
107 // is no action to suppress because the action may be suppressed from a merge module in
108 // the binder.
117 - if (requiredActionRows.TryGetValue(key, out var requiredActionRow))
109 + if (requiredActionTuples.TryGetValue(key, out var requiredActionTuple))
110 {
119 - if (requiredActionRow.Overridable)
111 + if (requiredActionTuple.Overridable)
112 {
121 - this.Messaging.Write(WarningMessages.SuppressAction(suppressActionRow.SourceLineNumbers, suppressActionRow.Action, suppressActionRow.SequenceTable.ToString()));
122 - if (null != requiredActionRow.SourceLineNumbers)
113 + this.Messaging.Write(WarningMessages.SuppressAction(suppressActionTuple.SourceLineNumbers, suppressActionTuple.Action, suppressActionTuple.SequenceTable.ToString()));
114 + if (null != requiredActionTuple.SourceLineNumbers)
115 {
124 - this.Messaging.Write(WarningMessages.SuppressAction2(requiredActionRow.SourceLineNumbers));
116 + this.Messaging.Write(WarningMessages.SuppressAction2(requiredActionTuple.SourceLineNumbers));
117 }
118
127 - requiredActionRows.Remove(key);
119 + requiredActionTuples.Remove(key);
120 }
129 - else // suppressing a non-overridable action row
121 + else // suppressing a non-overridable action tuple
122 {
131 - this.Messaging.Write(ErrorMessages.SuppressNonoverridableAction(suppressActionRow.SourceLineNumbers, suppressActionRow.SequenceTable.ToString(), suppressActionRow.Action));
132 - if (null != requiredActionRow.SourceLineNumbers)
123 + this.Messaging.Write(ErrorMessages.SuppressNonoverridableAction(suppressActionTuple.SourceLineNumbers, suppressActionTuple.SequenceTable.ToString(), suppressActionTuple.Action));
124 + if (null != requiredActionTuple.SourceLineNumbers)
125 {
134 - this.Messaging.Write(ErrorMessages.SuppressNonoverridableAction2(requiredActionRow.SourceLineNumbers));
126 + this.Messaging.Write(ErrorMessages.SuppressNonoverridableAction2(requiredActionTuple.SourceLineNumbers));
127 }
128 }
129 }
130 }
131
132 // Build up dependency trees of the relatively scheduled actions.
141 - // Use ToList() to create a copy of the required action rows so that new tuples can
133 + // Use ToList() to create a copy of the required action tuples so that new tuples can
134 // be added while enumerating.
143 - foreach (var actionRow in requiredActionRows.Values.ToList())
135 + foreach (var actionTuple in requiredActionTuples.Values.ToList())
136 {
145 - if (0 == actionRow.Sequence)
137 + if (!actionTuple.Sequence.HasValue)
138 {
139 // check for standard actions that don't have a sequence number in a merge module
148 - if (SectionType.Module == this.Section.Type && WindowsInstallerStandard.IsStandardAction(actionRow.Action))
140 + if (SectionType.Module == this.Section.Type && WindowsInstallerStandard.IsStandardAction(actionTuple.Action))
141 {
150 - this.Messaging.Write(ErrorMessages.StandardActionRelativelyScheduledInModule(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action));
142 + this.Messaging.Write(ErrorMessages.StandardActionRelativelyScheduledInModule(actionTuple.SourceLineNumbers, actionTuple.SequenceTable.ToString(), actionTuple.Action));
143 }
144
153 - this.SequenceActionRow(actionRow, requiredActionRows);
145 + this.SequenceActionTuple(actionTuple, requiredActionTuples);
146 }
155 - else if (SectionType.Module == this.Section.Type && 0 < actionRow.Sequence && !WindowsInstallerStandard.IsStandardAction(actionRow.Action)) // check for custom actions and dialogs that have a sequence number
147 + else if (SectionType.Module == this.Section.Type && 0 < actionTuple.Sequence && !WindowsInstallerStandard.IsStandardAction(actionTuple.Action)) // check for custom actions and dialogs that have a sequence number
148 {
157 - this.Messaging.Write(ErrorMessages.CustomActionSequencedInModule(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action));
149 + this.Messaging.Write(ErrorMessages.CustomActionSequencedInModule(actionTuple.SourceLineNumbers, actionTuple.SequenceTable.ToString(), actionTuple.Action));
150 }
151 }
152
153 // Look for standard actions with sequence restrictions that aren't necessarily scheduled based
154 // on the presence of a particular table.
163 - if (requiredActionRows.ContainsKey("InstallExecuteSequence/DuplicateFiles") && !requiredActionRows.ContainsKey("InstallExecuteSequence/InstallFiles"))
155 + if (requiredActionTuples.ContainsKey("InstallExecuteSequence/DuplicateFiles") && !requiredActionTuples.ContainsKey("InstallExecuteSequence/InstallFiles"))
156 {
157 var standardAction = this.StandardActionsById["InstallExecuteSequence/InstallFiles"];
166 - requiredActionRows.Add(standardAction.Id.Id, standardAction);
158 + requiredActionTuples.Add(standardAction.Id.Id, standardAction);
159 }
160
161 // Schedule actions.
170 - List<WixActionTuple> scheduledActionRows;
162 + List<WixActionTuple> scheduledActionTuples;
163 if (SectionType.Module == this.Section.Type)
164 {
173 - scheduledActionRows = requiredActionRows.Values.ToList();
165 + scheduledActionTuples = requiredActionTuples.Values.ToList();
166 }
167 else
168 {
177 - scheduledActionRows = this.ScheduleActions(requiredActionRows);
169 + scheduledActionTuples = this.ScheduleActions(requiredActionTuples);
170 }
171
172 // Remove all existing WixActionTuples from the section then add the
@@ -195,146 +187,162 @@ namespace WixToolset.Core.WindowsInstaller.Bind
187 this.Section.Tuples.RemoveAt(removeIndex);
188 }
189
198 - foreach (var action in scheduledActionRows)
190 + foreach (var action in scheduledActionTuples)
191 {
192 this.Section.Tuples.Add(action);
193 }
194 }
195
204 - private List<WixActionTuple> ScheduleActions(Dictionary<string, WixActionTuple> requiredActionRows)
196 + private Dictionary<string, WixActionTuple> GetRequiredStandardActions()
197 + {
198 + var overridableActionTuples = new Dictionary<string, WixActionTuple>();
199 +
200 + var requiredActionIds = this.GetRequiredActionIds();
201 +
202 + foreach (var actionId in requiredActionIds)
203 + {
204 + var standardAction = this.StandardActionsById[actionId];
205 +
206 + overridableActionTuples.Add(standardAction.Id.Id, standardAction);
207 + }
208 +
209 + return overridableActionTuples;
210 + }
211 +
212 + private List<WixActionTuple> ScheduleActions(Dictionary<string, WixActionTuple> requiredActionTuples)
213 {
206 - var scheduledActionRows = new List<WixActionTuple>();
214 + var scheduledActionTuples = new List<WixActionTuple>();
215
216 // Process each sequence table individually.
217 foreach (SequenceTable sequenceTable in Enum.GetValues(typeof(SequenceTable)))
218 {
211 - // Create a collection of just the action rows in this sequence
212 - var sequenceActionRows = requiredActionRows.Values.Where(a => a.SequenceTable == sequenceTable).ToList();
219 + // Create a collection of just the action tuples in this sequence
220 + var sequenceActionTuples = requiredActionTuples.Values.Where(a => a.SequenceTable == sequenceTable).ToList();
221
222 // Schedule the absolutely scheduled actions (by sorting them by their sequence numbers).
215 - var absoluteActionRows = new List<WixActionTuple>();
216 - foreach (var actionRow in sequenceActionRows)
223 + var absoluteActionTuples = new List<WixActionTuple>();
224 + foreach (var actionTuple in sequenceActionTuples)
225 {
218 - if (0 != actionRow.Sequence)
226 + if (actionTuple.Sequence.HasValue)
227 {
228 // Look for sequence number collisions
221 - foreach (var sequenceScheduledActionRow in absoluteActionRows)
229 + foreach (var sequenceScheduledActionTuple in absoluteActionTuples)
230 {
223 - if (sequenceScheduledActionRow.Sequence == actionRow.Sequence)
231 + if (sequenceScheduledActionTuple.Sequence == actionTuple.Sequence)
232 {
225 - this.Messaging.Write(WarningMessages.ActionSequenceCollision(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, sequenceScheduledActionRow.Action, actionRow.Sequence ?? 0));
226 - if (null != sequenceScheduledActionRow.SourceLineNumbers)
233 + this.Messaging.Write(WarningMessages.ActionSequenceCollision(actionTuple.SourceLineNumbers, actionTuple.SequenceTable.ToString(), actionTuple.Action, sequenceScheduledActionTuple.Action, actionTuple.Sequence ?? 0));
234 + if (null != sequenceScheduledActionTuple.SourceLineNumbers)
235 {
228 - this.Messaging.Write(WarningMessages.ActionSequenceCollision2(sequenceScheduledActionRow.SourceLineNumbers));
236 + this.Messaging.Write(WarningMessages.ActionSequenceCollision2(sequenceScheduledActionTuple.SourceLineNumbers));
237 }
238 }
239 }
240
233 - absoluteActionRows.Add(actionRow);
241 + absoluteActionTuples.Add(actionTuple);
242 }
243 }
244
237 - absoluteActionRows.Sort((x, y) => (x.Sequence ?? 0).CompareTo(y.Sequence ?? 0));
245 + absoluteActionTuples.Sort((x, y) => (x.Sequence ?? 0).CompareTo(y.Sequence ?? 0));
246
247 // Schedule the relatively scheduled actions (by resolving the dependency trees).
248 var previousUsedSequence = 0;
241 - var relativeActionRows = new List<WixActionTuple>();
242 - for (int j = 0; j < absoluteActionRows.Count; j++)
249 + var relativeActionTuples = new List<WixActionTuple>();
250 + for (int j = 0; j < absoluteActionTuples.Count; j++)
251 {
244 - var absoluteActionRow = absoluteActionRows[j];
252 + var absoluteActionTuple = absoluteActionTuples[j];
253
246 - // Get all the relatively scheduled action rows occuring before and after this absolutely scheduled action row.
247 - var relativeActions = this.GetAllRelativeActionsForSequenceType(sequenceTable, absoluteActionRow);
254 + // Get all the relatively scheduled action tuples occuring before and after this absolutely scheduled action tuple.
255 + var relativeActions = this.GetAllRelativeActionsForSequenceType(sequenceTable, absoluteActionTuple);
256
257 // Check for relatively scheduled actions occuring before/after a special action
258 // (those actions with a negative sequence number).
251 - if (absoluteActionRow.Sequence < 0 && (relativeActions.PreviousActions.Any() || relativeActions.NextActions.Any()))
259 + if (absoluteActionTuple.Sequence < 0 && (relativeActions.PreviousActions.Any() || relativeActions.NextActions.Any()))
260 {
261 // Create errors for all the before actions.
254 - foreach (var actionRow in relativeActions.PreviousActions)
262 + foreach (var actionTuple in relativeActions.PreviousActions)
263 {
256 - this.Messaging.Write(ErrorMessages.ActionScheduledRelativeToTerminationAction(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, absoluteActionRow.Action));
264 + this.Messaging.Write(ErrorMessages.ActionScheduledRelativeToTerminationAction(actionTuple.SourceLineNumbers, actionTuple.SequenceTable.ToString(), actionTuple.Action, absoluteActionTuple.Action));
265 }
266
267 // Create errors for all the after actions.
260 - foreach (var actionRow in relativeActions.NextActions)
268 + foreach (var actionTuple in relativeActions.NextActions)
269 {
262 - this.Messaging.Write(ErrorMessages.ActionScheduledRelativeToTerminationAction(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, absoluteActionRow.Action));
270 + this.Messaging.Write(ErrorMessages.ActionScheduledRelativeToTerminationAction(actionTuple.SourceLineNumbers, actionTuple.SequenceTable.ToString(), actionTuple.Action, absoluteActionTuple.Action));
271 }
272
273 // If there is source line information for the absolutely scheduled action display it
266 - if (absoluteActionRow.SourceLineNumbers != null)
274 + if (absoluteActionTuple.SourceLineNumbers != null)
275 {
268 - this.Messaging.Write(ErrorMessages.ActionScheduledRelativeToTerminationAction2(absoluteActionRow.SourceLineNumbers));
276 + this.Messaging.Write(ErrorMessages.ActionScheduledRelativeToTerminationAction2(absoluteActionTuple.SourceLineNumbers));
277 }
278
279 continue;
280 }
281
274 - // Schedule the action rows before this one.
275 - var unusedSequence = absoluteActionRow.Sequence - 1;
282 + // Schedule the action tuples before this one.
283 + var unusedSequence = absoluteActionTuple.Sequence - 1;
284 for (var i = relativeActions.PreviousActions.Count - 1; i >= 0; i--)
285 {
278 - var relativeActionRow = relativeActions.PreviousActions[i];
286 + var relativeActionTuple = relativeActions.PreviousActions[i];
287
288 // look for collisions
289 if (unusedSequence == previousUsedSequence)
290 {
283 - this.Messaging.Write(ErrorMessages.NoUniqueActionSequenceNumber(relativeActionRow.SourceLineNumbers, relativeActionRow.SequenceTable.ToString(), relativeActionRow.Action, absoluteActionRow.Action));
284 - if (absoluteActionRow.SourceLineNumbers != null)
291 + this.Messaging.Write(ErrorMessages.NoUniqueActionSequenceNumber(relativeActionTuple.SourceLineNumbers, relativeActionTuple.SequenceTable.ToString(), relativeActionTuple.Action, absoluteActionTuple.Action));
292 + if (absoluteActionTuple.SourceLineNumbers != null)
293 {
286 - this.Messaging.Write(ErrorMessages.NoUniqueActionSequenceNumber2(absoluteActionRow.SourceLineNumbers));
294 + this.Messaging.Write(ErrorMessages.NoUniqueActionSequenceNumber2(absoluteActionTuple.SourceLineNumbers));
295 }
296
297 unusedSequence++;
298 }
299
292 - relativeActionRow.Sequence = unusedSequence;
293 - relativeActionRows.Add(relativeActionRow);
300 + relativeActionTuple.Sequence = unusedSequence;
301 + relativeActionTuples.Add(relativeActionTuple);
302
303 unusedSequence--;
304 }
305
306 // Determine the next used action sequence number.
307 var nextUsedSequence = Int16.MaxValue + 1;
300 - if (absoluteActionRows.Count > j + 1)
308 + if (absoluteActionTuples.Count > j + 1)
309 {
302 - nextUsedSequence = absoluteActionRows[j + 1].Sequence ?? 0;
310 + nextUsedSequence = absoluteActionTuples[j + 1].Sequence ?? 0;
311 }
312
305 - // Schedule the action rows after this one.
306 - unusedSequence = absoluteActionRow.Sequence + 1;
313 + // Schedule the action tuples after this one.
314 + unusedSequence = absoluteActionTuple.Sequence + 1;
315 for (var i = 0; i < relativeActions.NextActions.Count; i++)
316 {
309 - var relativeActionRow = relativeActions.NextActions[i];
317 + var relativeActionTuple = relativeActions.NextActions[i];
318
319 if (unusedSequence == nextUsedSequence)
320 {
313 - this.Messaging.Write(ErrorMessages.NoUniqueActionSequenceNumber(relativeActionRow.SourceLineNumbers, relativeActionRow.SequenceTable.ToString(), relativeActionRow.Action, absoluteActionRow.Action));
314 - if (absoluteActionRow.SourceLineNumbers != null)
321 + this.Messaging.Write(ErrorMessages.NoUniqueActionSequenceNumber(relativeActionTuple.SourceLineNumbers, relativeActionTuple.SequenceTable.ToString(), relativeActionTuple.Action, absoluteActionTuple.Action));
322 + if (absoluteActionTuple.SourceLineNumbers != null)
323 {
316 - this.Messaging.Write(ErrorMessages.NoUniqueActionSequenceNumber2(absoluteActionRow.SourceLineNumbers));
324 + this.Messaging.Write(ErrorMessages.NoUniqueActionSequenceNumber2(absoluteActionTuple.SourceLineNumbers));
325 }
326
327 unusedSequence--;
328 }
329
322 - relativeActionRow.Sequence = unusedSequence;
323 - relativeActionRows.Add(relativeActionRow);
330 + relativeActionTuple.Sequence = unusedSequence;
331 + relativeActionTuples.Add(relativeActionTuple);
332
333 unusedSequence++;
334 }
335
336 // keep track of this sequence number as the previous used sequence number for the next iteration
329 - previousUsedSequence = absoluteActionRow.Sequence ?? 0;
337 + previousUsedSequence = absoluteActionTuple.Sequence ?? 0;
338 }
339
340 // add the absolutely and relatively scheduled actions to the list of scheduled actions
333 - scheduledActionRows.AddRange(absoluteActionRows);
334 - scheduledActionRows.AddRange(relativeActionRows);
341 + scheduledActionTuples.AddRange(absoluteActionTuples);
342 + scheduledActionTuples.AddRange(relativeActionTuples);
343 }
344
337 - return scheduledActionRows;
345 + return scheduledActionTuples;
346 }
347
348 private IEnumerable<string> GetRequiredActionIds()
@@ -568,51 +576,51 @@ namespace WixToolset.Core.WindowsInstaller.Bind
576 /// <summary>
577 /// Sequence an action before or after a standard action.
578 /// </summary>
571 - /// <param name="actionRow">The action row to be sequenced.</param>
572 - /// <param name="requiredActionRows">Collection of actions which must be included.</param>
573 - private void SequenceActionRow(WixActionTuple actionRow, Dictionary<string, WixActionTuple> requiredActionRows)
579 + /// <param name="actionTuple">The action tuple to be sequenced.</param>
580 + /// <param name="requiredActionTuples">Collection of actions which must be included.</param>
581 + private void SequenceActionTuple(WixActionTuple actionTuple, Dictionary<string, WixActionTuple> requiredActionTuples)
582 {
583 var after = false;
584
577 - if (actionRow.After != null)
585 + if (actionTuple.After != null)
586 {
587 after = true;
588 }
581 - else if (actionRow.Before == null)
589 + else if (actionTuple.Before == null)
590 {
583 - throw new InvalidOperationException("Found an ActionRow with no Sequence, Before, or After column set.");
591 + throw new InvalidOperationException("Found an action with no Sequence, Before, or After column set.");
592 }
593
586 - var parentActionName = (after ? actionRow.After : actionRow.Before);
587 - var parentActionKey = actionRow.SequenceTable.ToString() + "/" + parentActionName;
594 + var parentActionName = (after ? actionTuple.After : actionTuple.Before);
595 + var parentActionKey = actionTuple.SequenceTable.ToString() + "/" + parentActionName;
596
589 - if (!requiredActionRows.TryGetValue(parentActionKey, out var parentActionRow))
597 + if (!requiredActionTuples.TryGetValue(parentActionKey, out var parentActionTuple))
598 {
599 // If the missing parent action is a standard action (with a suggested sequence number), add it.
592 - if (this.StandardActionsById.TryGetValue(parentActionKey, out parentActionRow))
600 + if (this.StandardActionsById.TryGetValue(parentActionKey, out parentActionTuple))
601 {
602 // Create a clone to avoid modifying the static copy of the object.
595 - // TODO: consider this: parentActionRow = parentActionRow.Clone();
603 + // TODO: consider this: parentActionTuple = parentActionTuple.Clone();
604
597 - requiredActionRows.Add(parentActionRow.Id.Id, parentActionRow);
605 + requiredActionTuples.Add(parentActionTuple.Id.Id, parentActionTuple);
606 }
607 else
608 {
601 - throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, "Found an ActionRow with a non-existent {0} action: {1}.", (after ? "After" : "Before"), parentActionName));
609 + throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, "Found an action with a non-existent {0} action: {1}.", (after ? "After" : "Before"), parentActionName));
610 }
611 }
604 - else if (actionRow == parentActionRow || this.ContainsChildActionRow(actionRow, parentActionRow)) // cycle detected
612 + else if (actionTuple == parentActionTuple || this.ContainsChildActionTuple(actionTuple, parentActionTuple)) // cycle detected
613 {
606 - throw new WixException(ErrorMessages.ActionCircularDependency(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, parentActionRow.Action));
614 + throw new WixException(ErrorMessages.ActionCircularDependency(actionTuple.SourceLineNumbers, actionTuple.SequenceTable.ToString(), actionTuple.Action, parentActionTuple.Action));
615 }
616
609 - // Add this action to the appropriate list of dependent action rows.
610 - var relativeActions = this.GetRelativeActions(parentActionRow);
611 - var relatedRows = (after ? relativeActions.NextActions : relativeActions.PreviousActions);
612 - relatedRows.Add(actionRow);
617 + // Add this action to the appropriate list of dependent action tuples.
618 + var relativeActions = this.GetRelativeActions(parentActionTuple);
619 + var relatedTuples = (after ? relativeActions.NextActions : relativeActions.PreviousActions);
620 + relatedTuples.Add(actionTuple);
621 }
622
615 - private bool ContainsChildActionRow(WixActionTuple childTuple, WixActionTuple parentTuple)
623 + private bool ContainsChildActionTuple(WixActionTuple childTuple, WixActionTuple parentTuple)
624 {
625 var result = false;
626