public IStateTable GetSyntaxInputTable(ISyntaxInputNode syntaxInputNode) { Debug.Assert(_syntaxInputNodes.Contains(syntaxInputNode)); // when we don't have a value for this node, we update all the syntax inputs at once if (!_tableBuilder.ContainsKey(syntaxInputNode)) { // get a builder for each input node var builders = ArrayBuilder <ISyntaxInputBuilder> .GetInstance(_syntaxInputNodes.Length); foreach (var node in _syntaxInputNodes) { builders.Add(node.GetBuilder(_previousTable)); } // update each tree for the builders, sharing the semantic model foreach ((var tree, var state) in GetLatestStateTableForNode(SharedInputNodes.SyntaxTrees)) { var root = tree.GetRoot(_cancellationToken); var model = state != EntryState.Removed ? Compilation.GetSemanticModel(tree) : null; for (int i = 0; i < builders.Count; i++) { try { _cancellationToken.ThrowIfCancellationRequested(); builders[i].VisitTree(root, state, model, _cancellationToken); } catch (UserFunctionException ufe) { // we're evaluating this node ahead of time, so we can't just throw the exception // instead we'll hold onto it, and throw the exception when a downstream node actually // attempts to read the value _syntaxExceptions[builders[i].SyntaxInputNode] = ufe; builders.RemoveAt(i); i--; } } } // save the updated inputs foreach (var builder in builders) { builder.SaveStateAndFree(_tableBuilder); Debug.Assert(_tableBuilder.ContainsKey(builder.SyntaxInputNode)); } builders.Free(); } // if we don't have an entry for this node, it must have thrown an exception if (!_tableBuilder.ContainsKey(syntaxInputNode)) { throw _syntaxExceptions[syntaxInputNode]; } return(_tableBuilder[syntaxInputNode]); }
public void Clear_HasComparer_ReturnsEmptyWithOriginalComparer() { ImmutableSegmentedDictionary <string, int> dictionary = new Dictionary <string, int> { { "a", 1 } }.ToImmutableSegmentedDictionary(StringComparer.OrdinalIgnoreCase); ImmutableSegmentedDictionary <string, int> clearedDictionary = dictionary.Clear(); Assert.False(IsSame(ImmutableSegmentedDictionary <string, int> .Empty, clearedDictionary.Clear())); Assert.NotEmpty(dictionary); clearedDictionary = clearedDictionary.Add("a", 1); Assert.True(clearedDictionary.ContainsKey("A")); }
public bool Contains(object key) => _tableBuilder.ContainsKey(key);
public IStateTable GetSyntaxInputTable(ISyntaxInputNode syntaxInputNode) { Debug.Assert(_syntaxInputNodes.Contains(syntaxInputNode)); // when we don't have a value for this node, we update all the syntax inputs at once if (!_tableBuilder.ContainsKey(syntaxInputNode)) { // CONSIDER: when the compilation is the same as previous, the syntax trees must also be the same. // if we have a previous state table for a node, we can just short circuit knowing that it is up to date var compilationIsCached = GetLatestStateTableForNode(SharedInputNodes.Compilation).IsCached; // get a builder for each input node var builders = ArrayBuilder <ISyntaxInputBuilder> .GetInstance(_syntaxInputNodes.Length); foreach (var node in _syntaxInputNodes) { if (compilationIsCached && _previousTable._tables.TryGetValue(node, out var previousStateTable)) { _tableBuilder.Add(node, previousStateTable); } else { builders.Add(node.GetBuilder(_previousTable)); } } if (builders.Count == 0) { // bring over the previously cached syntax tree inputs _tableBuilder[SharedInputNodes.SyntaxTrees] = _previousTable._tables[SharedInputNodes.SyntaxTrees]; } else { // update each tree for the builders, sharing the semantic model foreach ((var tree, var state) in GetLatestStateTableForNode(SharedInputNodes.SyntaxTrees)) { var root = new Lazy <SyntaxNode>(() => tree.GetRoot(_cancellationToken)); var model = state != EntryState.Removed ? Compilation.GetSemanticModel(tree) : null; for (int i = 0; i < builders.Count; i++) { try { _cancellationToken.ThrowIfCancellationRequested(); builders[i].VisitTree(root, state, model, _cancellationToken); } catch (UserFunctionException ufe) { // we're evaluating this node ahead of time, so we can't just throw the exception // instead we'll hold onto it, and throw the exception when a downstream node actually // attempts to read the value _syntaxExceptions[builders[i].SyntaxInputNode] = ufe; builders.RemoveAt(i); i--; } } } // save the updated inputs foreach (var builder in builders) { builder.SaveStateAndFree(_tableBuilder); Debug.Assert(_tableBuilder.ContainsKey(builder.SyntaxInputNode)); } } builders.Free(); } // if we don't have an entry for this node, it must have thrown an exception if (!_tableBuilder.ContainsKey(syntaxInputNode)) { throw _syntaxExceptions[syntaxInputNode]; } return(_tableBuilder[syntaxInputNode]); }
public IStateTable GetSyntaxInputTable(ISyntaxInputNode syntaxInputNode) { Debug.Assert(_syntaxInputNodes.Contains(syntaxInputNode)); // when we don't have a value for this node, we update all the syntax inputs at once if (!_tableBuilder.ContainsKey(syntaxInputNode)) { // CONSIDER: when the compilation is the same as previous, the syntax trees must also be the same. // if we have a previous state table for a node, we can just short circuit knowing that it is up to date // This step isn't part of the tree, so we can skip recording. var compilationIsCached = GetLatestStateTableForNode(SharedInputNodes.Compilation).IsCached; // get a builder for each input node var syntaxInputBuilders = ArrayBuilder <ISyntaxInputBuilder> .GetInstance(_syntaxInputNodes.Length); foreach (var node in _syntaxInputNodes) { // TODO: We don't cache the tracked incremental steps in a manner that we can easily rehydrate between runs, // so we'll disable the cached compilation perf optimization when incremental step tracking is enabled. if (compilationIsCached && !DriverState.TrackIncrementalSteps && _previousTable._tables.TryGetValue(node, out var previousStateTable)) { _tableBuilder.Add(node, previousStateTable); } else { syntaxInputBuilders.Add(node.GetBuilder(_previousTable, DriverState.TrackIncrementalSteps)); } } if (syntaxInputBuilders.Count == 0) { // bring over the previously cached syntax tree inputs _tableBuilder[SharedInputNodes.SyntaxTrees] = _previousTable._tables[SharedInputNodes.SyntaxTrees]; } else { GeneratorRunStateTable.Builder temporaryRunStateBuilder = new GeneratorRunStateTable.Builder(DriverState.TrackIncrementalSteps); NodeStateTable <SyntaxTree> syntaxTreeState = GetLatestStateTableForNode(SharedInputNodes.SyntaxTrees); // update each tree for the builders, sharing the semantic model foreach ((var tree, var state, var syntaxTreeIndex, var stepInfo) in syntaxTreeState) { var root = new Lazy <SyntaxNode>(() => tree.GetRoot(_cancellationToken)); var model = state != EntryState.Removed ? Compilation.GetSemanticModel(tree) : null; for (int i = 0; i < syntaxInputBuilders.Count; i++) { try { _cancellationToken.ThrowIfCancellationRequested(); syntaxInputBuilders[i].VisitTree(root, state, model, _cancellationToken); } catch (UserFunctionException ufe) { // we're evaluating this node ahead of time, so we can't just throw the exception // instead we'll hold onto it, and throw the exception when a downstream node actually // attempts to read the value _syntaxExceptions[syntaxInputBuilders[i].SyntaxInputNode] = ufe; syntaxInputBuilders.RemoveAt(i); i--; } } } // save the updated inputs foreach (ISyntaxInputBuilder builder in syntaxInputBuilders) { builder.SaveStateAndFree(_tableBuilder); Debug.Assert(_tableBuilder.ContainsKey(builder.SyntaxInputNode)); } } syntaxInputBuilders.Free(); } // if we don't have an entry for this node, it must have thrown an exception if (!_tableBuilder.ContainsKey(syntaxInputNode)) { throw _syntaxExceptions[syntaxInputNode]; } return(_tableBuilder[syntaxInputNode]); }