private static SyntaxTree ComputeSyntaxTree(CSharpSyntaxNode node) { ArrayBuilder <CSharpSyntaxNode> nodes = null; SyntaxTree tree = null; // Find the nearest parent with a non-null syntax tree while (true) { tree = node._syntaxTree; if (tree != null) { break; } var parent = node.Parent; if (parent == null) { // set the tree on the root node atomically Interlocked.CompareExchange(ref node._syntaxTree, CSharpSyntaxTree.CreateWithoutClone(node), null); tree = node._syntaxTree; break; } tree = parent._syntaxTree; if (tree != null) { node._syntaxTree = tree; break; } (nodes ?? (nodes = ArrayBuilder <CSharpSyntaxNode> .GetInstance())).Add(node); node = parent; } // Propagate the syntax tree downwards if necessary if (nodes != null) { Debug.Assert(tree != null); foreach (var n in nodes) { var existingTree = n._syntaxTree; if (existingTree != null) { Debug.Assert(existingTree == tree, "how could this node belong to a different tree?"); // yield the race break; } n._syntaxTree = tree; } nodes.Free(); } return(tree); }
private static void ComputeSyntaxTree(CSharpSyntaxNode node) { ArrayBuilder <CSharpSyntaxNode> nodes = null; SyntaxTree tree = null; // Find the nearest parent with a non-null syntax tree while (true) { tree = node._syntaxTree; if (tree != null) { break; } var parent = node.Parent; if (parent == null) { Interlocked.CompareExchange(ref node._syntaxTree, CSharpSyntaxTree.CreateWithoutClone(node), null); tree = node._syntaxTree; break; } else if (parent._syntaxTree != null) { Interlocked.CompareExchange(ref node._syntaxTree, parent._syntaxTree, null); tree = node._syntaxTree; break; } else { (nodes ?? (nodes = ArrayBuilder <CSharpSyntaxNode> .GetInstance())).Add(node); node = parent; } } // Propagate the syntax tree downwards if necessary if (nodes != null) { Debug.Assert(tree != null); foreach (var n in nodes) { var existingTree = Interlocked.CompareExchange(ref n._syntaxTree, tree, null); if (existingTree != null) { tree = existingTree; } } nodes.Free(); } }