private static SyntaxNode GetChangedMember( ISyntaxFactsService syntaxFactsService, SyntaxNode oldRoot, SyntaxNode newRoot, TextChangeRange range) { // if either old or new tree contains skipped text, re-analyze whole document if (oldRoot.ContainsSkippedText || newRoot.ContainsSkippedText) { return(null); } var oldMember = syntaxFactsService.GetContainingMemberDeclaration(oldRoot, range.Span.Start); var newMember = syntaxFactsService.GetContainingMemberDeclaration(newRoot, range.Span.Start); // reached the top (compilation unit) if (oldMember == null || newMember == null) { return(null); } // member doesn't contain the change if (!syntaxFactsService.ContainsInMemberBody(oldMember, range.Span)) { return(null); } // member sigature has changed if (!oldMember.IsEquivalentTo(newMember, topLevel: true)) { return(null); } // looks like inside of the body has changed return(newMember); }
private static SyntaxNode?GetBestGuessChangedMember( ISyntaxFactsService syntaxFactsService, SyntaxNode oldRoot, SyntaxNode newRoot, TextChangeRange range ) { // if either old or new tree contains skipped text, re-analyze whole document if (oldRoot.ContainsSkippedText || newRoot.ContainsSkippedText) { return(null); } // there was top level changes, so we can't use equivalent to see whether two members are same. // so, we use some simple text based heuristic to find a member that has changed. // // if we have a differ that do diff on member level or a way to track member between incremental parsing, then // that would be preferable. but currently we don't have such thing. // get top level elements at the position where change has happened var oldMember = syntaxFactsService.GetContainingMemberDeclaration( oldRoot, range.Span.Start ); var newMember = syntaxFactsService.GetContainingMemberDeclaration( newRoot, range.Span.Start ); // reached the top (compilation unit) if (oldMember == null || newMember == null) { return(null); } // if old member was empty, just use new member if (oldMember.Span.IsEmpty) { return(newMember); } // looks like change doesn't belong to existing member if (!oldMember.Span.Contains(range.Span)) { return(null); } // change happened inside of the old member, check whether new member seems just delta of that change var lengthDelta = range.NewLength - range.Span.Length; return((oldMember.Span.Length + lengthDelta) == newMember.Span.Length ? newMember : null); }
private IEnumerable <IGrouping <SyntaxNode, Diagnostic> > GetDiagnosticsGroupedByMember( ImmutableArray <Diagnostic> diagnostics, ISyntaxFactsService syntaxFacts, SyntaxNode root) => diagnostics.GroupBy(d => syntaxFacts.GetContainingMemberDeclaration(root, d.Location.SourceSpan.Start));
private static SyntaxNode GetBestGuessChangedMember( ISyntaxFactsService syntaxFactsService, SyntaxNode oldRoot, SyntaxNode newRoot, TextChangeRange range) { // if either old or new tree contains skipped text, re-analyze whole document if (oldRoot.ContainsSkippedText || newRoot.ContainsSkippedText) { return null; } // there was top level changes, so we can't use equivalent to see whether two members are same. // so, we use some simple text based heuristic to find a member that has changed. // // if we have a differ that do diff on member level or a way to track member between incremental parsing, then // that would be preferable. but currently we don't have such thing. // get top level elements at the position where change has happened var oldMember = syntaxFactsService.GetContainingMemberDeclaration(oldRoot, range.Span.Start); var newMember = syntaxFactsService.GetContainingMemberDeclaration(newRoot, range.Span.Start); // reached the top (compilation unit) if (oldMember == null || newMember == null) { return null; } // if old member was empty, just use new member if (oldMember.Span.IsEmpty) { return newMember; } // looks like change doesn't belong to existing member if (!oldMember.Span.Contains(range.Span)) { return null; } // change happened inside of the old member, check whether new member seems just delta of that change var lengthDelta = range.NewLength - range.Span.Length; return (oldMember.Span.Length + lengthDelta) == newMember.Span.Length ? newMember : null; }
private static SyntaxNode GetChangedMember( ISyntaxFactsService syntaxFactsService, SyntaxNode oldRoot, SyntaxNode newRoot, TextChangeRange range) { // if either old or new tree contains skipped text, re-analyze whole document if (oldRoot.ContainsSkippedText || newRoot.ContainsSkippedText) { return null; } var oldMember = syntaxFactsService.GetContainingMemberDeclaration(oldRoot, range.Span.Start); var newMember = syntaxFactsService.GetContainingMemberDeclaration(newRoot, range.Span.Start); // reached the top (compilation unit) if (oldMember == null || newMember == null) { return null; } // member doesn't contain the change if (!syntaxFactsService.ContainsInMemberBody(oldMember, range.Span)) { return null; } // member signature has changed if (!oldMember.IsEquivalentTo(newMember, topLevel: true)) { return null; } // looks like inside of the body has changed return newMember; }