Пример #1
0
            public Task <object> GetDocumentationAsync(IAsyncCompletionSession session, CompletionItem item, CancellationToken token)
            {
                var closingFor = item.Properties.GetProperty <(XElement element, bool isMultiple)> (this);

                ClassifiedTextElement content;

                if (closingFor.isMultiple)
                {
                    content = new ClassifiedTextElement(
                        new ClassifiedTextRun(PredefinedClassificationTypeNames.NaturalLanguage, "Closing tag for element "),
                        new ClassifiedTextRun(PredefinedClassificationTypeNames.Type, $"<{closingFor.element.Name}>"),
                        new ClassifiedTextRun(PredefinedClassificationTypeNames.NaturalLanguage, ", closing all intermediate elements")
                        );
                }
                else
                {
                    content = new ClassifiedTextElement(
                        new ClassifiedTextRun(PredefinedClassificationTypeNames.NaturalLanguage, "Closing tag for element "),
                        new ClassifiedTextRun(PredefinedClassificationTypeNames.Type, $"<{closingFor.element.Name}>")
                        );
                }


                return(Task.FromResult <object> (content));
            }
Пример #2
0
            public Task <object> GetDocumentationAsync(IAsyncCompletionSession session, CompletionItem item, CancellationToken token)
            {
                var annotation = item.Properties.GetProperty <XmlSchemaAnnotation> (this);

                var documentationBuilder = new StringBuilder();

                foreach (XmlSchemaObject schemaObject in annotation.Items)
                {
                    var schemaDocumentation = schemaObject as XmlSchemaDocumentation;
                    if (schemaDocumentation != null && schemaDocumentation.Markup != null)
                    {
                        foreach (XmlNode node in schemaDocumentation.Markup)
                        {
                            var textNode = node as XmlText;
                            if (textNode != null && !string.IsNullOrEmpty(textNode.Data))
                            {
                                documentationBuilder.Append(textNode.Data);
                            }
                        }
                    }
                }

                var desc    = documentationBuilder.ToString();
                var content = new ClassifiedTextElement(
                    new ClassifiedTextRun(PredefinedClassificationTypeNames.NaturalLanguage, desc)
                    );

                return(Task.FromResult <object> (content));
            }
Пример #3
0
        public async Task TestResolveCompletionItemAsync()
        {
            var markup =
                @"class A
{
    void M()
    {
        {|caret:|}
    }
}";

            using var testLspServer = CreateTestLspServer(markup, out var locations);
            var tags             = new string[] { "Class", "Internal" };
            var completionParams = CreateCompletionParams(locations["caret"].Single(), LSP.VSCompletionInvokeKind.Explicit, "\0", LSP.CompletionTriggerKind.Invoked);
            var document         = testLspServer.GetCurrentSolution().Projects.First().Documents.First();

            var completionItem = await CreateCompletionItemAsync(
                "A", LSP.CompletionItemKind.Class, tags, completionParams, document, commitCharacters : CompletionRules.Default.DefaultCommitCharacters).ConfigureAwait(false);

            var description        = new ClassifiedTextElement(CreateClassifiedTextRunForClass("A"));
            var clientCapabilities = new LSP.VSClientCapabilities {
                SupportsVisualStudioExtensions = true
            };

            var expected = CreateResolvedCompletionItem(completionItem, description, "class A", null);

            var results = (LSP.VSCompletionItem) await RunResolveCompletionItemAsync(testLspServer, completionItem, clientCapabilities).ConfigureAwait(false);

            AssertJsonEquals(expected, results);
        }
Пример #4
0
        public async Task TestResolveCompletionItemAsync()
        {
            var markup =
                @"class A
{
    void M()
    {
        {|caret:|}
    }
}";

            using var workspace = CreateTestWorkspace(markup, out var locations);
            var tags             = new string[] { "Class", "Internal" };
            var completionParams = CreateCompletionParams(locations["caret"].Single(), "\0", LSP.CompletionTriggerKind.Invoked);
            var commitCharacters = new string[]
            {
                " ", "{", "}", "[", "]", "(", ")", ".", ",", ":",
                ";", "+", "-", "*", "/", "%", "&", "|", "^", "!",
                "~", "=", "<", ">", "?", "@", "#", "'", "\"", "\\"
            };
            var completionItem = CreateCompletionItem
                                     ("A", LSP.CompletionItemKind.Class, tags, completionParams, commitCharacters: commitCharacters);
            var description        = new ClassifiedTextElement(CreateClassifiedTextRunForClass("A"));
            var clientCapabilities = new LSP.VSClientCapabilities {
                SupportsVisualStudioExtensions = true
            };

            var expected = CreateResolvedCompletionItem(
                "A", LSP.CompletionItemKind.Class, null, completionParams, description, "class A", null, commitCharacters);

            var results = (LSP.VSCompletionItem) await RunResolveCompletionItemAsync(workspace.CurrentSolution, completionItem, clientCapabilities);

            AssertJsonEquals(expected, results);
        }
Пример #5
0
        public async Task TestResolveCompletionItemAsync()
        {
            var markup =
                @"class A
{
    void M()
    {
        {|caret:|}
    }
}";

            var(solution, locations) = CreateTestSolution(markup);
            var tags               = new string[] { "Class", "Internal" };
            var completionParams   = CreateCompletionParams(locations["caret"].Single());
            var completionItem     = CreateCompletionItem("A", LSP.CompletionItemKind.Class, tags, completionParams);
            var description        = new ClassifiedTextElement(CreateClassifiedTextRunForClass("A"));
            var clientCapabilities = new LSP.VSClientCapabilities {
                SupportsVisualStudioExtensions = true
            };

            var expected = CreateResolvedCompletionItem("A", LSP.CompletionItemKind.Class, null, completionParams, description, "class A", null);

            var results = (LSP.VSCompletionItem) await RunResolveCompletionItemAsync(solution, completionItem, clientCapabilities);

            AssertJsonEquals(expected, results);
        }
Пример #6
0
 private static void EqualClassifiedTextElement(ClassifiedTextElement expected, ClassifiedTextElement actual)
 {
     Assert.Equal(expected.Runs.Count(), actual.Runs.Count());
     foreach (var(expectedRun, actualRun) in expected.Runs.Zip(actual.Runs, (expectedRun, actualRun) => (expectedRun, actualRun)))
     {
         EqualClassifiedTextRun(expectedRun, actualRun);
     }
 }
Пример #7
0
            public Task <object> GetDocumentationAsync(IAsyncCompletionSession session, CompletionItem item, CancellationToken token)
            {
                var desc    = item.Properties.GetProperty <string> (this);
                var content = new ClassifiedTextElement(
                    new ClassifiedTextRun(PredefinedClassificationTypeNames.NaturalLanguage, desc)
                    );

                return(Task.FromResult <object> (content));
            }
Пример #8
0
        private async Task <LSP.ReferenceGroup[]> GetReferenceGroupsAsync(LSP.ReferenceParams request, SimpleFindUsagesContext context, CancellationToken cancellationToken)
        {
            var definitionMap = new Dictionary <DefinitionItem, List <SourceReferenceItem> >();

            foreach (var reference in context.GetReferences())
            {
                if (!definitionMap.ContainsKey(reference.Definition))
                {
                    definitionMap.Add(reference.Definition, new List <SourceReferenceItem>());
                }

                definitionMap[reference.Definition].Add(reference);
            }

            var referenceGroups = ArrayBuilder <LSP.ReferenceGroup> .GetInstance();

            foreach (var keyValuePair in definitionMap)
            {
                var definition = keyValuePair.Key;
                var references = keyValuePair.Value;

                var referenceGroup = new LSP.ReferenceGroup();
                var text           = definition.GetClassifiedText();

                referenceGroup.Definition = await ProtocolConversions.DocumentSpanToLocationWithTextAsync(definition.SourceSpans.First(), text, cancellationToken).ConfigureAwait(false);

                referenceGroup.DefinitionIcon = new ImageElement(definition.Tags.GetFirstGlyph().GetImageId());

                var locationWithTexts = new ArrayBuilder <LSP.LocationWithText>();
                foreach (var reference in references)
                {
                    var classifiedSpansAndHighlightSpan = await ClassifiedSpansAndHighlightSpanFactory.ClassifyAsync(reference.SourceSpan, context.CancellationToken).ConfigureAwait(false);

                    var classifiedSpans   = classifiedSpansAndHighlightSpan.ClassifiedSpans;
                    var referenceLocation = await ProtocolConversions.DocumentSpanToLocationAsync(reference.SourceSpan, cancellationToken).ConfigureAwait(false);

                    var docText = await reference.SourceSpan.Document.GetTextAsync(context.CancellationToken).ConfigureAwait(false);

                    var classifiedText   = new ClassifiedTextElement(classifiedSpans.Select(cspan => new ClassifiedTextRun(cspan.ClassificationType, docText.ToString(cspan.TextSpan))));
                    var locationWithText = new LSP.LocationWithText {
                        Range = referenceLocation.Range, Uri = referenceLocation.Uri, Text = classifiedText
                    };
                    locationWithTexts.Add(locationWithText);
                }

                referenceGroup.References = locationWithTexts.ToArrayAndFree();
                referenceGroups.Add(referenceGroup);
            }

            return(referenceGroups.ToArrayAndFree());
        }
Пример #9
0
        public async Task TestResolveCompletionItemFromListAsync()
        {
            var markup =
                @"class A
{
    void M()
    {
        {|caret:|}
    }
}";

            using var testLspServer = CreateTestLspServer(markup, out var locations);
            var tags             = new string[] { "Class", "Internal" };
            var completionParams = CreateCompletionParams(
                locations["caret"].Single(), LSP.VSCompletionInvokeKind.Explicit, "\0", LSP.CompletionTriggerKind.Invoked);

            var clientCapabilities = new LSP.VSClientCapabilities
            {
                SupportsVisualStudioExtensions = true,
                TextDocument = new TextDocumentClientCapabilities()
                {
                    Completion = new VSCompletionSetting()
                    {
                        CompletionList = new VSCompletionListSetting()
                        {
                            Data = true,
                        }
                    }
                }
            };
            var completionList = await RunGetCompletionsAsync(testLspServer, completionParams, clientCapabilities);

            var serverCompletionItem = completionList.Items.FirstOrDefault(item => item.Label == "A");
            var completionResultId   = ((CompletionResolveData)serverCompletionItem.Data).ResultId.Value;
            var document             = testLspServer.GetCurrentSolution().Projects.First().Documents.First();
            var clientCompletionItem = ConvertToClientCompletionItem(serverCompletionItem);

            var description = new ClassifiedTextElement(CreateClassifiedTextRunForClass("A"));

            var expected = CreateResolvedCompletionItem(clientCompletionItem, description, "class A", null);

            var results = (LSP.VSCompletionItem) await RunResolveCompletionItemAsync(
                testLspServer, clientCompletionItem, clientCapabilities).ConfigureAwait(false);

            AssertJsonEquals(expected, results);
            var vsCompletionList = Assert.IsAssignableFrom <VSCompletionList>(completionList);

            Assert.NotNull(vsCompletionList.Data);
        }
Пример #10
0
        private static LSP.VSCompletionItem CreateResolvedCompletionItem(string text, LSP.CompletionItemKind kind, string[] tags, LSP.CompletionParams requestParameters,
                                                                         ClassifiedTextElement description, string detail, string documentation, string[] commitCharacters = null)
        {
            var resolvedCompletionItem = CreateCompletionItem(text, kind, tags, requestParameters, commitCharacters: commitCharacters);

            resolvedCompletionItem.Detail = detail;
            if (documentation != null)
            {
                resolvedCompletionItem.Documentation = new LSP.MarkupContent()
                {
                    Kind  = LSP.MarkupKind.PlainText,
                    Value = documentation
                };
            }

            resolvedCompletionItem.Description = description;
            return(resolvedCompletionItem);
        }
Пример #11
0
        private static LSP.VSInternalCompletionItem CreateResolvedCompletionItem(
            VSInternalCompletionItem completionItem,
            ClassifiedTextElement description,
            string detail,
            string documentation)
        {
            completionItem.Detail = detail;
            if (documentation != null)
            {
                completionItem.Documentation = new LSP.MarkupContent()
                {
                    Kind  = LSP.MarkupKind.PlainText,
                    Value = documentation
                };
            }

            completionItem.Description = description;
            return(completionItem);
        }
Пример #12
0
        public async Task TestResolveCompletionItemFromListAsync()
        {
            var markup =
                @"class A
{
    void M()
    {
        {|caret:|}
    }
}";

            var clientCapabilities = new LSP.VSInternalClientCapabilities
            {
                SupportsVisualStudioExtensions = true,
                TextDocument = new TextDocumentClientCapabilities()
                {
                    Completion = new VSInternalCompletionSetting()
                    {
                        CompletionList = new VSInternalCompletionListSetting()
                        {
                            Data = true,
                        }
                    }
                }
            };

            using var testLspServer = await CreateTestLspServerAsync(markup, clientCapabilities);

            var clientCompletionItem = await GetCompletionItemToResolveAsync <LSP.VSInternalCompletionItem>(
                testLspServer,
                label : "A").ConfigureAwait(false);

            var description = new ClassifiedTextElement(CreateClassifiedTextRunForClass("A"));
            var expected    = CreateResolvedCompletionItem(clientCompletionItem, description, "class A", null);

            var results = (LSP.VSInternalCompletionItem) await RunResolveCompletionItemAsync(
                testLspServer, clientCompletionItem).ConfigureAwait(false);

            AssertJsonEquals(expected, results);
        }
Пример #13
0
        public async Task TestResolveCompletionItemAsync()
        {
            var markup =
                @"class A
{
    void M()
    {
        {|caret:|}
    }
}";

            using var testLspServer = CreateTestLspServer(markup, out var locations);
            var clientCompletionItem = await GetCompletionItemToResolveAsync <LSP.VSCompletionItem>(testLspServer, locations, label : "A").ConfigureAwait(false);

            var description = new ClassifiedTextElement(CreateClassifiedTextRunForClass("A"));
            var expected    = CreateResolvedCompletionItem(clientCompletionItem, description, "class A", null);

            var results = (LSP.VSCompletionItem) await RunResolveCompletionItemAsync(
                testLspServer, clientCompletionItem).ConfigureAwait(false);

            AssertJsonEquals(expected, results);
        }
Пример #14
0
        public async Task <object> GetDescriptionAsync(IAsyncCompletionSession session, CompletionItem item, CancellationToken token)
        {
            var content = new ContainerElement(
                ContainerElementStyle.Wrapped,
                CompletionItemIcon,
                new ClassifiedTextElement(
                    new ClassifiedTextRun(PredefinedClassificationTypeNames.Keyword, "Hello!"),
                    new ClassifiedTextRun(PredefinedClassificationTypeNames.Identifier, " This is a sample item")));
            var lineInfo = new ClassifiedTextElement(
                new ClassifiedTextRun(
                    PredefinedClassificationTypeNames.Comment,
                    "You are on line " + ((int)(session.Properties["LineNumber"]) + 1).ToString()));
            var timeInfo = new ClassifiedTextElement(
                new ClassifiedTextRun(
                    PredefinedClassificationTypeNames.Identifier,
                    "and it is " + DateTime.Now.ToShortTimeString()));

            return(new ContainerElement(
                       ContainerElementStyle.Stacked,
                       content,
                       lineInfo,
                       timeInfo));
        }
Пример #15
0
        //static bool skipFirst = true;

        public async Task <QuickInfoItem> GetQuickInfoItemAsync(IAsyncQuickInfoSession session, CancellationToken cancellationToken)
        {
            if (XSettings.DebuggerIsRunning || XSettings.DisableQuickInfo)
            {
                await session.DismissAsync();

                return(null);
            }
            var triggerPoint = session.GetTriggerPoint(_textBuffer.CurrentSnapshot);

            if (triggerPoint == null)
            {
                await session.DismissAsync();

                return(null);
            }
            try
            {
                ModelWalker.Suspend();
                var ssp = triggerPoint.Value;
                // Map the trigger point down to our buffer.
                ITextSnapshot currentSnapshot = ssp.Snapshot;
                bool          abort           = false;
                var           tokens          = _textBuffer.GetDocument();
                if (tokens == null)
                {
                    return(null);
                }
                if (cancellationToken.IsCancellationRequested)
                {
                    return(null);
                }
                if (!abort)
                {
                    WriteOutputMessage($"Triggerpoint: {triggerPoint.Value.Position}");
                    // We don't want to lex the buffer. So get the tokens from the last lex run
                    // and when these are too old, then simply bail out
                    abort = tokens == null || tokens.SnapShot.Version != currentSnapshot.Version;
                }
                if (abort)
                {
                    await session.DismissAsync();

                    return(null);
                }
                if (cancellationToken.IsCancellationRequested)
                {
                    return(null);
                }
                var             location = _textBuffer.FindLocation(ssp);
                CompletionState state;
                var             tokenList = XSharpTokenTools.GetTokensUnderCursor(location, out state);
                // LookUp for the BaseType, reading the TokenList (From left to right)
                if (cancellationToken.IsCancellationRequested)
                {
                    return(null);
                }
                var lookupresult = new List <IXSymbol>();
                lookupresult.AddRange(XSharpLookup.RetrieveElement(location, tokenList, state, out var notProcessed, true));
                var lastToken = tokenList.LastOrDefault();
                //
                if (lookupresult.Count > 0)
                {
                    var element   = lookupresult[0];
                    var qiContent = new List <object>();

                    if (element.Kind == Kind.Constructor && lastToken?.Type != XSharpLexer.CONSTRUCTOR && lastToken?.Type != XSharpLexer.LPAREN)
                    {
                        if (element.Parent != null)
                        {
                            var xtype = element.Parent as IXTypeSymbol;
                            var qitm  = new XTypeAnalysis(xtype);
                            AddImage(qiContent, qitm.Image);
                            var description = new ClassifiedTextElement(qitm.WPFDescription);
                            qiContent.Add(description);
                        }
                    }
                    else if (element is IXMemberSymbol mem)
                    {
                        QuickInfoTypeMember qitm = new QuickInfoTypeMember(mem);
                        AddImage(qiContent, qitm.Image);
                        var description = new ClassifiedTextElement(qitm.WPFDescription);
                        qiContent.Add(description);
                    }
                    else if (element is IXVariableSymbol var)
                    {
                        QuickInfoVariable qitm = new QuickInfoVariable(var);
                        AddImage(qiContent, qitm.Image);
                        var description = new ClassifiedTextElement(qitm.WPFDescription);
                        qiContent.Add(description);
                    }
                    else if (element is IXTypeSymbol xtype)
                    {
                        var qitm = new XTypeAnalysis(xtype);
                        AddImage(qiContent, qitm.Image);
                        var description = new ClassifiedTextElement(qitm.WPFDescription);
                        qiContent.Add(description);
                    }
                    else
                    {
                        var qitm = new XAnalysis(element);
                        AddImage(qiContent, qitm.Image);
                        var description = new ClassifiedTextElement(qitm.WPFDescription);
                        qiContent.Add(description);
                    }
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return(null);
                    }
                    var result   = new ContainerElement(ContainerElementStyle.Wrapped, qiContent);
                    var line     = ssp.GetContainingLine();
                    var lineSpan = _textBuffer.CurrentSnapshot.CreateTrackingSpan(line.Extent, SpanTrackingMode.EdgeInclusive);

                    return(new QuickInfoItem(lineSpan, result));
                }
            }
            catch (Exception ex)
            {
                XSettings.LogException(ex, "XSharpQuickInfo.AugmentQuickInfoSession failed : ");
            }
            finally
            {
                ModelWalker.Resume();
            }
            await session.DismissAsync();

            return(null);
        }
Пример #16
0
        public static async Task <LSP.LocationWithText?> DocumentSpanToLocationWithTextAsync(DocumentSpan documentSpan, ClassifiedTextElement text, CancellationToken cancellationToken)
        {
            var location = await TextSpanToLocationAsync(documentSpan.Document, documentSpan.SourceSpan, cancellationToken).ConfigureAwait(false);

            return(location == null ? null : new LSP.LocationWithText
            {
                Uri = location.Uri,
                Range = location.Range,
                Text = text
            });
        }
Пример #17
0
        public async Task HandleRequestAsync_CSharpProjection_FiltersReferenceClassifiedRuns()
        {
            // Arrange
            var progressReported = false;
            var externalUri      = new Uri("C:/path/to/someotherfile.razor");

            var expectedClassifiedRun = new ClassifiedTextElement(new ClassifiedTextRun[]
            {
                new ClassifiedTextRun("text", "counter"),
            });
            var expectedReferenceItem = GetReferenceItem(5, 5, 5, 5, externalUri, text: expectedClassifiedRun);
            var documentManager       = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>(d => d.Version == 2));
            documentManager.AddDocument(externalUri, Mock.Of <LSPDocumentSnapshot>(d => d.Version == 5));

            var virtualClassifiedRun = new ClassifiedTextElement(new ClassifiedTextRun[]
            {
                new ClassifiedTextRun("field name", "__o"),
                new ClassifiedTextRun("text", " "),
                new ClassifiedTextRun("operator", "="),
                new ClassifiedTextRun("text", " "),
                new ClassifiedTextRun("text", "counter"),
                new ClassifiedTextRun("punctuation", ";"),
            });
            var virtualCSharpUri = new Uri("C:/path/to/someotherfile.razor.g.cs");
            var csharpLocation   = GetReferenceItem(100, 100, 100, 100, virtualCSharpUri, text: virtualClassifiedRun);

            var(requestInvoker, progressListener) = MockServices(csharpLocation, out var token);

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.CSharp,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>();

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));

            var remappingResult = new RazorMapToDocumentRangesResponse()
            {
                Ranges = new[] { expectedReferenceItem.Location.Range },
                HostDocumentVersion = 5
            };
            var documentMappingProvider = new Mock <LSPDocumentMappingProvider>();

            documentMappingProvider.Setup(d => d.MapToDocumentRangesAsync(RazorLanguageKind.CSharp, externalUri, new[] { csharpLocation.Location.Range }, It.IsAny <CancellationToken>())).
            Returns(Task.FromResult(remappingResult));

            var referencesHandler = new FindAllReferencesHandler(requestInvoker, documentManager, projectionProvider.Object, documentMappingProvider.Object, progressListener);

            referencesHandler.WaitForProgressNotificationTimeout = TestWaitForProgressNotificationTimeout;

            var progressToken = new ProgressWithCompletion <object>((val) =>
            {
                var results             = Assert.IsType <VSReferenceItem[]>(val);
                var actualReferenceItem = Assert.Single(results);
                AssertVSReferenceItem(expectedReferenceItem, actualReferenceItem);
                progressReported = true;
            });
            var referenceRequest = new ReferenceParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position           = new Position(10, 5),
                PartialResultToken = progressToken
            };

            // Act
            var result = await referencesHandler.HandleRequestAsync(referenceRequest, new ClientCapabilities(), token, CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(progressReported);
        }
Пример #18
0
        public static async Task <LSP.LocationWithText> DocumentSpanToLocationWithTextAsync(DocumentSpan documentSpan, ClassifiedTextElement text, CancellationToken cancellationToken)
        {
            var sourceText = await documentSpan.Document.GetTextAsync(cancellationToken).ConfigureAwait(false);

            var locationWithText = new LSP.LocationWithText
            {
                Uri   = documentSpan.Document.GetURI(),
                Range = TextSpanToRange(documentSpan.SourceSpan, sourceText),
                Text  = text
            };

            return(locationWithText);
        }