pnodechange.h 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. template <class Context>
  7. class ParseNodeMutatorBase
  8. {
  9. public:
  10. typedef Context Context;
  11. };
  12. template <typename Mutator, typename TContext = typename Mutator::Context>
  13. struct ParseNodeMutatingVisitor : public Mutator
  14. {
  15. public:
  16. typedef TContext Context;
  17. typedef typename Mutator::Context MutatorContext;
  18. class MutatorWalkerPolicy
  19. {
  20. public:
  21. typedef bool ResultType;
  22. typedef struct
  23. {
  24. MutatorContext mutatorContext;
  25. ParseNodeMutatingVisitor<Mutator, Context> *mutator;
  26. } Context;
  27. inline bool DefaultResult() { return true; }
  28. inline bool ContinueWalk(bool value) { return value; }
  29. inline bool WalkNode(ParseNode *node, Context context) { return true; }
  30. inline bool WalkListNode(ParseNode *node, Context context) { return true; }
  31. inline bool WalkFirstChild(ParseNode *&node, Context context) { return context.mutator->Mutate(node, context.mutatorContext); }
  32. inline bool WalkSecondChild(ParseNode *&node, Context context) { return context.mutator->Mutate(node, context.mutatorContext); }
  33. inline bool WalkNthChild(ParseNode* pnodeParent, ParseNode *&node, Context context) { return context.mutator->Mutate(node, context.mutatorContext); }
  34. };
  35. // Warning: This contains an unsafe cast if TContext != Mutator::Context.
  36. // If you use a non-default type parameter for TContext you must override this method with the safe version.
  37. // This cast is in place because if TContext != Muator::Context this will not compile even thought it will
  38. // not be used if it is overridden.
  39. virtual MutatorContext GetMutatorContext(Context context) { return (MutatorContext)context; }
  40. inline bool Preorder(ParseNode *node, Context context)
  41. {
  42. MutatorWalkerPolicy::Context mutatorWalkerContext;
  43. mutatorWalkerContext.mutatorContext = GetMutatorContext(context);
  44. mutatorWalkerContext.mutator = this;
  45. ParseNodeWalker<MutatorWalkerPolicy> walker;
  46. return walker.Walk(node, mutatorWalkerContext);
  47. }
  48. inline void Inorder(ParseNode *node, Context context) { }
  49. inline void Midorder(ParseNode *node, Context context) { }
  50. inline void Postorder(ParseNode *node, Context context) { }
  51. inline void InList(ParseNode *pnode, Context context) { }
  52. inline void PassReference(ParseNode **ppnode, Context context) { }
  53. };