public void AddReference(IJsNameReference reference) { if (reference != null) { m_referenceTable.Add(reference); if (this.OuterField != null) { this.OuterField.AddReference(reference); } } }
private static bool IsIterativeReference(JsAstNode initializer, IJsNameReference reference) { // we only care about array and regular expressions with the global switch at this point. // if it's not one of those types, then go ahead and assume iterative reference doesn't matter. var regExp = initializer as JsRegExpLiteral; if (initializer is JsArrayLiteral || initializer is JsObjectLiteral || (regExp != null && regExp.PatternSwitches != null && regExp.PatternSwitches.IndexOf("g", StringComparison.OrdinalIgnoreCase) >= 0)) { // get the parent block for the initializer. We'll use this as a stopping point in our loop. var parentBlock = GetParentBlock(initializer); // walk up the parent chain from the reference. If we find a while, a for, or a do-while, // then we know this reference is iteratively called. // stop when the parent is null, the same block containing the initializer, or a function object. // (because a function object will step out of scope, and we know we should be in the same scope) var child = reference as JsAstNode; var parent = child.Parent; while (parent != null && parent != parentBlock && !(parent is JsFunctionObject)) { // while or do-while is iterative -- the condition and the body are both called repeatedly. if (parent is JsWhileNode || parent is JsDoWhile) { return(true); } // for-statements call the condition, the incrementer, and the body repeatedly, but not the // initializer. var forNode = parent as JsForNode; if (forNode != null && child != forNode.Initializer) { return(true); } // in forin-statements, only the body is repeated, the collection is evaluated only once. var forInStatement = parent as JsForIn; if (forInStatement != null && child == forInStatement.Body) { return(true); } // go up child = parent; parent = parent.Parent; } } return(false); }
private static bool IsIterativeReference(JsAstNode initializer, IJsNameReference reference) { // we only care about array and regular expressions with the global switch at this point. // if it's not one of those types, then go ahead and assume iterative reference doesn't matter. var regExp = initializer as JsRegExpLiteral; if (initializer is JsArrayLiteral || initializer is JsObjectLiteral || (regExp != null && regExp.PatternSwitches != null && regExp.PatternSwitches.IndexOf("g", StringComparison.OrdinalIgnoreCase) >= 0)) { // get the parent block for the initializer. We'll use this as a stopping point in our loop. var parentBlock = GetParentBlock(initializer); // walk up the parent chain from the reference. If we find a while, a for, or a do-while, // then we know this reference is iteratively called. // stop when the parent is null, the same block containing the initializer, or a function object. // (because a function object will step out of scope, and we know we should be in the same scope) var child = reference as JsAstNode; var parent = child.Parent; while (parent != null && parent != parentBlock && !(parent is JsFunctionObject)) { // while or do-while is iterative -- the condition and the body are both called repeatedly. if (parent is JsWhileNode || parent is JsDoWhile) { return true; } // for-statements call the condition, the incrementer, and the body repeatedly, but not the // initializer. var forNode = parent as JsForNode; if (forNode != null && child != forNode.Initializer) { return true; } // in forin-statements, only the body is repeated, the collection is evaluated only once. var forInStatement = parent as JsForIn; if (forInStatement != null && child == forInStatement.Body) { return true; } // go up child = parent; parent = parent.Parent; } } return false; }