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)); }
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)); }
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); }
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); }
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); }
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); } }
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)); }
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()); }
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); }
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); }
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); }
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); }
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); }
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)); }
//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); }
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 }); }
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); }
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); }