internal static async Task VerifyExpectedTextAsync(string intentName, string activeDocument, string[] additionalDocuments, string expectedText, OptionsCollection?options = null) { var documentSet = additionalDocuments.Prepend(activeDocument).ToArray(); using var workspace = TestWorkspace.CreateCSharp(documentSet, exportProvider: EditorTestCompositions.EditorFeatures.ExportProviderFactory.CreateExportProvider()); if (options != null) { workspace.ApplyOptions(options !); } var intentSource = workspace.ExportProvider.GetExportedValue <IIntentSourceProvider>(); // The first document will be the active document. var document = workspace.Documents.Single(d => d.Name == "test1.cs"); var textBuffer = document.GetTextBuffer(); var typedSpan = document.AnnotatedSpans["typed"].Single(); // Get the current snapshot span and selection. var currentSelectedSpan = document.SelectedSpans.FirstOrDefault(); if (currentSelectedSpan.IsEmpty) { currentSelectedSpan = TextSpan.FromBounds(typedSpan.End, typedSpan.End); } var currentSnapshotSpan = new SnapshotSpan(textBuffer.CurrentSnapshot, currentSelectedSpan.ToSpan()); // Determine the edits to rewind to the prior snapshot by removing the changes in the annotated span. var rewindTextChange = new TextChange(typedSpan, ""); var priorSelection = TextSpan.FromBounds(rewindTextChange.Span.Start, rewindTextChange.Span.Start); if (document.AnnotatedSpans.ContainsKey("priorSelection")) { priorSelection = document.AnnotatedSpans["priorSelection"].Single(); } var intentContext = new IntentRequestContext( intentName, currentSnapshotSpan, ImmutableArray.Create(rewindTextChange), priorSelection, intentData: null); var results = await intentSource.ComputeIntentsAsync(intentContext, CancellationToken.None).ConfigureAwait(false); // For now, we're just taking the first result to match intellicode behavior. var result = results.First(); using var edit = textBuffer.CreateEdit(); foreach (var change in result.TextChanges) { edit.Replace(change.Span.ToSpan(), change.NewText); } edit.Apply(); Assert.Equal(expectedText, textBuffer.CurrentSnapshot.GetText()); }
public async Task <ImmutableArray <IntentSource> > ComputeIntentsAsync(IntentRequestContext intentRequestContext, CancellationToken cancellationToken) { var currentDocument = intentRequestContext.CurrentSnapshotSpan.Snapshot.GetOpenDocumentInCurrentContextWithChanges(); if (currentDocument == null) { throw new ArgumentException("could not retrieve document for request snapshot"); } var languageName = currentDocument.Project.Language; if (!_lazyIntentProviders.TryGetValue((LanguageName: languageName, IntentName: intentRequestContext.IntentName), out var provider)) { Logger.Log(FunctionId.Intellicode_UnknownIntent, KeyValueLogMessage.Create(LogType.UserAction, m => { m["intent"] = intentRequestContext.IntentName; m["language"] = languageName; })); return(ImmutableArray <IntentSource> .Empty); } var currentText = await currentDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); var originalDocument = currentDocument.WithText(currentText.WithChanges(intentRequestContext.PriorTextEdits)); var selectionTextSpan = intentRequestContext.PriorSelection; var results = await provider.Value.ComputeIntentAsync( originalDocument, selectionTextSpan, currentDocument, new IntentDataProvider( intentRequestContext.IntentData, _globalOptions.CreateProvider()), cancellationToken).ConfigureAwait(false); if (results.IsDefaultOrEmpty) { return(ImmutableArray <IntentSource> .Empty); } using var _ = ArrayBuilder <IntentSource> .GetInstance(out var convertedResults); foreach (var result in results) { var convertedIntent = await ConvertToIntelliCodeResultAsync(result, originalDocument, currentDocument, cancellationToken).ConfigureAwait(false); convertedResults.AddIfNotNull(convertedIntent); } return(convertedResults.ToImmutable()); }
internal static async Task VerifyExpectedTextAsync( string intentName, string activeDocument, string[] additionalDocuments, string[] expectedTexts, OptionsCollection?options = null, string?intentData = null, string?priorText = null) { var documentSet = additionalDocuments.Prepend(activeDocument).ToArray(); using var workspace = TestWorkspace.CreateCSharp(documentSet, exportProvider: EditorTestCompositions.EditorFeatures.ExportProviderFactory.CreateExportProvider()); if (options != null) { workspace.ApplyOptions(options !); } var intentSource = workspace.ExportProvider.GetExportedValue <IIntentSourceProvider>(); // The first document will be the active document. var document = workspace.Documents.Single(d => d.Name == "test1.cs"); var textBuffer = document.GetTextBuffer(); // Get the text change to rewind the document to the correct pre-intent location. var rewindTextChange = new TextChange(document.AnnotatedSpans["typed"].Single(), priorText ?? string.Empty); // Get the current snapshot span to pass in. var currentSnapshot = new SnapshotSpan(textBuffer.CurrentSnapshot, new Span(0, textBuffer.CurrentSnapshot.Length)); var priorSelection = TextSpan.FromBounds(rewindTextChange.Span.Start, rewindTextChange.Span.Start); if (document.AnnotatedSpans.ContainsKey("priorSelection")) { priorSelection = document.AnnotatedSpans["priorSelection"].Single(); } var intentContext = new IntentRequestContext( intentName, currentSnapshot, ImmutableArray.Create(rewindTextChange), priorSelection, intentData: intentData); var results = await intentSource.ComputeIntentsAsync(intentContext, CancellationToken.None).ConfigureAwait(false); // For now, we're just taking the first result to match intellicode behavior. var result = results.First(); var actualDocumentTexts = new List <string>(); foreach (var documentChange in result.DocumentChanges) { // Get the document and open it. Since we're modifying the text buffer we don't care about linked documents. var documentBuffer = workspace.GetTestDocument(documentChange.Key).GetTextBuffer(); using var edit = documentBuffer.CreateEdit(); foreach (var change in documentChange.Value) { edit.Replace(change.Span.ToSpan(), change.NewText); } edit.Apply(); actualDocumentTexts.Add(documentBuffer.CurrentSnapshot.GetText()); } Assert.Equal(expectedTexts.Length, actualDocumentTexts.Count); foreach (var expectedText in expectedTexts) { Assert.True(actualDocumentTexts.Contains(expectedText)); } }