static void ThrowIfMapsIncompatible(DynamicUpdateMap first, DynamicUpdateMap second, MergeErrorContext errorContext) { Fx.Assert(!first.IsNoChanges && !second.IsNoChanges, "This method is never supposed to be called on the NoChanges map."); if (first.IsForImplementation != second.IsForImplementation) { errorContext.Throw(SR.InvalidMergeMapForImplementation(first.IsForImplementation, second.IsForImplementation)); } if (first.NewDefinitionMemberCount != second.OldDefinitionMemberCount) { errorContext.Throw(SR.InvalidMergeMapMemberCount(first.NewDefinitionMemberCount, second.OldDefinitionMemberCount)); } if (!first.ArgumentsAreUnknown && !second.ArgumentsAreUnknown && first.IsForImplementation && !ActivityComparer.ListEquals(first.newArguments, second.oldArguments)) { if (first.NewArguments.Count != second.OldArguments.Count) { errorContext.Throw(SR.InvalidMergeMapArgumentCount(first.NewArguments.Count, second.OldArguments.Count)); } else { errorContext.Throw(SR.InvalidMergeMapArgumentsChanged); } } }
internal static DynamicUpdateMap Merge(DynamicUpdateMap first, DynamicUpdateMap second, MergeErrorContext errorContext) { if (first == null || second == null) { return(first ?? second); } if (first.IsNoChanges || second.IsNoChanges) { // DynamicUpdateMap.NoChanges has zero members, so we need to special-case it here. return(first.IsNoChanges ? second : first); } ThrowIfMapsIncompatible(first, second, errorContext); DynamicUpdateMap result = new DynamicUpdateMap { IsForImplementation = first.IsForImplementation, NewDefinitionMemberCount = second.NewDefinitionMemberCount, ArgumentsAreUnknown = first.ArgumentsAreUnknown && second.ArgumentsAreUnknown, oldArguments = first.ArgumentsAreUnknown ? second.oldArguments : first.oldArguments, newArguments = second.ArgumentsAreUnknown ? first.newArguments : second.newArguments }; foreach (DynamicUpdateMapEntry firstEntry in first.Entries) { DynamicUpdateMapEntry parent = null; if (firstEntry.Parent != null) { result.TryGetUpdateEntry(firstEntry.Parent.OldActivityId, out parent); } if (firstEntry.IsRemoval) { result.AddEntry(firstEntry.Clone(parent)); } else { DynamicUpdateMapEntry secondEntry = second.entries[firstEntry.NewActivityId]; result.AddEntry(DynamicUpdateMapEntry.Merge(firstEntry, secondEntry, parent, errorContext)); } } return(result); }