private void RecordAugmentations(IEnumerable <CSharpSyntaxNode> statements) { // get the parent assigned variables, and static status // it should be the same for all statements, as we're operating at the block level here var parentAssigned = GetAssignedVariablesAtParent(statements.First()); var isInStaticMethod = _semanticModel.GetEnclosingSymbol(statements.First().SpanStart).IsStatic; var dataFlowIn = _semanticModel.AnalyzeDataFlow(statements.First()).DataFlowsIn; var filteredStatements = FilterStatementsByRegions(statements).ToList(); for (int i = 0; i < statements.Count(); i++) { var statement = filteredStatements[i]; var prevAssigned = i > 0 ? _semanticModel.AnalyzeDataFlow(filteredStatements[0], filteredStatements[i - 1]).AlwaysAssigned : Enumerable.Empty <ISymbol>(); var assigned = prevAssigned.Union(parentAssigned).Union(dataFlowIn); // if the node has children, figure out what variables are valid inside, so the child nodes will be aware of them later on var validForChildren = Enumerable.Empty <ISymbol>(); if (statement.ChildNodes().Any(n => n is BlockSyntax)) { var dataFlow = _semanticModel.AnalyzeDataFlow(statement); validForChildren = dataFlow.AlwaysAssigned.Union(dataFlow.DataFlowsIn); } var symbols = _semanticModel.LookupSymbols(statement.FullSpan.Start); var locals = symbols.Where(s => s.Kind == SymbolKind.Local && assigned.Contains(s)); var fields = symbols.Where(s => s.Kind == SymbolKind.Field && (s.IsStatic || !isInStaticMethod)); var param = symbols.Where(s => s.Kind == SymbolKind.Parameter); var augmentation = new Augmentation(statement, locals, fields, param, validForChildren); Augmentations.Data[statement] = augmentation; } }
private static Augmentation MapAugmentationToViewport(Augmentation input, LinePositionSpan viewportSpan) => input.withPosition( new FilePosition { Line = CalculateOffset(input.CurrentFilePosition.Line, viewportSpan), Character = input.CurrentFilePosition.Character, File = input.CurrentFilePosition.File } );