public async Task TestGetSemanticTokensEdits_EndDeletionAsync() { var updatedText = @"// Comment"; using var testLspServer = CreateTestLspServer(s_standardCase, out var locations); var caretLocation = locations["caret"].First(); await RunGetSemanticTokensAsync(testLspServer, caretLocation); UpdateDocumentText(updatedText, testLspServer.TestWorkspace); var results = await RunGetSemanticTokensEditsAsync( testLspServer, caretLocation, previousResultId : "1" ); var expectedEdit = SemanticTokensEditsHandler.GenerateEdit( start: 5, deleteCount: 25, data: System.Array.Empty <int>() ); Assert.Equal(expectedEdit, ((LSP.SemanticTokensEdits)results).Edits.First()); Assert.Equal("2", ((LSP.SemanticTokensEdits)results).ResultId); }
public async Task TestGetSemanticTokensEdits_ReturnMinimalEdits() { var updatedText = @"class // Comment"; using var workspace = CreateTestWorkspace(s_singleLineCase, out var locations); var caretLocation = locations["caret"].First(); await RunGetSemanticTokensAsync(workspace.CurrentSolution, caretLocation); // Edit text UpdateDocumentText(updatedText, workspace); var results = await RunGetSemanticTokensEditsAsync(workspace.CurrentSolution, caretLocation, previousResultId : "1"); // 1. Replaces length of token (10 to 5) and replaces token type (comment to keyword) // 2. Creates new token for '// Comment' var expectedEdit = SemanticTokensEditsHandler.GenerateEdit( start: 0, deleteCount: 5, data: new int[] { 0, 0, 5, SemanticTokensCache.TokenTypeToIndex[LSP.SemanticTokenTypes.Keyword], 0, 1, 0, 10, SemanticTokensCache.TokenTypeToIndex[LSP.SemanticTokenTypes.Comment], 0 }); Assert.Equal(expectedEdit, ((LSP.SemanticTokensEdits)results).Edits?[0]); Assert.Equal("2", ((LSP.SemanticTokensEdits)results).ResultId); }
public async Task TestInsertingNewLineInMiddleOfFile() { var updatedText = @"// Comment static class C { }"; using var testLspServer = CreateTestLspServer(s_standardCase, out var locations); var caretLocation = locations["caret"].First(); await RunGetSemanticTokensAsync(testLspServer, caretLocation); UpdateDocumentText(updatedText, testLspServer.TestWorkspace); var results = await RunGetSemanticTokensEditsAsync( testLspServer, caretLocation, previousResultId : "1" ); var expectedEdit = SemanticTokensEditsHandler.GenerateEdit( start: 5, deleteCount: 1, data: new int[] { 2 } ); Assert.Equal(expectedEdit, ((LSP.SemanticTokensEdits)results).Edits.First()); Assert.Equal("2", ((LSP.SemanticTokensEdits)results).ResultId); }
public async Task TestGetSemanticTokensEdits_EndInsertionAsync() { var updatedText = @"// Comment static class C { } // Comment"; using var workspace = CreateTestWorkspace(s_standardCase, out var locations); var caretLocation = locations["caret"].First(); await RunGetSemanticTokensAsync(workspace.CurrentSolution, caretLocation); UpdateDocumentText(updatedText, workspace); var results = await RunGetSemanticTokensEditsAsync(workspace.CurrentSolution, caretLocation, previousResultId : "1"); var expectedEdit = SemanticTokensEditsHandler.GenerateEdit( start: 30, deleteCount: 0, data: new int[] { 1, 0, 10, SemanticTokensCache.TokenTypeToIndex[LSP.SemanticTokenTypes.Comment], 0 }); Assert.Equal(expectedEdit, ((LSP.SemanticTokensEdits)results).Edits.First()); Assert.Equal("2", ((LSP.SemanticTokensEdits)results).ResultId); }
public async Task TestAllHandlersAsync() { var markup = @"{|caret:|}// Comment static class C { } "; using var testLspServer = CreateTestLspServer(markup, out var locations); var caretLocation = locations["caret"].First(); // 1. Range handler var range = new LSP.Range { Start = new Position(1, 0), End = new Position(2, 0) }; var rangeResults = await RunGetSemanticTokensRangeAsync( testLspServer, caretLocation, range ); var expectedRangeResults = new LSP.SemanticTokens { Data = new int[] { // Line | Char | Len | Token type | Modifier 1, 0, 6, SemanticTokensCache.TokenTypeToIndex[LSP.SemanticTokenTypes.Keyword], 0, // 'static' 0, 7, 5, SemanticTokensCache.TokenTypeToIndex[LSP.SemanticTokenTypes.Keyword], 0, // 'class' 0, 6, 1, SemanticTokensCache.TokenTypeToIndex[LSP.SemanticTokenTypes.Class], (int)TokenModifiers.Static, // 'C' 0, 2, 1, SemanticTokensCache.TokenTypeToIndex[ClassificationTypeNames.Punctuation], 0, // '{' 0, 2, 1, SemanticTokensCache.TokenTypeToIndex[ClassificationTypeNames.Punctuation], 0, // '}' }, ResultId = "1" }; await VerifyNoMultiLineTokens(testLspServer, rangeResults.Data !).ConfigureAwait(false); Assert.Equal(expectedRangeResults.Data, rangeResults.Data); Assert.Equal(expectedRangeResults.ResultId, rangeResults.ResultId); // 2. Whole document handler var wholeDocResults = await RunGetSemanticTokensAsync(testLspServer, caretLocation); var expectedWholeDocResults = new LSP.SemanticTokens { Data = new int[] { // Line | Char | Len | Token type | Modifier 0, 0, 10, SemanticTokensCache.TokenTypeToIndex[LSP.SemanticTokenTypes.Comment], 0, // '// Comment' 1, 0, 6, SemanticTokensCache.TokenTypeToIndex[LSP.SemanticTokenTypes.Keyword], 0, // 'static' 0, 7, 5, SemanticTokensCache.TokenTypeToIndex[LSP.SemanticTokenTypes.Keyword], 0, // 'class' 0, 6, 1, SemanticTokensCache.TokenTypeToIndex[LSP.SemanticTokenTypes.Class], (int)TokenModifiers.Static, // 'C' 0, 2, 1, SemanticTokensCache.TokenTypeToIndex[ClassificationTypeNames.Punctuation], 0, // '{' 0, 2, 1, SemanticTokensCache.TokenTypeToIndex[ClassificationTypeNames.Punctuation], 0, // '}' }, ResultId = "2" }; await VerifyNoMultiLineTokens(testLspServer, wholeDocResults.Data !) .ConfigureAwait(false); Assert.Equal(expectedWholeDocResults.Data, wholeDocResults.Data); Assert.Equal(expectedWholeDocResults.ResultId, wholeDocResults.ResultId); // 3. Edits handler - insert newline at beginning of file var newMarkup = @" // Comment static class C { } "; UpdateDocumentText(newMarkup, testLspServer.TestWorkspace); var editResults = await RunGetSemanticTokensEditsAsync( testLspServer, caretLocation, previousResultId : "2" ); var expectedEdit = SemanticTokensEditsHandler.GenerateEdit(0, 1, new int[] { 1 }); Assert.Equal(expectedEdit, ((LSP.SemanticTokensEdits)editResults).Edits.First()); Assert.Equal("3", ((LSP.SemanticTokensEdits)editResults).ResultId); // 4. Re-request whole document handler (may happen if LSP runs into an error) var wholeDocResults2 = await RunGetSemanticTokensAsync(testLspServer, caretLocation); var expectedWholeDocResults2 = new LSP.SemanticTokens { Data = new int[] { // Line | Char | Len | Token type | Modifier 1, 0, 10, SemanticTokensCache.TokenTypeToIndex[LSP.SemanticTokenTypes.Comment], 0, // '// Comment' 1, 0, 6, SemanticTokensCache.TokenTypeToIndex[LSP.SemanticTokenTypes.Keyword], 0, // 'static' 0, 7, 5, SemanticTokensCache.TokenTypeToIndex[LSP.SemanticTokenTypes.Keyword], 0, // 'class' 0, 6, 1, SemanticTokensCache.TokenTypeToIndex[LSP.SemanticTokenTypes.Class], (int)TokenModifiers.Static, // 'C' 0, 2, 1, SemanticTokensCache.TokenTypeToIndex[ClassificationTypeNames.Punctuation], 0, // '{' 0, 2, 1, SemanticTokensCache.TokenTypeToIndex[ClassificationTypeNames.Punctuation], 0, // '}' }, ResultId = "4" }; await VerifyNoMultiLineTokens(testLspServer, wholeDocResults2.Data !) .ConfigureAwait(false); Assert.Equal(expectedWholeDocResults2.Data, wholeDocResults2.Data); Assert.Equal(expectedWholeDocResults2.ResultId, wholeDocResults2.ResultId); }