public override void ReplaceChild(JSNode oldChild, JSNode newChild) { if (oldChild == null) { throw new ArgumentNullException("oldChild"); } if (newChild == this) { throw new InvalidOperationException("Infinite recursion"); } if ((newChild != null) && !(newChild is JSExpression)) { return; } var expr = (JSExpression)newChild; for (int i = 0, c = Values.Length; i < c; i++) { if (Values[i] == oldChild) { Values[i] = expr; } } }
public override void ReplaceChild(JSNode oldChild, JSNode newChild) { if (oldChild == null) { throw new ArgumentNullException("oldChild"); } if (_Initializer == oldChild) { _Initializer = (JSStatement)newChild; } if (_Condition == oldChild) { _Condition = (JSExpression)newChild; } if (_Increment == oldChild) { _Increment = (JSStatement)newChild; } if (newChild is JSStatement) { base.ReplaceChild(oldChild, newChild); } }
public NodeVisitor Get(JSNode node) { if (node == null) { return(null); } var nodeType = node.GetType(); var currentType = nodeType; return(Cache.GetOrCreate( nodeType, () => { while (currentType != null) { NodeVisitor result; if (Methods.TryGetValue(currentType, out result)) { return result; } currentType = currentType.BaseType; } return null; } )); }
private IEnumerable <State> VisitNode(JSNode node, string name = null, Indices indices = null, int depth = 0) { int?statementIndex = null; if (indices == null) { indices = new Indices(); } int nodeIndex = indices.GetNodeIndex(); if (node is JSStatement) { statementIndex = indices.GetStatementIndex(); } yield return(new State( node, name, depth, nodeIndex, statementIndex )); foreach (var e in VisitChildren(node, indices, depth)) { foreach (var c in e) { yield return(c); } } }
public JSAstCursor(JSNode root, params string[] namesToSkip) { Root = root; NamesToSkip = new HashSet <string>(namesToSkip); Reset(); }
protected VisitorCache(Type visitorType) { VisitorType = visitorType; var methods = new Dictionary <Type, NodeVisitor>(new ReferenceComparer <Type>()); foreach (var m in VisitorType.GetMethods()) { if (m.Name != "VisitNode") { continue; } var parameters = m.GetParameters(); if (parameters.Length != 1) { continue; } var nodeType = parameters[0].ParameterType; methods.Add(nodeType, MakeVisitorAdapter(m, visitorType, nodeType)); } TypeToVisitor = new NodeVisitor[JSNode.NodeTypes.Length]; foreach (var nt in JSNode.NodeTypes) { var id = JSNode.GetTypeId(nt); TypeToVisitor[id] = FindNodeVisitor(nt, methods); } }
public override void ReplaceChild(JSNode oldChild, JSNode newChild) { if (oldChild == null) { throw new ArgumentNullException("oldChild"); } var stmt = newChild as JSStatement; if (stmt == null) { return; } foreach (var kvp in Labels.ToArray()) { if (kvp.Value == oldChild) { if (stmt.Label == kvp.Key) { Labels.Replace(kvp.Key, stmt); } else { Labels.Remove(kvp.Key); if (!stmt.IsNull) { Add(stmt); } } } } }
public override void ReplaceChild(JSNode oldChild, JSNode newChild) { if (oldChild == null) { throw new ArgumentNullException("oldChild"); } var boe = newChild as JSBinaryOperatorExpression; if (boe == null) { Declarations.RemoveAll((c) => c == oldChild); } else if (boe.Operator != JSOperator.Assignment) { throw new InvalidOperationException("A variable declaration statement may only contain assignments"); } else { for (int i = 0, c = Declarations.Count; i < c; i++) { if (Declarations[i] == oldChild) { Declarations[i] = boe; } } } }
public override void ReplaceChild(JSNode oldChild, JSNode newChild) { if (oldChild == null) { throw new ArgumentNullException("oldChild"); } if (_Condition == oldChild) { _Condition = (JSExpression)newChild; } var cse = newChild as JSSwitchCase; if (cse != null) { for (int i = 0, c = Cases.Count; i < c; i++) { if (Cases[i] == oldChild) { Cases[i] = cse; } } } }
public State(JSNode node, string name, int depth, int nodeIndex, int?statementIndex) { Node = node; Name = name; Depth = depth; NodeIndex = nodeIndex; StatementIndex = statementIndex; }
public NodeVisitor Get(JSNode node) { if (node == null) { return(null); } return(TypeToVisitor[node.TypeId]); }
/// <summary> /// Responsible for traversing a node. Do not invoke directly. /// By default, this method traverses the node's children, but takes no other action. /// </summary> public virtual void VisitNode(JSNode node) { if (node == null) { Console.WriteLine("Warning: Null node found in JavaScript AST"); return; } VisitChildren(node); }
protected static void SetValueNames(Type nodeType, params string[] valueNames) { var id = JSNode.GetTypeId(nodeType); if (TypeToValueNames[id] != null) { throw new InvalidOperationException("Value names already set for this node type"); } TypeToValueNames[id] = valueNames; }
public override void ReplaceChild(JSNode oldChild, JSNode newChild) { if (oldChild == null) { throw new ArgumentNullException("oldChild"); } throw new NotImplementedException( String.Format("Statements of type '{0}' do not support child replacement", GetType().Name) ); }
public override void ReplaceChild(JSNode oldChild, JSNode newChild) { if (newChild == this) { throw new InvalidOperationException("Direct cycle formed by replacement"); } if (DefaultValue == oldChild) { DefaultValue = (JSExpression)newChild; } }
/// <summary> /// Traverses all of a node's children. This is the default behavior for VisitNode. /// </summary> protected virtual void VisitChildren(JSNode node, Func <JSNode, string, bool> predicate = null) { if (node == null) { throw new ArgumentNullException("node"); } var oldPreviousSibling = PreviousSibling; var oldNextSibling = NextSibling; string nextSiblingName = null; predicate = predicate ?? DefaultVisitPredicate; try { PreviousSibling = NextSibling = null; using (var e = node.Children.EnumeratorTemplate) while (e.MoveNext()) { var toVisit = NextSibling; var toVisitName = nextSiblingName; NextSibling = e.Current; nextSiblingName = e.CurrentName; if (toVisit != null) { if ((predicate == null) || predicate(toVisit, toVisitName)) { Visit(toVisit, toVisitName); } } PreviousSibling = toVisit; } if (NextSibling != null) { var toVisit = NextSibling; NextSibling = null; if (toVisit != null) { if ((predicate == null) || predicate(toVisit, nextSiblingName)) { Visit(toVisit, nextSiblingName); } } } } finally { PreviousSibling = oldPreviousSibling; NextSibling = oldNextSibling; } }
public override void ReplaceChild(JSNode oldChild, JSNode newChild) { if (oldChild == null) { throw new ArgumentNullException("oldChild"); } if (oldChild == _Expression) { _Expression = (JSExpression)newChild; } }
public override void ReplaceChild(JSNode oldChild, JSNode newChild) { foreach (var key in Variables.Keys.ToArray()) { if (Variables[key] == oldChild) { Variables[key] = (JSExpression)newChild; } } base.ReplaceChild(oldChild, newChild); }
public virtual void ReplaceChildRecursive(JSNode oldChild, JSNode newChild) { ReplaceChild(oldChild, newChild); foreach (var child in Children) { if ((child != null) && (child != newChild)) { child.ReplaceChildRecursive(oldChild, newChild); } } }
public override void ReplaceChild(JSNode oldChild, JSNode newChild) { if (oldChild == null) { throw new ArgumentNullException("oldChild"); } var stmt = newChild as JSStatement; if (stmt == null) { return; } foreach (var kvp in Labels.ToArray()) { if (kvp.Value == oldChild) { if (stmt.Label == kvp.Key) { Labels.Replace(kvp.Key, stmt); } else if (stmt.Label == null) { stmt.Label = kvp.Key; if (stmt.IsNull) { Labels.Remove(kvp.Key); } else { Labels.Replace(kvp.Key, stmt); } } else { Labels.Remove(kvp.Key); if (!stmt.IsNull) { if (Labels.ContainsKey(stmt.Label)) { throw new InvalidOperationException("Replacing LabelGroupStatement child '" + oldChild + "' with '" + newChild + "' but group already contains the label '" + stmt.Label + "'"); } Add(stmt); } } } } }
public NodeVisitor Get(JSNode node) { if (node == null) { return(null); } var nodeType = node.GetType(); return(Cache.GetOrCreate( nodeType, FindNodeVisitor )); }
protected static bool GetChild(JSNode parent, int index, out JSNode node, out string name) { var self = (JSLabelGroupStatement)parent; if (index >= self.Labels.Count) { node = null; name = null; return(false); } node = self.Labels.AtIndex(index).Value; name = "Labels"; return(true); }
public virtual void ReplaceChildRecursive(JSNode oldChild, JSNode newChild) { ReplaceChild(oldChild, newChild); using (var e = Children.EnumeratorTemplate) while (e.MoveNext()) { var child = e.Current; if ((child != null) && (child != newChild)) { child.ReplaceChildRecursive(oldChild, newChild); } } }
public static IEnumerable <T> GetChildNodes <T> (JSNode root, Func <T, bool> predicate = null) where T : JSNode { foreach (var n in root.AllChildrenRecursive) { var value = n as T; if (value != null) { if ((predicate == null) || predicate(value)) { yield return(value); } } } }
/// <summary> /// Visits a node and its children (if any), updating the traversal stack. The current node is replaced by the new node. /// </summary> /// <param name="node">The node to visit.</param> protected void VisitReplacement(JSNode node) { Stack.Pop(); Stack.Push(node); var visitor = Visitors.Get(node); if (visitor != null) { visitor(this, node); } else { VisitNode(node); } }
private void SkipNode(JSNode node, string name, Indices indices, int depth) { indices.GetNodeIndex(); if (node is JSStatement) { indices.GetStatementIndex(); } foreach (var e in VisitChildren(node, indices, depth)) { foreach (var c in e) { ; } } }
private IEnumerable <IEnumerable <State> > VisitChildren(JSNode node, Indices indices, int depth) { if (node == null) { throw new ArgumentNullException("node"); } JSNode nextSibling = null; string nextSiblingName = null; int nextDepth = depth + 1; using (var e = node.Children.EnumeratorTemplate) while (e.MoveNext()) { var toVisit = nextSibling; var toVisitName = nextSiblingName; nextSibling = e.Current; nextSiblingName = e.CurrentName; if (toVisit != null) { if (toVisitName == null || !NamesToSkip.Contains(toVisitName)) { yield return(VisitNode(toVisit, toVisitName, indices, nextDepth)); } else { SkipNode(toVisit, toVisitName, indices, nextDepth); } } } if (nextSibling != null) { if (nextSiblingName == null || !NamesToSkip.Contains(nextSiblingName)) { yield return(VisitNode(nextSibling, nextSiblingName, indices, nextDepth)); } else { SkipNode(nextSibling, nextSiblingName, indices, nextDepth); } } }
/// <summary> /// Visits a node and its children (if any), updating the traversal stack. /// </summary> /// <param name="node">The node to visit.</param> /// <param name="name">The name to annotate the node with, if any.</param> public void Visit(JSNode node, string name = null) { var oldNodeIndex = NodeIndex; var oldStatementIndex = StatementIndex; #if PARANOID if (Stack.Contains(node)) { throw new InvalidOperationException("AST traversal formed a cycle"); } #endif Stack.Push(node); NameStack.Push(name); try { NodeIndexStack.Push(NodeIndex = NextNodeIndex); NextNodeIndex += 1; if (node is JSStatement) { StatementIndex = NextStatementIndex; NextStatementIndex += 1; } var visitor = Visitors.Get(node); if (visitor != null) { visitor(this, node); } else { VisitNode(node); } } finally { NodeIndexStack.Pop(); Stack.Pop(); NameStack.Pop(); NodeIndex = oldNodeIndex; StatementIndex = oldStatementIndex; } }
static bool GetValue(JSNode parent, int index, out JSNode node, out string name) { JSExpression expr = (JSExpression)parent; var values = expr.Values; if (index >= values.Length) { node = null; name = null; return(false); } else { node = values[index]; name = expr.GetValueName(index) ?? "Values"; return(true); } }
public override void ReplaceChild(JSNode oldChild, JSNode newChild) { if (Values == null) { return; } var jse = newChild as JSExpression; if (jse != null) { for (var i = 0; i < Values.Length; i++) { if (oldChild.Equals(Values[i])) { Values[i] = jse; } } } }