Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Data.SqlXml / System / Xml / Xsl / QIL / QilScopedVisitor.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="QilScopedVisitor.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">Microsoft</owner>
6 //------------------------------------------------------------------------------
7 using System;
8 using System.Collections.Generic;
9
10 namespace System.Xml.Xsl.Qil {
11
12     /// <summary>
13     /// Adds iterator and function scoping to the QilVisitor implementation.
14     /// </summary>
15     internal class QilScopedVisitor : QilVisitor {
16
17         //-----------------------------------------------
18         // QilScopedVisitor methods
19         //-----------------------------------------------
20
21         /// <summary>
22         /// Called when a variable, parameter, or function enters scope.
23         /// </summary>
24         protected virtual void BeginScope(QilNode node) {
25         }
26
27         /// <summary>
28         /// Called when a variable, parameter, or function exits scope.
29         /// </summary>
30         protected virtual void EndScope(QilNode node) {
31         }
32
33         /// <summary>
34         /// Called at the beginning of Visit().
35         /// </summary>
36         protected virtual void BeforeVisit(QilNode node) {
37             QilExpression qil;
38
39             switch (node.NodeType) {
40                 case QilNodeType.QilExpression:
41                     // Put all global functions, variables, and parameters in scope
42                     qil = (QilExpression) node;
43                     foreach (QilNode param in qil.GlobalParameterList) BeginScope(param);
44                     foreach (QilNode var in qil.GlobalVariableList) BeginScope(var);
45                     foreach (QilNode func in qil.FunctionList) BeginScope(func);
46                     break;
47
48                 case QilNodeType.Function:
49                     // Put all formal arguments in scope
50                     foreach (QilNode arg in ((QilFunction) node).Arguments) BeginScope(arg);
51                     break;
52
53                 case QilNodeType.Loop:
54                 case QilNodeType.Filter:
55                 case QilNodeType.Sort:
56                     // Put loop iterator in scope
57                     BeginScope(((QilLoop) node).Variable);
58                     break;
59             }
60         }
61
62         /// <summary>
63         /// Called at the end of Visit().
64         /// </summary>
65         protected virtual void AfterVisit(QilNode node) {
66             QilExpression qil;
67
68             switch (node.NodeType) {
69                 case QilNodeType.QilExpression:
70                     // Remove all global functions, variables, and parameters from scope
71                     qil = (QilExpression) node;
72                     foreach (QilNode func in qil.FunctionList) EndScope(func);
73                     foreach (QilNode var in qil.GlobalVariableList) EndScope(var);
74                     foreach (QilNode param in qil.GlobalParameterList) EndScope(param);
75                     break;
76
77                 case QilNodeType.Function:
78                     // Remove all formal arguments from scope
79                     foreach (QilNode arg in ((QilFunction) node).Arguments) EndScope(arg);
80                     break;
81
82                 case QilNodeType.Loop:
83                 case QilNodeType.Filter:
84                 case QilNodeType.Sort:
85                     // Remove loop iterator in scope
86                     EndScope(((QilLoop) node).Variable);
87                     break;
88             }
89         }
90
91
92         //-----------------------------------------------
93         // QilVisitor overrides
94         //-----------------------------------------------
95
96         /// <summary>
97         /// Call BeforeVisit() and AfterVisit().
98         /// </summary>
99         protected override QilNode Visit(QilNode n) {
100             QilNode ret;
101             BeforeVisit(n);
102             ret = base.Visit(n);
103             AfterVisit(n);
104             return ret;
105         }
106     }
107 }