/*
The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language
governing rights and limitations under the License.
The Original Code is RAIL(Runtime Assembly Instrumentation Library) Alpha Version.
The Initial Developer of the Original Code is University of Coimbra,
Computer Science Department, Dependable Systems Group. Copyright (C) University of Coimbra.
All Rights Reserved.
*/
using System;
using Rail.Reflect;
namespace Rail.Transformation{
/// <summary>
/// Possible orders in which a descent can be organized
/// </summary>
public enum TraversalOrder {
PostOrder,
PreOrder
}
/// <summary>
/// Controls the traversal order.
/// </summary>
internal abstract class Walker {
protected readonly Visitor visitor;
/// <summary>
/// </summary>
/// <param name="visitor">The visitor corresponding to this walker.</param>
public Walker(Visitor visitor) {
this.visitor = visitor;
}
/// <summary>
///
/// </summary>
/// <param name="assm"></param>
abstract public void WalkAssembly(RAssemblyDef assm);
/// <summary>
///
/// </summary>
/// <param name="module"></param>
abstract public void WalkModule(RModuleDef module);
/// <summary>
///
/// </summary>
/// <param name="type"></param>
abstract public void WalkType(RTypeDef type);
/// <summary>
///
/// </summary>
/// <param name="property"></param>
abstract public void WalkProperty(RPropertyDef property);
/// <summary>
///
/// </summary>
/// <param name="field"></param>
abstract public void WalkField(RFieldDef field);
/// <summary>
///
/// </summary>
/// <param name="method"></param>
abstract public void WalkMethod(RMethodDef method);
/// <summary>
///
/// </summary>
/// <param name="ctor"></param>
abstract public void WalkConstructor(RConstructorDef ctor);
/// <summary>
///
/// </summary>
/// <param name="evt"></param>
abstract public void WalkEvent(REventDef evt);
}
/// <summary>
/// The end nodes are treated the same way by every walker,
/// so it's better to place that code in a base class.
/// </summary>
internal abstract class BaseWalker : Walker {
/// <summary>
///
/// </summary>
/// <param name="v"></param>
public BaseWalker(Visitor v) : base(v) {}
/// <summary>
///
/// </summary>
/// <param name="property"></param>
override public void WalkProperty(RPropertyDef property) {
visitor.VisitProperty(property);
}
/// <summary>
///
/// </summary>
/// <param name="field"></param>
override public void WalkField(RFieldDef field) {
visitor.VisitField(field);
}
/// <summary>
///
/// </summary>
/// <param name="method"></param>
override public void WalkMethod(RMethodDef method) {
visitor.VisitMethod(method);
}
/// <summary>
///
/// </summary>
/// <param name="ctor"></param>
override public void WalkConstructor(RConstructorDef ctor) {
visitor.VisitConstructor(ctor);
}
/// <summary>
///
/// </summary>
/// <param name="evt"></param>
override public void WalkEvent(REventDef evt) {
visitor.VisitEvent(evt);
}
}
/// <summary>
/// Walks the hierarchy using a post-order traversal.
/// <remarks>
/// Post-order: subnodes visited before the current node
/// </remarks>
/// </summary>
internal class PostOrderWalker : BaseWalker {
/// <summary>
///
/// </summary>
/// <param name="v"></param>
public PostOrderWalker(Visitor v) : base(v) {}
/// <summary>
///
/// </summary>
/// <param name="assembly"></param>
override public void WalkAssembly(RAssemblyDef assembly) {
// Descends into the subelments
foreach (RModuleDef m in assembly.GetModules()) {
m.Accept(visitor);
}
// Calls the user defined visitor
visitor.VisitAssembly(assembly);
}
/// <summary>
///
/// </summary>
/// <param name="module"></param>
override public void WalkModule(RModuleDef module) {
// Descends into the subelments
foreach (RTypeDef t in module.GetTypes()) {
t.Accept(visitor);
}
// Calls the user defined visitor
visitor.VisitModule(module);
}
/// <summary>
///
/// </summary>
/// <param name="type"></param>
override public void WalkType(RTypeDef type) {
// Descends into the subelments
foreach (RConstructorDef ctor in type.GetConstructors()) {
ctor.Accept(visitor);
}
foreach (RMethodDef m in type.GetMethods()) {
m.Accept(visitor);
}
foreach (RFieldDef f in type.GetFields()) {
f.Accept(visitor);
}
foreach (RPropertyDef p in type.GetProperties()) {
p.Accept(visitor);
}
foreach (REventDef evt in type.GetEvents()) {
evt.Accept(visitor);
}
// Calls the user defined visitor
visitor.VisitType(type);
}
}
/// <summary>
/// Walks the hierarchy using a pre-order traversal.
/// <remarks>
/// Pre-order: current node visited before the subnodes
/// </remarks>
/// </summary>
internal class PreOrderWalker : BaseWalker {
/// <summary>
///
/// </summary>
/// <param name="v"></param>
public PreOrderWalker(Visitor v) : base(v) {}
/// <summary>
///
/// </summary>
/// <param name="assembly"></param>
override public void WalkAssembly(RAssemblyDef assembly) {
// Calls the user defined visitor
visitor.VisitAssembly(assembly);
// Descends into the subelments
foreach (RModuleDef m in assembly.GetModules()) {
m.Accept(visitor);
//This is a workaround because rail does not support Multiple modules
//yet
break;
}
}
/// <summary>
///
/// </summary>
/// <param name="module"></param>
override public void WalkModule(RModuleDef module) {
// Calls the user defined visitor
visitor.VisitModule(module);
// Descends into the subelments
foreach (RTypeDef t in module.GetTypes()) {
t.Accept(visitor);
}
}
/// <summary>
///
/// </summary>
/// <param name="type"></param>
override public void WalkType(RTypeDef type) {
// Calls the user defined visitor
visitor.VisitType(type);
// Descends into the subelments
foreach (RConstructorDef ctor in type.GetConstructors()) {
ctor.Accept(visitor);
}
foreach (RMethodDef m in type.GetMethods()) {
m.Accept(visitor);
}
foreach (RFieldDef f in type.GetFields()) {
f.Accept(visitor);
}
foreach (RPropertyDef p in type.GetProperties()) {
p.Accept(visitor);
}
foreach (REventDef evt in type.GetEvents()) {
evt.Accept(visitor);
}
}
}
}
|