|
//------------------------------------------------------------------------------
// <copyright file="QilScopedVisitor.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">Microsoft</owner>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
namespace System.Xml.Xsl.Qil {
/// <summary>
/// Adds iterator and function scoping to the QilVisitor implementation.
/// </summary>
internal class QilScopedVisitor : QilVisitor {
//-----------------------------------------------
// QilScopedVisitor methods
//-----------------------------------------------
/// <summary>
/// Called when a variable, parameter, or function enters scope.
/// </summary>
protected virtual void BeginScope(QilNode node) {
}
/// <summary>
/// Called when a variable, parameter, or function exits scope.
/// </summary>
protected virtual void EndScope(QilNode node) {
}
/// <summary>
/// Called at the beginning of Visit().
/// </summary>
protected virtual void BeforeVisit(QilNode node) {
QilExpression qil;
switch (node.NodeType) {
case QilNodeType.QilExpression:
// Put all global functions, variables, and parameters in scope
qil = (QilExpression) node;
foreach (QilNode param in qil.GlobalParameterList) BeginScope(param);
foreach (QilNode var in qil.GlobalVariableList) BeginScope(var);
foreach (QilNode func in qil.FunctionList) BeginScope(func);
break;
case QilNodeType.Function:
// Put all formal arguments in scope
foreach (QilNode arg in ((QilFunction) node).Arguments) BeginScope(arg);
break;
case QilNodeType.Loop:
case QilNodeType.Filter:
case QilNodeType.Sort:
// Put loop iterator in scope
BeginScope(((QilLoop) node).Variable);
break;
}
}
/// <summary>
/// Called at the end of Visit().
/// </summary>
protected virtual void AfterVisit(QilNode node) {
QilExpression qil;
switch (node.NodeType) {
case QilNodeType.QilExpression:
// Remove all global functions, variables, and parameters from scope
qil = (QilExpression) node;
foreach (QilNode func in qil.FunctionList) EndScope(func);
foreach (QilNode var in qil.GlobalVariableList) EndScope(var);
foreach (QilNode param in qil.GlobalParameterList) EndScope(param);
break;
case QilNodeType.Function:
// Remove all formal arguments from scope
foreach (QilNode arg in ((QilFunction) node).Arguments) EndScope(arg);
break;
case QilNodeType.Loop:
case QilNodeType.Filter:
case QilNodeType.Sort:
// Remove loop iterator in scope
EndScope(((QilLoop) node).Variable);
break;
}
}
//-----------------------------------------------
// QilVisitor overrides
//-----------------------------------------------
/// <summary>
/// Call BeforeVisit() and AfterVisit().
/// </summary>
protected override QilNode Visit(QilNode n) {
QilNode ret;
BeforeVisit(n);
ret = base.Visit(n);
AfterVisit(n);
return ret;
}
}
}
|