예제 #1
0
        internal ResolvedAttributeSet Merge(ResolvedAttribute toMerge, CdmAttributeContext attCtx = null)
        {
            ResolvedAttributeSet rasResult = this;

            if (toMerge != null)
            {
                if (rasResult.ResolvedName2resolvedAttribute.ContainsKey(toMerge.ResolvedName))
                {
                    ResolvedAttribute existing = rasResult.ResolvedName2resolvedAttribute[toMerge.ResolvedName];
                    if (this.RefCnt > 1 && existing.Target != toMerge.Target)
                    {
                        rasResult = rasResult.Copy(); // copy on write
                        existing  = rasResult.ResolvedName2resolvedAttribute[toMerge.ResolvedName];
                    }
                    existing.Target = toMerge.Target; // replace with newest version
                    existing.Arc    = toMerge.Arc;

                    ResolvedTraitSet rtsMerge = existing.ResolvedTraits.MergeSet(toMerge.ResolvedTraits); // newest one may replace
                    if (rtsMerge != existing.ResolvedTraits)
                    {
                        rasResult = rasResult.Copy(); // copy on write
                        existing  = rasResult.ResolvedName2resolvedAttribute[toMerge.ResolvedName];
                        existing.ResolvedTraits = rtsMerge;
                    }
                }
                else
                {
                    if (this.RefCnt > 1)
                    {
                        rasResult = rasResult.Copy(); // copy on write
                    }
                    if (rasResult == null)
                    {
                        rasResult = this;
                    }
                    rasResult.ResolvedName2resolvedAttribute.Add(toMerge.ResolvedName, toMerge);
                    // don't use the attCtx on the actual attribute, that's only for doing appliers
                    if (attCtx != null)
                    {
                        rasResult.CacheAttributeContext(attCtx, toMerge);
                    }
                    //toMerge.InsertOrder = rasResult.Set.Count;
                    rasResult.Set.Add(toMerge);
                }
                this.BaseTrait2Attributes = null;
            }
            return(rasResult);
        }
예제 #2
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        //  traits that change attributes
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        internal ResolvedAttributeSet ApplyTraits(ResolvedTraitSet traits, ResolveOptions resOpt, CdmAttributeResolutionGuidance resGuide, List <AttributeResolutionApplier> actions)
        {
            ResolvedAttributeSet rasResult = this;
            ResolvedAttributeSet rasApplied;

            if (this.RefCnt > 1 && rasResult.CopyNeeded(traits, resOpt, resGuide, actions))
            {
                rasResult = rasResult.Copy();
            }
            rasApplied = rasResult.Apply(traits, resOpt, resGuide, actions);

            // now we are that
            rasResult.ResolvedName2resolvedAttribute = rasApplied.ResolvedName2resolvedAttribute;
            rasResult.BaseTrait2Attributes           = null;
            rasResult.Set = rasApplied.Set;

            return(rasResult);
        }
예제 #3
0
        internal ResolvedAttributeSet Merge(ResolvedAttribute toMerge, CdmAttributeContext attCtx = null)
        {
            ResolvedAttributeSet rasResult = this;

            if (toMerge != null)
            {
                // if there is already a resolve attribute present, remove it before adding the new attribute
                if (rasResult.ResolvedName2resolvedAttribute.ContainsKey(toMerge.ResolvedName))
                {
                    ResolvedAttribute existing = rasResult.ResolvedName2resolvedAttribute[toMerge.ResolvedName];
                    if (this.RefCnt > 1 && existing.Target != toMerge.Target)
                    {
                        rasResult = rasResult.Copy(); // copy on write
                        existing  = rasResult.ResolvedName2resolvedAttribute[toMerge.ResolvedName];
                    }
                    else
                    {
                        rasResult = this;
                    }

                    if (existing.Target is CdmAttribute)
                    {
                        rasResult.ResolvedAttributeCount -= existing.Target.AttributeCount;
                    }
                    else if (existing.Target is ResolvedAttributeSet)
                    {
                        rasResult.ResolvedAttributeCount -= existing.Target.ResolvedAttributeCount;
                    }

                    if (toMerge.Target is CdmAttribute)
                    {
                        rasResult.ResolvedAttributeCount += toMerge.Target.AttributeCount;
                    }
                    else if (toMerge.Target is ResolvedAttributeSet)
                    {
                        rasResult.ResolvedAttributeCount += toMerge.Target.ResolvedAttributeCount;
                    }

                    existing.Target = toMerge.Target; // replace with newest version
                    existing.Arc    = toMerge.Arc;

                    // Replace old context mappings with mappings to new attribute
                    rasResult.RemoveCachedAttributeContext(existing.AttCtx);
                    rasResult.CacheAttributeContext(attCtx, existing);

                    ResolvedTraitSet rtsMerge = existing.ResolvedTraits.MergeSet(toMerge.ResolvedTraits); // newest one may replace
                    if (rtsMerge != existing.ResolvedTraits)
                    {
                        rasResult = rasResult.Copy(); // copy on write
                        existing  = rasResult.ResolvedName2resolvedAttribute[toMerge.ResolvedName];
                        existing.ResolvedTraits = rtsMerge;
                    }
                }
                else
                {
                    if (this.RefCnt > 1)
                    {
                        rasResult = rasResult.Copy(); // copy on write
                    }
                    if (rasResult == null)
                    {
                        rasResult = this;
                    }
                    rasResult.ResolvedName2resolvedAttribute.Add(toMerge.ResolvedName, toMerge);
                    // don't use the attCtx on the actual attribute, that's only for doing appliers
                    if (attCtx != null)
                    {
                        rasResult.CacheAttributeContext(attCtx, toMerge);
                    }
                    //toMerge.InsertOrder = rasResult.Set.Count;
                    rasResult.Set.Add(toMerge);
                    rasResult.ResolvedAttributeCount += toMerge.ResolvedAttributeCount;
                }
                this.BaseTrait2Attributes = null;
            }
            return(rasResult);
        }
예제 #4
0
        internal ResolvedAttributeSet Merge(ResolvedAttribute toMerge)
        {
            ResolvedAttributeSet rasResult = this;

            if (toMerge != null)
            {
                // if there is already a resolve attribute present, remove it before adding the new attribute
                if (rasResult.ResolvedName2resolvedAttribute.ContainsKey(toMerge.ResolvedName))
                {
                    ResolvedAttribute existing = rasResult.ResolvedName2resolvedAttribute[toMerge.ResolvedName];
                    if (existing != toMerge)
                    {
                        if (this.RefCnt > 1 && existing.Target != toMerge.Target)
                        {
                            rasResult = rasResult.Copy(); // copy on write
                            existing  = rasResult.ResolvedName2resolvedAttribute[toMerge.ResolvedName];
                        }
                        else
                        {
                            rasResult = this;
                        }

                        if (existing.Target is CdmAttribute)
                        {
                            rasResult.ResolvedAttributeCount -= existing.Target.AttributeCount;
                        }
                        else if (existing.Target is ResolvedAttributeSet)
                        {
                            rasResult.ResolvedAttributeCount -= existing.Target.ResolvedAttributeCount;
                        }

                        if (toMerge.Target is CdmAttribute)
                        {
                            rasResult.ResolvedAttributeCount += toMerge.Target.AttributeCount;
                        }
                        else if (toMerge.Target is ResolvedAttributeSet)
                        {
                            rasResult.ResolvedAttributeCount += toMerge.Target.ResolvedAttributeCount;
                        }

                        existing.Target = toMerge.Target; // replace with newest version
                        existing.Arc    = toMerge.Arc;

                        // merge a new ra into one with the same name, so make a lineage
                        // the existing attCtx becomes the new lineage. but the old one needs to stay too... so you get both. it came from both places.
                        // we need ONE place where this RA can point, so that will be the most recent place with a fixed lineage
                        // A->C1->C0 gets merged with A'->C2->C3 that turns into A->C2->[(c3), (C1->C0)]. in the more simple case this is just A->C2->C1
                        if (toMerge.AttCtx != null)
                        {
                            if (existing.AttCtx != null)
                            {
                                toMerge.AttCtx.AddLineage(existing.AttCtx);
                            }
                            existing.AttCtx = toMerge.AttCtx;
                        }

                        ResolvedTraitSet rtsMerge = existing.ResolvedTraits.MergeSet(toMerge.ResolvedTraits); // newest one may replace
                        if (rtsMerge != existing.ResolvedTraits)
                        {
                            rasResult = rasResult.Copy(); // copy on write
                            existing  = rasResult.ResolvedName2resolvedAttribute[toMerge.ResolvedName];
                            existing.ResolvedTraits = rtsMerge;
                        }
                    }
                }
                else
                {
                    if (this.RefCnt > 1)
                    {
                        rasResult = rasResult.Copy(); // copy on write
                    }
                    if (rasResult == null)
                    {
                        rasResult = this;
                    }
                    rasResult.ResolvedName2resolvedAttribute.Add(toMerge.ResolvedName, toMerge);
                    //toMerge.InsertOrder = rasResult.Set.Count;
                    rasResult.Set.Add(toMerge);
                    rasResult.ResolvedAttributeCount += toMerge.ResolvedAttributeCount;
                }
                this.BaseTrait2Attributes = null;
            }
            return(rasResult);
        }