public ParserContext(ParserContext context, bool copyNames = false) : this(context.Nodes) { if (copyNames) { NameStack.AddRange(context.NameStack); } }
protected IEnumerable <EnclosingNode <T> > GetEnclosingNodes <T> (Func <T, bool> selector = null, Func <JSNode, bool> halter = null) where T : JSNode { JSNode previous = null; string previousName = null; // F**k the C# compiler and its busted enumerator transform // https://connect.microsoft.com/VisualStudio/feedback/details/781746/c-compiler-produces-incorrect-code-for-use-of-enumerator-structs-inside-enumerator-functions using (var eNodes = (IEnumerator <JSNode>)Stack.GetEnumerator()) using (var eNames = (IEnumerator <string>)NameStack.GetEnumerator()) while (eNodes.MoveNext() && eNames.MoveNext()) { iterationStart: var value = eNodes.Current as T; var name = eNames.Current; if (value == null) { previous = eNodes.Current; previousName = name; continue; } if ((selector == null) || selector(value)) { yield return(new EnclosingNode <T> { Node = value, Child = previous, ChildName = previousName }); } if ((halter != null) && halter(value)) { yield break; } previous = eNodes.Current; previousName = name; } }
public void VisitNode(JSVariable v) { if (CurrentName == "FunctionSignature") { // In argument list return; } var parentBoe = ParentNode as JSBinaryOperatorExpression; var parentDot = ParentNode as JSDotExpressionBase; var parentInvocation = ParentNode as JSDelegateInvocationExpression; var parentAccess = ParentNode as JSDotExpressionBase; var escapeContext = Stack.FirstOrDefault( n => n is JSReturnExpression || n is JSThrowExpression || n is JSOperatorExpressionBase || n is JSInvocationExpressionBase || n is JSNewExpression ); var escapeBoe = escapeContext as JSBinaryOperatorExpression; var isWriteTarget = ( (escapeBoe != null) && (escapeBoe.Operator is JSAssignmentOperator) && NameStack.FirstOrDefault( n => (n == "Left") || (n == "Right") ) == "Left" ); var isWriteSource = ( (escapeBoe != null) && (escapeBoe.Operator is JSAssignmentOperator) && NameStack.FirstOrDefault( n => (n == "Left") || (n == "Right") ) == "Right" ); var isReturned = escapeContext is JSReturnExpression; var isThrown = escapeContext is JSThrowExpression; var isArgument = escapeContext is JSInvocationExpressionBase || escapeContext is JSNewExpression; var flags = SlotFlags.None; if ( (parentBoe != null) && (parentBoe.Operator is JSAssignmentOperator) && (CurrentName == "Left") ) { flags |= SlotFlags.Assignment; } else if ( (parentDot != null) && (CurrentName == "Target") ) { flags |= isWriteTarget ? SlotFlags.Write | SlotFlags.Through : SlotFlags.Read | SlotFlags.Through; } else if ( (parentInvocation != null) && (CurrentName == "Delegate") ) { flags |= SlotFlags.Invoke; } else { flags |= SlotFlags.Read; } if (isWriteSource || isReturned || isThrown || isArgument) { if (parentAccess == null) { flags |= SlotFlags.Escapes; } } if (flags != SlotFlags.None) { CreateBarrier(new SlotDictionary { { v, flags } }); } VisitChildren(v); }