private void AddBoundTreeForStandaloneSyntax(LanguageSyntaxNode syntax, BoundNode bound) { bool alreadyInTree = false; // check if we already have node in the cache. // this may happen if we have races and in such case we are no longer interested in adding if (bound != null) { alreadyInTree = _map.ContainsKey(bound.Syntax); } if (!alreadyInTree) { if (syntax == this.Root || this.IsBindableNode(syntax)) { // Note: For speculative model we want to always cache the entire bound tree. // If syntax is a statement, we need to add all its children. // Node cache assumes that if statement is cached, then all // its children are cached too. BoundNodeMapBuilder.AddToMap(bound, _map); } else { // expressions can be added individually. BoundNodeMapBuilder.AddToMap(bound, _map, syntax); } } }
/// <summary> /// Return bound node for a syntax node. /// </summary> public BoundNode CreateBoundNode(LanguageSyntaxNode node, Binder binder) { Debug.Assert(node != null); if (node.IsMissing) { return(null); } var childBoundNodes = ArrayBuilder <object> .GetInstance(); int position = node.Position; var state = node.Parent != null ? BoundNodeFactoryState.InParent : BoundNodeFactoryState.InNode; var nodeToVisit = node.Parent != null ? node.Parent : node; BoundNodeFactoryVisitor visitor = _boundNodeFactoryVisitorPool.Allocate(); visitor.Initialize(position, state); BoundNode result = visitor.Visit(nodeToVisit, childBoundNodes); _boundNodeFactoryVisitorPool.Free(visitor); if (node == this.Root && !(result is BoundRoot)) { Debug.Assert(result == null || childBoundNodes.Count == 0); if (result != null) { result = new BoundRoot(BoundKind.Root, this, ImmutableArray.Create <object>(result), node); } else { result = new BoundRoot(BoundKind.Root, this, childBoundNodes.ToImmutable(), node); } } else if (result == null) { Debug.Assert(false); result = (BoundNode)childBoundNodes[0]; } childBoundNodes.Free(); BoundNodeMapBuilder.AddToMap(result, _map, node); ImmutableArray <BoundNode> results = GetBoundNodesFromMap(node); if (results.IsDefaultOrEmpty) { Debug.Assert(false); return(null); } else { return(results[0]); } }
// Adds every syntax/bound pair in a tree rooted at the given bound node to the map, and the // performs a lookup of the given syntax node in the map. private ImmutableArray <BoundNode> AddBoundTreeAndGetBoundNodeFromMap(LanguageSyntaxNode syntax, BoundNode bound) { bool alreadyInTree = false; if (bound != null) { alreadyInTree = _map.ContainsKey(bound.Syntax); } // check if we already have node in the cache. // this may happen if we have races and in such case we are no longer interested in adding if (!alreadyInTree) { BoundNodeMapBuilder.AddToMap(bound, _map); } ImmutableArray <BoundNode> result; return(_map.TryGetValue(syntax, out result) ? result : default(ImmutableArray <BoundNode>)); }