//------------------------------------------------------------------------------------------------------- // 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 ParseNodeMutatorBase { public: typedef Context Context; }; template 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; 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 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) { } };