The Labs \ Source Viewer \ SSCLI \ System.Xml.Xsl.Qil \ QilCloneVisitor

  1. //------------------------------------------------------------------------------
  2. // <copyright file="QilCloneVisitor.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Diagnostics;
  18. using System.Xml;
  19. using System.Xml.Xsl;
  20. namespace System.Xml.Xsl.Qil
  21. {
  22.    
  23.     // Create an exact replica of a QIL graph
  24.     internal class QilCloneVisitor : QilScopedVisitor
  25.     {
  26.         private QilFactory fac;
  27.         private SubstitutionList subs;
  28.        
  29.        
  30.         //-----------------------------------------------
  31.         // Constructors
  32.         //-----------------------------------------------
  33.        
  34.         public QilCloneVisitor(QilFactory fac) : this(fac, new SubstitutionList())
  35.         {
  36.         }
  37.        
  38.         public QilCloneVisitor(QilFactory fac, SubstitutionList subs)
  39.         {
  40.             this.fac = fac;
  41.             this.subs = subs;
  42.         }
  43.        
  44.        
  45.         //-----------------------------------------------
  46.         // Entry
  47.         //-----------------------------------------------
  48.        
  49.         public QilNode Clone(QilNode node)
  50.         {
  51.             // Assume that iterator nodes at the top-level are references rather than definitions
  52.             return VisitAssumeReference(node);
  53.         }
  54.        
  55.        
  56.         //-----------------------------------------------
  57.         // QilVisitor overrides
  58.         //-----------------------------------------------
  59.        
  60.         /// <summary>
  61.         /// Visit all children of "parent", replacing each child with a copy of each child.
  62.         /// </summary>
  63.         protected override QilNode Visit(QilNode oldNode)
  64.         {
  65.             QilNode newNode = null;
  66.            
  67.             if (oldNode == null)
  68.                 return null;
  69.            
  70.             // ShallowClone any nodes which have not yet been cloned
  71.             if (oldNode is QilReference) {
  72.                 // Reference nodes may have been cloned previously and put into scope
  73.                 newNode = FindClonedReference(oldNode);
  74.             }
  75.            
  76.             if (newNode == null)
  77.                 newNode = oldNode.ShallowClone(this.fac);
  78.            
  79.             return base.Visit(newNode);
  80.         }
  81.        
  82.         /// <summary>
  83.         /// Visit all children of "parent", replacing each child with a copy of each child.
  84.         /// </summary>
  85.         protected override QilNode VisitChildren(QilNode parent)
  86.         {
  87.             // Visit children
  88.             for (int i = 0; i < parent.Count; i++) {
  89.                 QilNode child = parent[i];
  90.                
  91.                 // If child is a reference,
  92.                 if (IsReference(parent, i)) {
  93.                     // Visit the reference and substitute its copy
  94.                     parent[i] = VisitReference(child);
  95.                    
  96.                     // If no substutition found, then use original child
  97.                     if (parent[i] == null)
  98.                         parent[i] = child;
  99.                 }
  100.                 else {
  101.                     // Otherwise, visit the node and substitute its copy
  102.                     parent[i] = Visit(child);
  103.                 }
  104.             }
  105.            
  106.             return parent;
  107.         }
  108.        
  109.         /// <summary>
  110.         /// If a cloned reference is in scope, replace "oldNode". Otherwise, return "oldNode".
  111.         /// </summary>
  112.         protected override QilNode VisitReference(QilNode oldNode)
  113.         {
  114.             QilNode newNode = FindClonedReference(oldNode);
  115.             return base.VisitReference(newNode == null ? oldNode : newNode);
  116.         }
  117.        
  118.        
  119.         //-----------------------------------------------
  120.         // QilScopedVisitor methods
  121.         //-----------------------------------------------
  122.        
  123.         /// <summary>
  124.         /// Push node and its shallow clone onto the substitution list.
  125.         /// </summary>
  126.         protected override void BeginScope(QilNode node)
  127.         {
  128.             this.subs.AddSubstitutionPair(node, node.ShallowClone(this.fac));
  129.         }
  130.        
  131.         /// <summary>
  132.         /// Pop entry from substitution list.
  133.         /// </summary>
  134.         protected override void EndScope(QilNode node)
  135.         {
  136.             this.subs.RemoveLastSubstitutionPair();
  137.         }
  138.        
  139.        
  140.         //-----------------------------------------------
  141.         // QilCloneVisitor methods
  142.         //-----------------------------------------------
  143.        
  144.         /// <summary>
  145.         /// Find the clone of an in-scope reference.
  146.         /// </summary>
  147.         protected QilNode FindClonedReference(QilNode node)
  148.         {
  149.             return this.subs.FindReplacement(node);
  150.         }
  151.     }
  152. }

Developer Fusion