public async Task TestGetSemanticTokensEdits_EndInsertionAsync() { var updatedText = @"// Comment static class C { } // Comment"; using var testLspServer = await CreateTestLspServerAsync(s_standardCase); var caretLocation = testLspServer.GetLocations("caret").First(); await RunGetSemanticTokensAsync(testLspServer, caretLocation); await UpdateDocumentTextAsync(updatedText, testLspServer.TestWorkspace); var results = await RunGetSemanticTokensEditsAsync(testLspServer, caretLocation, previousResultId : "1"); var expectedEdit = new LSP.SemanticTokensEdit { Start = 30, DeleteCount = 0, Data = new int[] { 1, 0, 10, SemanticTokensCache.TokenTypeToIndex[LSP.SemanticTokenTypes.Comment], 0 } }; Assert.Equal(expectedEdit, ((LSP.SemanticTokensDelta)results).Edits.First()); Assert.Equal("2", ((LSP.SemanticTokensDelta)results).ResultId); }
public async Task TestGetSemanticTokensEdits_ReturnMinimalEdits() { var updatedText = @"class // Comment"; using var testLspServer = CreateTestLspServer(s_singleLineCase, out var locations); var caretLocation = locations["caret"].First(); await RunGetSemanticTokensAsync(testLspServer, caretLocation); // Edit text UpdateDocumentText(updatedText, testLspServer.TestWorkspace); var results = await RunGetSemanticTokensEditsAsync(testLspServer, caretLocation, previousResultId : "1"); // 1. Updates length of token (10 to 5) and updates token type (comment to keyword) // 2. Creates new token for '// Comment' var expectedEdit = new LSP.SemanticTokensEdit { Start = 2, DeleteCount = 0, Data = new int[] { // 'class' /* 0, 0, */ 5, SemanticTokensCache.TokenTypeToIndex[LSP.SemanticTokenTypes.Keyword], 0, // '// Comment' 1, 0, /* 10, SemanticTokensCache.TokenTypeToIndex[LSP.SemanticTokenTypes.Comment], 0 */ } }; Assert.Equal(expectedEdit, ((LSP.SemanticTokensDelta)results).Edits?[0]); Assert.Equal("2", ((LSP.SemanticTokensDelta)results).ResultId); }
public async Task TestGetSemanticTokensEdits_EndDeletionAsync() { var updatedText = @"// Comment"; using var testLspServer = await CreateTestLspServerAsync(s_standardCase); var caretLocation = testLspServer.GetLocations("caret").First(); await RunGetSemanticTokensAsync(testLspServer, caretLocation); await UpdateDocumentTextAsync(updatedText, testLspServer.TestWorkspace); var results = await RunGetSemanticTokensEditsAsync(testLspServer, caretLocation, previousResultId : "1"); var expectedEdit = new LSP.SemanticTokensEdit { Start = 5, DeleteCount = 25, Data = System.Array.Empty <int>() }; Assert.Equal(expectedEdit, ((LSP.SemanticTokensDelta)results).Edits.First()); Assert.Equal("2", ((LSP.SemanticTokensDelta)results).ResultId); }
public async Task TestInsertingNewLineInMiddleOfFile() { var updatedText = @"// Comment static class C { }"; using var testLspServer = await CreateTestLspServerAsync(s_standardCase); var caretLocation = testLspServer.GetLocations("caret").First(); await RunGetSemanticTokensAsync(testLspServer, caretLocation); await UpdateDocumentTextAsync(updatedText, testLspServer.TestWorkspace); var results = await RunGetSemanticTokensEditsAsync(testLspServer, caretLocation, previousResultId : "1"); var expectedEdit = new LSP.SemanticTokensEdit { Start = 5, DeleteCount = 1, Data = new int[] { 2 } }; Assert.Equal(expectedEdit, ((LSP.SemanticTokensDelta)results).Edits.First()); Assert.Equal("2", ((LSP.SemanticTokensDelta)results).ResultId); }
public async Task TestAllHandlersAsync() { var markup = @"{|caret:|}// Comment static class C { } "; using var testLspServer = await CreateTestLspServerAsync(markup); var caretLocation = testLspServer.GetLocations("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[ClassificationTypeNames.ClassName], (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); Assert.True(rangeResults is RoslynSemanticTokens); // 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[ClassificationTypeNames.ClassName], (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); Assert.True(wholeDocResults is RoslynSemanticTokens); // 3. Edits handler - insert newline at beginning of file var newMarkup = @" // Comment static class C { } "; await UpdateDocumentTextAsync(newMarkup, testLspServer.TestWorkspace); var editResults = await RunGetSemanticTokensEditsAsync(testLspServer, caretLocation, previousResultId : "2"); var expectedEdit = new LSP.SemanticTokensEdit { Start = 0, DeleteCount = 1, Data = new int[] { 1 } }; Assert.Equal(expectedEdit, ((LSP.SemanticTokensDelta)editResults).Edits.First()); Assert.Equal("3", ((LSP.SemanticTokensDelta)editResults).ResultId); Assert.True((LSP.SemanticTokensDelta)editResults is RoslynSemanticTokensDelta); // 4. Edits handler - no changes (ResultId should remain same) var editResultsNoChange = await RunGetSemanticTokensEditsAsync(testLspServer, caretLocation, previousResultId : "3"); Assert.Equal("3", ((LSP.SemanticTokensDelta)editResultsNoChange).ResultId); Assert.True((LSP.SemanticTokensDelta)editResultsNoChange is RoslynSemanticTokensDelta); // 5. 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[ClassificationTypeNames.ClassName], (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); Assert.True(wholeDocResults2 is RoslynSemanticTokens); }