예제 #1
0
        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());
        }
예제 #2
0
        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());
        }
예제 #3
0
        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));
            }
        }