blob: 86d6a663bd14e4ebc32220662a6b7560b3c523f3 [file] [log] [blame]
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#pragma once
template <class Context>
class ParseNodeMutatorBase
{
public:
typedef Context Context;
};
template <typename Mutator, typename TContext = typename Mutator::Context>
struct ParseNodeMutatingVisitor : public Mutator
{
public:
typedef TContext Context;
typedef typename Mutator::Context MutatorContext;
class MutatorWalkerPolicy
{
public:
typedef bool ResultType;
typedef struct
{
MutatorContext mutatorContext;
ParseNodeMutatingVisitor<Mutator, Context> *mutator;
} Context;
inline bool DefaultResult() { return true; }
inline bool ContinueWalk(bool value) { return value; }
inline bool WalkNode(ParseNode *node, Context context) { return true; }
inline bool WalkListNode(ParseNode *node, Context context) { return true; }
inline bool WalkFirstChild(ParseNode *&node, Context context) { return context.mutator->Mutate(node, context.mutatorContext); }
inline bool WalkSecondChild(ParseNode *&node, Context context) { return context.mutator->Mutate(node, context.mutatorContext); }
inline bool WalkNthChild(ParseNode* pnodeParent, ParseNode *&node, Context context) { return context.mutator->Mutate(node, context.mutatorContext); }
};
// Warning: This contains an unsafe cast if TContext != Mutator::Context.
// If you use a non-default type parameter for TContext you must override this method with the safe version.
// This cast is in place because if TContext != Muator::Context this will not compile even thought it will
// not be used if it is overridden.
virtual MutatorContext GetMutatorContext(Context context) { return (MutatorContext)context; }
inline bool Preorder(ParseNode *node, Context context)
{
MutatorWalkerPolicy::Context mutatorWalkerContext;
mutatorWalkerContext.mutatorContext = GetMutatorContext(context);
mutatorWalkerContext.mutator = this;
ParseNodeWalker<MutatorWalkerPolicy> walker;
return walker.Walk(node, mutatorWalkerContext);
}
inline void Inorder(ParseNode *node, Context context) { }
inline void Midorder(ParseNode *node, Context context) { }
inline void Postorder(ParseNode *node, Context context) { }
inline void InList(ParseNode *pnode, Context context) { }
inline void PassReference(ParseNode **ppnode, Context context) { }
};