Esempio n. 1
0
        // At end of parse, removes and returns all remaining simple fixups, whether or not they
        // are resolved
        public IEnumerable <NameFixupToken> GetRemainingSimpleFixups()
        {
            foreach (object key in _dependenciesByParentObject.Keys)
            {
                _uninitializedObjectsAtParseEnd.Add(key);
            }

            List <string> names = new List <string>(_dependenciesByName.Keys);

            foreach (string name in names)
            {
                FrugalObjectList <NameFixupToken> dependencies = _dependenciesByName[name];
                int i = 0;
                while (i < dependencies.Count)
                {
                    NameFixupToken token = dependencies[i];
                    if (!token.CanAssignDirectly)
                    {
                        i++;
                        continue;
                    }
                    dependencies.RemoveAt(i);
                    if (dependencies.Count == 0)
                    {
                        _dependenciesByName.Remove(name);
                    }
                    RemoveTokenByParent(token);
                    yield return(token);
                }
            }
        }
Esempio n. 2
0
        public IEnumerable <NameFixupToken> GetRemainingSimpleFixups()
        {
            foreach (object obj2 in this._dependenciesByParentObject.Keys)
            {
                this._uninitializedObjectsAtParseEnd.Add(obj2);
            }
            List <string> iteratorVariable0 = new List <string>(this._dependenciesByName.Keys);

            foreach (string iteratorVariable1 in iteratorVariable0)
            {
                FrugalObjectList <NameFixupToken> iteratorVariable2 = this._dependenciesByName[iteratorVariable1];
                int index = 0;
                while (index < iteratorVariable2.Count)
                {
                    NameFixupToken token = iteratorVariable2[index];
                    if (!token.CanAssignDirectly)
                    {
                        index++;
                        continue;
                    }
                    iteratorVariable2.RemoveAt(index);
                    if (iteratorVariable2.Count == 0)
                    {
                        this._dependenciesByName.Remove(iteratorVariable1);
                    }
                    this.RemoveTokenByParent(token);
                    yield return(token);
                }
            }
        }
Esempio n. 3
0
        // Finds the names that this object's subtree is blocked on.
        public void GetDependentNames(object instance, List <string> result)
        {
            // We're only interested in the immediate subtree, not named-references to other subtrees
            // that might exist but not be fully initialized. So we only follow UnresolvedChildren and
            // MarkupExtensionFirstRun edges, which means there is no risk of cycles
            FrugalObjectList <NameFixupToken> dependencies;

            if (!_dependenciesByParentObject.TryGetValue(instance, out dependencies))
            {
                return;
            }
            for (int i = 0; i < dependencies.Count; i++)
            {
                NameFixupToken token = dependencies[i];
                if (token.FixupType == FixupType.MarkupExtensionFirstRun ||
                    token.FixupType == FixupType.UnresolvedChildren)
                {
                    GetDependentNames(token.ReferencedObject, result);
                }
                else if (token.NeededNames != null)
                {
                    foreach (string name in token.NeededNames)
                    {
                        if (!result.Contains(name))
                        {
                            result.Add(name);
                        }
                    }
                }
            }
        }
Esempio n. 4
0
 private bool FindDependencies(NameFixupToken inEdge, List <NameFixupToken> alreadyTraversed)
 {
     if (!alreadyTraversed.Contains(inEdge))
     {
         FrugalObjectList <NameFixupToken> list;
         alreadyTraversed.Add(inEdge);
         if ((inEdge.ReferencedObject == null) || !this._dependenciesByParentObject.TryGetValue(inEdge.ReferencedObject, out list))
         {
             return(true);
         }
         for (int i = 0; i < list.Count; i++)
         {
             NameFixupToken token = list[i];
             if (token.FixupType == FixupType.MarkupExtensionFirstRun)
             {
                 return(false);
             }
             if (!this.FindDependencies(token, alreadyTraversed))
             {
                 return(false);
             }
         }
     }
     return(true);
 }
Esempio n. 5
0
        // Depth-first traversal of the graph starting at a given edge. Ignores edges that would cause cycles.
        // Returns true if the dependency list is complete, false if we aborted because we found an ME.
        private bool FindDependencies(NameFixupToken inEdge, List <NameFixupToken> alreadyTraversed)
        {
            if (alreadyTraversed.Contains(inEdge))
            {
                // Cycle, skip it
                return(true);
            }
            alreadyTraversed.Add(inEdge);
            FrugalObjectList <NameFixupToken> outEdges;

            if (inEdge.ReferencedObject == null ||
                !_dependenciesByParentObject.TryGetValue(inEdge.ReferencedObject, out outEdges))
            {
                // No dependencies, we're done with this subgraph
                return(true);
            }
            for (int i = 0; i < outEdges.Count; i++)
            {
                NameFixupToken outEdge = outEdges[i];
                if (outEdge.FixupType == FixupType.MarkupExtensionFirstRun)
                {
                    return(false);
                }
                Debug.Assert(outEdge.FixupType == FixupType.UnresolvedChildren);
                if (!FindDependencies(outEdge, alreadyTraversed))
                {
                    return(false);
                }
            }
            return(true);
        }
Esempio n. 6
0
        public void GetDependentNames(object instance, List <string> result)
        {
            FrugalObjectList <NameFixupToken> list;

            if (this._dependenciesByParentObject.TryGetValue(instance, out list))
            {
                for (int i = 0; i < list.Count; i++)
                {
                    NameFixupToken token = list[i];
                    if ((token.FixupType == FixupType.MarkupExtensionFirstRun) || (token.FixupType == FixupType.UnresolvedChildren))
                    {
                        this.GetDependentNames(token.ReferencedObject, result);
                    }
                    else if (token.NeededNames != null)
                    {
                        foreach (string str in token.NeededNames)
                        {
                            if (!result.Contains(str))
                            {
                                result.Add(str);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 7
0
        public void AddEndOfParseDependency(object childThatHasUnresolvedChildren, FixupTarget parentObject)
        {
            NameFixupToken token = new NameFixupToken {
                Target           = parentObject,
                FixupType        = FixupType.UnresolvedChildren,
                ReferencedObject = childThatHasUnresolvedChildren
            };

            AddToMultiDict <object>(this._dependenciesByParentObject, parentObject.Instance, token);
        }
Esempio n. 8
0
        public void AddEndOfParseDependency(object childThatHasUnresolvedChildren, FixupTarget parentObject)
        {
            NameFixupToken token = new NameFixupToken();

            token.Target           = parentObject;
            token.FixupType        = FixupType.UnresolvedChildren;
            token.ReferencedObject = childThatHasUnresolvedChildren;
            AddToMultiDict(_dependenciesByParentObject, parentObject.Instance, token);
            // We don't add to the _dependenciesByChildObject, because at end-of-parse, a single
            // child object can be a dependency of multiple parents
        }
Esempio n. 9
0
        // Remove a resolved dependency from the graph.
        // Enqueues all removed edges so that the ObjectWriter can process the dependents
        // (rerun converters, apply simple fixups, call EndInit on parent ojects, etc).
        public void ResolveDependenciesTo(object instance, string name)
        {
            // Remove any dependency on this instance
            NameFixupToken token = null;

            if (instance != null)
            {
                if (_dependenciesByChildObject.TryGetValue(instance, out token))
                {
                    _dependenciesByChildObject.Remove(instance);
                    RemoveTokenByParent(token);
                    _resolvedTokensPendingProcessing.Enqueue(token);
                }
            }

            // Remove any dependencies on this name, and return any tokens whose dependencies
            // have all been resolved.
            FrugalObjectList <NameFixupToken> nameDependencies;

            if (name != null && _dependenciesByName.TryGetValue(name, out nameDependencies))
            {
                int i = 0;
                while (i < nameDependencies.Count)
                {
                    token = nameDependencies[i];

                    // The same name can occur in multiple namescopes, so we need to make sure that
                    // this named object is visible in the scope of the token.
                    object resolvedName = token.ResolveName(name);
                    if (instance != resolvedName)
                    {
                        i++;
                        continue;
                    }

                    if (token.CanAssignDirectly)
                    {
                        // For simple fixups, we need to return the resolved object
                        token.ReferencedObject = instance;
                    }
                    token.NeededNames.Remove(name);
                    nameDependencies.RemoveAt(i);
                    if (nameDependencies.Count == 0)
                    {
                        _dependenciesByName.Remove(name);
                    }
                    if (token.NeededNames.Count == 0)
                    {
                        RemoveTokenByParent(token);
                        _resolvedTokensPendingProcessing.Enqueue(token);
                    }
                }
            }
        }
Esempio n. 10
0
        private static void AddToMultiDict <TKey>(Dictionary <TKey, FrugalObjectList <NameFixupToken> > dict,
                                                  TKey key, NameFixupToken value)
        {
            FrugalObjectList <NameFixupToken> tokenList;

            if (!dict.TryGetValue(key, out tokenList))
            {
                tokenList = new FrugalObjectList <NameFixupToken>(1);
                dict.Add(key, tokenList);
            }
            tokenList.Add(value);
        }
Esempio n. 11
0
        private void RemoveTokenByParent(NameFixupToken token)
        {
            object instance = token.Target.Instance;
            FrugalObjectList <NameFixupToken> list = this._dependenciesByParentObject[instance];

            if (list.Count == 1)
            {
                this._dependenciesByParentObject.Remove(instance);
            }
            else
            {
                list.Remove(token);
            }
        }
Esempio n. 12
0
        private void RemoveTokenByParent(NameFixupToken token)
        {
            object parentInstance = token.Target.Instance;
            FrugalObjectList <NameFixupToken> parentDependencies = _dependenciesByParentObject[parentInstance];

            Debug.Assert(parentDependencies.Contains(token));

            if (parentDependencies.Count == 1)
            {
                _dependenciesByParentObject.Remove(parentInstance);
            }
            else
            {
                parentDependencies.Remove(token);
            }
        }
Esempio n. 13
0
        // Add an edge to the graph. We need to look up edges in both directions, so each edge is
        // stored in two dictionaries.
        public void AddDependency(NameFixupToken fixupToken)
        {
            // Need to special case a deferred ProvideValue at the root, because it has no parent
            if (fixupToken.Target.Property == null)
            {
                Debug.Assert(fixupToken.Target.Instance == null &&
                             fixupToken.Target.InstanceType == null &&
                             fixupToken.FixupType == FixupType.MarkupExtensionFirstRun);
                Debug.Assert(_deferredRootProvideValue == null);
                _deferredRootProvideValue = fixupToken;
                return;
            }

            object parentObject = fixupToken.Target.Instance;

            // References aren't allowed in non-instantiating directives, except for:
            // - Initialization, in which case FixupTarget.Instance is the object whose property the
            //   initialized object will be assigned to; and
            // - Key, in which case the FixupTarget.Instance is the dictionary
            Debug.Assert(parentObject != null);

            AddToMultiDict(_dependenciesByParentObject, parentObject, fixupToken);

            if (fixupToken.ReferencedObject != null)
            {
                Debug.Assert(fixupToken.FixupType == FixupType.UnresolvedChildren ||
                             fixupToken.FixupType == FixupType.MarkupExtensionFirstRun);
                // These fixups are only used for the immediate parent of the object, so there can
                // only be one per child instance
                Debug.Assert(!_dependenciesByChildObject.ContainsKey(fixupToken.ReferencedObject));

                _dependenciesByChildObject.Add(fixupToken.ReferencedObject, fixupToken);
            }
            else
            {
                Debug.Assert(fixupToken.FixupType != FixupType.UnresolvedChildren &&
                             fixupToken.FixupType != FixupType.MarkupExtensionFirstRun);

                foreach (string name in fixupToken.NeededNames)
                {
                    AddToMultiDict(_dependenciesByName, name, fixupToken);
                }
            }
        }
Esempio n. 14
0
        public void ResolveDependenciesTo(object instance, string name)
        {
            NameFixupToken token = null;
            FrugalObjectList <NameFixupToken> list;

            if ((instance != null) && this._dependenciesByChildObject.TryGetValue(instance, out token))
            {
                this._dependenciesByChildObject.Remove(instance);
                this.RemoveTokenByParent(token);
                this._resolvedTokensPendingProcessing.Enqueue(token);
            }
            if ((name != null) && this._dependenciesByName.TryGetValue(name, out list))
            {
                int index = 0;
                while (index < list.Count)
                {
                    token = list[index];
                    object obj2 = token.ResolveName(name);
                    if (instance != obj2)
                    {
                        index++;
                    }
                    else
                    {
                        if (token.CanAssignDirectly)
                        {
                            token.ReferencedObject = instance;
                        }
                        token.NeededNames.Remove(name);
                        list.RemoveAt(index);
                        if (list.Count == 0)
                        {
                            this._dependenciesByName.Remove(name);
                        }
                        if (token.NeededNames.Count == 0)
                        {
                            this.RemoveTokenByParent(token);
                            this._resolvedTokensPendingProcessing.Enqueue(token);
                        }
                    }
                }
            }
        }
Esempio n. 15
0
        // At end of parse, removes and returns all remaining reparse fixups, whether or not they
        // are resolved. Assumes that all simple fixups have already been removed.
        public IEnumerable <NameFixupToken> GetRemainingReparses()
        {
            List <object> parentObjs = new List <object>(_dependenciesByParentObject.Keys);

            foreach (object parentObj in parentObjs)
            {
                FrugalObjectList <NameFixupToken> dependencies = _dependenciesByParentObject[parentObj];
                int i = 0;
                while (i < dependencies.Count)
                {
                    NameFixupToken token = dependencies[i];
                    if (token.FixupType == FixupType.MarkupExtensionFirstRun ||
                        token.FixupType == FixupType.UnresolvedChildren)
                    {
                        i++;
                        continue;
                    }

                    // Remove this token from the _dependenciesByParentObject dictionary
                    dependencies.RemoveAt(i);
                    if (dependencies.Count == 0)
                    {
                        _dependenciesByParentObject.Remove(parentObj);
                    }

                    // Remove this token from the _dependenciesByName dictionary
                    foreach (string name in token.NeededNames)
                    {
                        FrugalObjectList <NameFixupToken> nameDependencies = _dependenciesByName[name];
                        if (nameDependencies.Count == 1)
                        {
                            nameDependencies.Remove(token);
                        }
                        else
                        {
                            _dependenciesByName.Remove(name);
                        }
                    }

                    yield return(token);
                }
            }
        }
Esempio n. 16
0
 public void AddDependency(NameFixupToken fixupToken)
 {
     if (fixupToken.Target.Property == null)
     {
         this._deferredRootProvideValue = fixupToken;
     }
     else
     {
         object instance = fixupToken.Target.Instance;
         AddToMultiDict <object>(this._dependenciesByParentObject, instance, fixupToken);
         if (fixupToken.ReferencedObject != null)
         {
             this._dependenciesByChildObject.Add(fixupToken.ReferencedObject, fixupToken);
         }
         else
         {
             foreach (string str in fixupToken.NeededNames)
             {
                 AddToMultiDict <string>(this._dependenciesByName, str, fixupToken);
             }
         }
     }
 }
Esempio n. 17
0
        public IEnumerable <NameFixupToken> GetRemainingReparses()
        {
            List <object> iteratorVariable0 = new List <object>(this._dependenciesByParentObject.Keys);

            foreach (object iteratorVariable1 in iteratorVariable0)
            {
                FrugalObjectList <NameFixupToken> iteratorVariable2 = this._dependenciesByParentObject[iteratorVariable1];
                int index = 0;
                while (index < iteratorVariable2.Count)
                {
                    NameFixupToken iteratorVariable4 = iteratorVariable2[index];
                    if ((iteratorVariable4.FixupType == FixupType.MarkupExtensionFirstRun) || (iteratorVariable4.FixupType == FixupType.UnresolvedChildren))
                    {
                        index++;
                        continue;
                    }
                    iteratorVariable2.RemoveAt(index);
                    if (iteratorVariable2.Count == 0)
                    {
                        this._dependenciesByParentObject.Remove(iteratorVariable1);
                    }
                    foreach (string str in iteratorVariable4.NeededNames)
                    {
                        FrugalObjectList <NameFixupToken> list = this._dependenciesByName[str];
                        if (list.Count == 1)
                        {
                            list.Remove(iteratorVariable4);
                        }
                        else
                        {
                            this._dependenciesByName.Remove(str);
                        }
                    }
                    yield return(iteratorVariable4);
                }
            }
        }
 private NameFixupToken GetTokenForUnresolvedChildren(object childThatHasUnresolvedChildren, XamlMember property, XamlSavedContext deferredMarkupExtensionContext)
 {
     NameFixupToken token = new NameFixupToken();
     if (deferredMarkupExtensionContext != null)
     {
         token.FixupType = FixupType.MarkupExtensionFirstRun;
         token.SavedContext = deferredMarkupExtensionContext;
     }
     else
     {
         token.FixupType = FixupType.UnresolvedChildren;
     }
     token.ReferencedObject = childThatHasUnresolvedChildren;
     token.Target.Property = property;
     return token;
 }
 private void ProcessNameFixup_UpdatePendingAddKey(NameFixupToken token, object key)
 {
     if (token.Target.KeyHolder != null)
     {
         token.Target.KeyHolder.Key = key;
     }
     else if (token.Target.TemporaryCollectionIndex >= 0)
     {
         List<PendingCollectionAdd> list = this.PendingCollectionAdds[token.Target.Instance];
         PendingCollectionAdd add = list[token.Target.TemporaryCollectionIndex];
         add.Key = key;
         add.KeyIsSet = true;
     }
 }
 private void ProcessNameFixup_UpdatePendingAddItem(NameFixupToken token, object item)
 {
     List<PendingCollectionAdd> list = this.PendingCollectionAdds[token.Target.Instance];
     PendingCollectionAdd add = list[token.Target.TemporaryCollectionIndex];
     add.Item = item;
     if (!(item is NameFixupToken))
     {
         add.ItemType = (item != null) ? this.GetXamlType(item.GetType()) : null;
     }
 }
 private void ProcessNameFixup_Simple(NameFixupToken token)
 {
     object referencedObject = token.ReferencedObject;
     if (token.Target.Property == XamlLanguage.Key)
     {
         this.ProcessNameFixup_UpdatePendingAddKey(token, referencedObject);
     }
     else if (token.Target.Property == XamlLanguage.Items)
     {
         this.ProcessNameFixup_UpdatePendingAddItem(token, referencedObject);
     }
     else
     {
         this.SetValue(token.Target.Instance, token.Target.Property, referencedObject);
     }
 }
        private void ProcessNameFixup_Reparse(NameFixupToken token, bool nameResolutionIsComplete)
        {
            object obj2 = null;
            ObjectWriterContext targetContext = token.TargetContext;
            targetContext.NameResolutionComplete = nameResolutionIsComplete;
            targetContext.IsInitializedCallback = this;
            switch (token.FixupType)
            {
                case FixupType.MarkupExtensionFirstRun:
                    if (!this.Logic_ProvideValue(targetContext))
                    {
                        break;
                    }
                    return;

                case FixupType.MarkupExtensionRerun:
                    obj2 = this.Runtime.CallProvideValue((MarkupExtension) targetContext.CurrentInstance, targetContext.ServiceProviderContext);
                    targetContext.CurrentInstance = obj2;
                    break;

                case FixupType.PropertyValue:
                    obj2 = this.Logic_CreateFromValue(targetContext, targetContext.ParentProperty.TypeConverter, targetContext.CurrentInstance, targetContext.ParentProperty, targetContext.ParentProperty.Name, token);
                    token.TargetContext.CurrentInstance = obj2;
                    break;

                case FixupType.ObjectInitializationValue:
                    this.Logic_CreateFromInitializationValue(targetContext);
                    if (token.TargetContext.CurrentInstanceRegisteredName != null)
                    {
                        this.Logic_RegisterName_OnCurrent(token.TargetContext, token.TargetContext.CurrentInstanceRegisteredName);
                    }
                    break;
            }
            if (token.Target.Property == XamlLanguage.Key)
            {
                this.ProcessNameFixup_UpdatePendingAddKey(token, targetContext.CurrentInstance);
            }
            else if (token.Target.Property == XamlLanguage.Items)
            {
                this.ProcessNameFixup_UpdatePendingAddItem(token, targetContext.CurrentInstance);
            }
            else if (token.Target.Property != null)
            {
                this.Logic_DoAssignmentToParentProperty(targetContext);
            }
            else
            {
                this._lastInstance = targetContext.CurrentInstance;
            }
            NameFixupToken currentInstance = targetContext.CurrentInstance as NameFixupToken;
            if (currentInstance != null)
            {
                currentInstance.Target = token.Target;
                currentInstance.LineNumber = token.LineNumber;
                currentInstance.LinePosition = token.LinePosition;
                if ((token.Target.Property == XamlLanguage.Key) || (token.Target.Property == XamlLanguage.Items))
                {
                    this._nameFixupGraph.AddDependency(currentInstance);
                }
            }
        }
 private void ProcessNameFixup(NameFixupToken token, bool nameResolutionIsComplete)
 {
     IAddLineInfo lineInfo = this.Runtime.LineInfo;
     try
     {
         this.Runtime.LineInfo = token;
         if (token.CanAssignDirectly)
         {
             this.ProcessNameFixup_Simple(token);
         }
         else if (token.FixupType != FixupType.UnresolvedChildren)
         {
             this.ProcessNameFixup_Reparse(token, nameResolutionIsComplete);
         }
     }
     finally
     {
         this.Runtime.LineInfo = lineInfo;
     }
 }
 private void PendCurrentFixupToken_SetValue(NameFixupToken token)
 {
     token.LineNumber = this._lineNumber;
     token.LinePosition = this._linePosition;
     token.Runtime = this.Runtime;
     this.NameFixupGraph.AddDependency(token);
 }
 private void Logic_PendKeyFixupToken(ObjectWriterContext ctx, NameFixupToken token)
 {
     token.Target.Instance = ctx.GrandParentInstance;
     token.Target.InstanceType = ctx.GrandParentType;
     token.Target.InstanceWasGotten = ctx.GrandParentIsObjectFromMember;
     FixupTargetKeyHolder holder = new FixupTargetKeyHolder(token);
     token.Target.KeyHolder = holder;
     ctx.ParentKey = holder;
     if (token.Target.Instance != null)
     {
         this.PendCurrentFixupToken_SetValue(token);
     }
 }
 object IXamlNameResolver.GetFixupToken(IEnumerable<string> names, bool canAssignDirectly)
 {
     if (this._xamlContext.NameResolutionComplete)
     {
         return null;
     }
     NameFixupToken token = new NameFixupToken {
         CanAssignDirectly = canAssignDirectly
     };
     token.NeededNames.AddRange(names);
     if (token.CanAssignDirectly && (token.NeededNames.Count != 1))
     {
         throw new ArgumentException(System.Xaml.SR.Get("SimpleFixupsMustHaveOneName"), "names");
     }
     if (this._xamlContext.CurrentType == null)
     {
         if (this._xamlContext.ParentProperty == XamlLanguage.Initialization)
         {
             token.FixupType = FixupType.ObjectInitializationValue;
             token.Target.Instance = this._xamlContext.GrandParentInstance;
             token.Target.InstanceWasGotten = this._xamlContext.GrandParentIsObjectFromMember;
             token.Target.InstanceType = this._xamlContext.GrandParentType;
             token.Target.Property = this._xamlContext.GrandParentProperty;
         }
         else
         {
             token.FixupType = FixupType.PropertyValue;
             token.Target.Instance = this._xamlContext.ParentInstance;
             token.Target.InstanceWasGotten = this._xamlContext.ParentIsObjectFromMember;
             token.Target.InstanceType = this._xamlContext.ParentType;
             token.Target.Property = this._xamlContext.ParentProperty;
         }
     }
     else
     {
         token.FixupType = FixupType.MarkupExtensionRerun;
         token.Target.Instance = this._xamlContext.ParentInstance;
         token.Target.InstanceWasGotten = this._xamlContext.ParentIsObjectFromMember;
         token.Target.InstanceType = this._xamlContext.ParentType;
         token.Target.Property = this._xamlContext.ParentProperty;
     }
     if (token.CanAssignDirectly)
     {
         token.NameScopeDictionaryList.AddRange(this._xamlContext.StackWalkOfNameScopes);
         return token;
     }
     token.SavedContext = this._xamlContext.GetSavedContext((token.FixupType == FixupType.MarkupExtensionRerun) ? SavedContextType.ReparseMarkupExtension : SavedContextType.ReparseValue);
     return token;
 }
Esempio n. 27
0
        public IEnumerable <NameFixupToken> GetRemainingObjectDependencies()
        {
            List <NameFixupToken> markupExtensionTokens = new List <NameFixupToken>();

            foreach (NameFixupToken token in this._dependenciesByChildObject.Values)
            {
                if (token.FixupType == FixupType.MarkupExtensionFirstRun)
                {
                    markupExtensionTokens.Add(token);
                }
            }
            while (markupExtensionTokens.Count > 0)
            {
                bool iteratorVariable1 = false;
                int  index             = 0;
                while (index < markupExtensionTokens.Count)
                {
                    NameFixupToken        inEdge           = markupExtensionTokens[index];
                    List <NameFixupToken> alreadyTraversed = new List <NameFixupToken>();
                    if (!this.FindDependencies(inEdge, alreadyTraversed))
                    {
                        index++;
                    }
                    else
                    {
                        for (int i = alreadyTraversed.Count - 1; i >= 0; i--)
                        {
                            NameFixupToken iteratorVariable6 = alreadyTraversed[i];
                            this.RemoveTokenByParent(iteratorVariable6);
                            yield return(iteratorVariable6);
                        }
                        iteratorVariable1 = true;
                        markupExtensionTokens.RemoveAt(index);
                    }
                }
                if (!iteratorVariable1)
                {
                    ThrowProvideValueCycle(markupExtensionTokens);
                }
            }
            while (this._dependenciesByParentObject.Count > 0)
            {
                FrugalObjectList <NameFixupToken> iteratorVariable7 = null;
                foreach (FrugalObjectList <NameFixupToken> list in this._dependenciesByParentObject.Values)
                {
                    iteratorVariable7 = list;
                    break;
                }
                for (int j = 0; j < iteratorVariable7.Count; j++)
                {
                    List <NameFixupToken> iteratorVariable9 = new List <NameFixupToken>();
                    this.FindDependencies(iteratorVariable7[j], iteratorVariable9);
                    for (int k = iteratorVariable9.Count - 1; k >= 0; k--)
                    {
                        NameFixupToken iteratorVariable11 = iteratorVariable9[k];
                        this.RemoveTokenByParent(iteratorVariable11);
                        yield return(iteratorVariable11);
                    }
                }
            }
            if (this._deferredRootProvideValue != null)
            {
                yield return(this._deferredRootProvideValue);
            }
            else
            {
                yield break;
            }
        }
Esempio n. 28
0
        // At end of parse, removes and returns all remaining MarkupExtensionFirstRun and UnresolvedChildren
        // tokens, even if they are not fully initialized. Assumes that all simple fixups and reparses have
        // already been removed.
        public IEnumerable <NameFixupToken> GetRemainingObjectDependencies()
        {
            // We'd like to return dependencies in a topologically sorted order, but the graph is
            // not acylic. (If it were, all references would have been resolved during the regular parse.)
            // However, we don't allow ProvideValue cycles. So find a MarkupExtension that doesn't have
            // dependencies on any other MarkupExtension.

            // Note: at this point we can't use _dependenciesByChildObject for general traversal,
            // because it's not updated by AddEndOfParseDependency. However, AddEndOfParseDependency
            // doesn't add MarkupExtension edges, so we can still use _dependenciesByChildObject for that.
            List <NameFixupToken> markupExtensionTokens = new List <NameFixupToken>();

            foreach (NameFixupToken curToken in _dependenciesByChildObject.Values)
            {
                if (curToken.FixupType == FixupType.MarkupExtensionFirstRun)
                {
                    markupExtensionTokens.Add(curToken);
                }
            }
            while (markupExtensionTokens.Count > 0)
            {
                bool found = false;
                int  i     = 0;
                while (i < markupExtensionTokens.Count)
                {
                    NameFixupToken        meToken      = markupExtensionTokens[i];
                    List <NameFixupToken> dependencies = new List <NameFixupToken>();
                    if (!FindDependencies(meToken, dependencies))
                    {
                        i++;
                        continue;
                    }
                    // Iterate the list in backwards order, so we return the deepest first
                    for (int j = dependencies.Count - 1; j >= 0; j--)
                    {
                        NameFixupToken token = dependencies[j];
                        RemoveTokenByParent(token);
                        yield return(token);
                    }
                    found = true;
                    markupExtensionTokens.RemoveAt(i);
                }
                if (!found)
                {
                    // We have MEs left, but they all have dependencies on other MEs.
                    // That means we have a cycle.
                    ThrowProvideValueCycle(markupExtensionTokens);
                }
            }

            // For the remaining EndInits, we pick an arbitrary point and return a DFS of its dependencies
            while (_dependenciesByParentObject.Count > 0)
            {
                FrugalObjectList <NameFixupToken> startNodeOutEdges = null;
                foreach (FrugalObjectList <NameFixupToken> list in _dependenciesByParentObject.Values)
                {
                    startNodeOutEdges = list;
                    break;
                }
                for (int i = 0; i < startNodeOutEdges.Count; i++)
                {
                    List <NameFixupToken> dependencies = new List <NameFixupToken>();
                    FindDependencies(startNodeOutEdges[i], dependencies);
                    // Iterate the list in backwards order, so we return the deepest first
                    for (int j = dependencies.Count - 1; j >= 0; j--)
                    {
                        NameFixupToken token = dependencies[j];
                        RemoveTokenByParent(token);
                        yield return(token);
                    }
                }
            }

            // Finally, if there was a deferred ProvideValue at the root, return it
            if (_deferredRootProvideValue != null)
            {
                yield return(_deferredRootProvideValue);
            }
        }