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);
        }
Exemple #5
0
        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);
        }