Example #1
0
        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);
        }
Example #2
0
        // rootIdSpace is optional.  if it's null, result.NewActivity will be null
        internal UpdatedActivity GetUpdatedActivity(QualifiedId oldQualifiedId, IdSpace rootIdSpace)
        {
            UpdatedActivity result = new UpdatedActivity();

            int[]            oldIdSegments  = oldQualifiedId.AsIDArray();
            int[]            newIdSegments  = null;
            IdSpace          currentIdSpace = rootIdSpace;
            DynamicUpdateMap currentMap     = this;

            Fx.Assert(!this.IsForImplementation, "This method is never supposed to be called on an implementation map.");

            for (int i = 0; i < oldIdSegments.Length; i++)
            {
                if (currentMap == null || currentMap.Entries.Count == 0)
                {
                    break;
                }

                DynamicUpdateMapEntry entry;
                if (!currentMap.TryGetUpdateEntry(oldIdSegments[i], out entry))
                {
                    // UpdateMap should contain entries for all old activities in the IdSpace
                    int[] subIdSegments = new int[i + 1];
                    Array.Copy(oldIdSegments, subIdSegments, subIdSegments.Length);
                    throw FxTrace.Exception.AsError(new InstanceUpdateException(SR.InvalidUpdateMap(
                                                                                    SR.MapEntryNotFound(new QualifiedId(subIdSegments)))));
                }

                if (entry.IsIdChange)
                {
                    if (newIdSegments == null)
                    {
                        newIdSegments = new int[oldIdSegments.Length];
                        Array.Copy(oldIdSegments, newIdSegments, oldIdSegments.Length);
                    }

                    newIdSegments[i] = entry.NewActivityId;
                }

                Activity currentActivity = null;
                if (currentIdSpace != null && !entry.IsRemoval)
                {
                    currentActivity = currentIdSpace[entry.NewActivityId];
                    if (currentActivity == null)
                    {
                        // New Activity pointed to by UpdateMap should exist
                        string activityId = currentIdSpace.Owner.Id + "." + entry.NewActivityId.ToString(CultureInfo.InvariantCulture);
                        throw FxTrace.Exception.AsError(new InstanceUpdateException(SR.InvalidUpdateMap(
                                                                                        SR.ActivityNotFound(activityId))));
                    }
                    currentIdSpace = currentActivity.ParentOf;
                }

                if (i == oldIdSegments.Length - 1)
                {
                    result.Map         = currentMap;
                    result.MapEntry    = entry;
                    result.NewActivity = currentActivity;
                }
                else if (entry.IsRuntimeUpdateBlocked || entry.IsUpdateBlockedByUpdateAuthor)
                {
                    currentMap = null;
                }
                else
                {
                    currentMap = entry.ImplementationUpdateMap;
                }
            }

            result.IdChanged = newIdSegments != null;
            result.NewId     = result.IdChanged ? new QualifiedId(newIdSegments) : oldQualifiedId;

            return(result);
        }