Esempio n. 1
0
        public void ResetDocumentBuffer()
        {
            var doc = new DocumentBuffer();

            doc.Reset(0, "");

            Assert.AreEqual("", doc.Text.ToString());

            doc.Update(new[] { new DocumentChangeSet(0, 1, new[] {
                    DocumentChange.Insert("text", SourceLocation.MinValue)
                }) });

            Assert.AreEqual("text", doc.Text.ToString());

            try {
                doc.Update(new[] { new DocumentChangeSet(1, 0, new[] {
                        DocumentChange.Delete(SourceLocation.MinValue, SourceLocation.MinValue.AddColumns(4))
                    }) });
                Assert.Fail("expected InvalidOperationException");
            } catch (InvalidOperationException) {
            }
            Assert.AreEqual("text", doc.Text.ToString());
            Assert.AreEqual(1, doc.Version);

            doc.Update(new[] { new DocumentChangeSet(1, 0, new[] {
                    new DocumentChange {
                        WholeBuffer = true
                    }
                }) });

            Assert.AreEqual("", doc.Text.ToString());
            Assert.AreEqual(0, doc.Version);
        }
        public async Task MultiPartDocument()
        {
            var s = await CreateServer();

            var mod = await AddModule(s, "x = 1", "mod");

            var modP2 = new Uri(mod, "#2");
            var modP3 = new Uri(mod, "#3");

            await AssertCompletion(s, mod, new[] { "x" }, Enumerable.Empty <string>());

            Assert.AreEqual(Tuple.Create("y = 2", 1), await ApplyChange(s, modP2, DocumentChange.Insert("y = 2", SourceLocation.MinValue)));
            await s.WaitForCompleteAnalysisAsync();

            await AssertCompletion(s, modP2, new[] { "x", "y" }, Enumerable.Empty <string>());

            Assert.AreEqual(Tuple.Create("z = 3", 1), await ApplyChange(s, modP3, DocumentChange.Insert("z = 3", SourceLocation.MinValue)));
            await s.WaitForCompleteAnalysisAsync();

            await AssertCompletion(s, modP3, new[] { "x", "y", "z" }, Enumerable.Empty <string>());
            await AssertCompletion(s, mod, new[] { "x", "y", "z" }, Enumerable.Empty <string>());

            await ApplyChange(s, mod, DocumentChange.Delete(SourceLocation.MinValue, SourceLocation.MinValue.AddColumns(5)));

            await s.WaitForCompleteAnalysisAsync();

            await AssertCompletion(s, modP2, new[] { "y", "z" }, new[] { "x" });
            await AssertCompletion(s, modP3, new[] { "y", "z" }, new[] { "x" });
        }
Esempio n. 3
0
 private DocumentChange Delete(int oldStart, int oldEnd)
 {
     return(DocumentChange.Delete(new SourceSpan(
                                      _oldLines[oldStart].Info.SourceStart,
                                      _oldLines[oldEnd].Info.SourceEndIncludingLineBreak
                                      )));
 }
        public async Task ApplyChanges()
        {
            var s = await CreateServer();

            var m = await AddModule(s, "", "mod");

            Assert.AreEqual(Tuple.Create("x", 1), await ApplyChange(s, m, DocumentChange.Insert("x", new SourceLocation(1, 1))));
            Assert.AreEqual(Tuple.Create("", 2), await ApplyChange(s, m, DocumentChange.Delete(new SourceLocation(1, 1), new SourceLocation(1, 2))));
            Assert.AreEqual(Tuple.Create("y", 3), await ApplyChange(s, m, DocumentChange.Insert("y", new SourceLocation(1, 1))));
        }
Esempio n. 5
0
        public void BasicDocumentBuffer()
        {
            var doc = new DocumentBuffer();

            doc.Reset(0, @"def f(x):
    return

def g(y):
    return y * 2
");

            doc.Update(new DocumentChangeSet(0, 1, new[] {
                // We *should* batch adjacent insertions, but we should also
                // work fine even if we don't. Note that the insertion point
                // tracks backwards with previous insertions in the same version.
                // If each of these were in its own array, the location would
                // have to change for each.
                DocumentChange.Insert(")", new SourceLocation(2, 11)),
                DocumentChange.Insert("x", new SourceLocation(2, 11)),
                DocumentChange.Insert("(", new SourceLocation(2, 11)),
                DocumentChange.Insert("g", new SourceLocation(2, 11)),
                DocumentChange.Insert(" ", new SourceLocation(2, 11))
            }));

            doc.Text.Should().Contain("return g(x)");
            Assert.AreEqual(1, doc.Version);

            doc.Update(new[] {
                new DocumentChangeSet(1, 2, new [] {
                    DocumentChange.Delete(new SourceLocation(2, 14), new SourceLocation(2, 15))
                }),
                new DocumentChangeSet(2, 3, new [] {
                    DocumentChange.Insert("x * 2", new SourceLocation(2, 14))
                })
            });

            doc.Text.Should().Contain("return g(x * 2)");

            doc.Update(new DocumentChangeSet(3, 4, new[] {
                DocumentChange.Replace(new SourceLocation(2, 18), new SourceLocation(2, 19), "300")
            }));

            doc.Text.Should().Contain("return g(x * 300)");

            doc.Update(new DocumentChangeSet(4, 5, new[] {
                // Changes are out of order, but we should fix that automatically
                DocumentChange.Delete(new SourceLocation(2, 13), new SourceLocation(2, 22)),
                DocumentChange.Insert("#", new SourceLocation(2, 7))
            }));
            doc.Text.Should().Contain("re#turn g");
        }
        public void SequentialChanges()
        {
            var doc = new DocumentBuffer();

            doc.SetContent(@"
line1
line2
line3
line4
");
            doc.Update(new[] {
                DocumentChange.Delete(new SourceSpan(2, 5, 3, 5)),
                DocumentChange.Delete(new SourceSpan(3, 5, 4, 5))
            });
            Assert.AreEqual(@"
line2
line4
", doc.Text);
        }
Esempio n. 7
0
        public void DeleteAcrossLines()
        {
            var doc = new DocumentBuffer();

            doc.Reset(0, @"
line1
line2
line3
line4
");
            doc.Update(new[] {
                DocumentChange.Delete(new SourceSpan(4, 5, 5, 5)),
                DocumentChange.Delete(new SourceSpan(2, 5, 3, 5)),
            });
            Assert.AreEqual(@"
line2
line4
", doc.Text);
        }
Esempio n. 8
0
        private void ReplaceLines(List <DocumentChange> edits, int startOldLine, int endOldLine, int startNewLine, int endNewLine)
        {
            int oldLineCount = endOldLine - startOldLine;
            int newLineCount = endNewLine - startNewLine;

            // replace one line at a time instead of all of the lines at once so that we preserve breakpoints
            int excessNewLineStart = startNewLine - startOldLine;

            for (int i = startOldLine; i < endOldLine && i < (endNewLine - startNewLine + startOldLine); i++)
            {
                edits.Add(
                    DocumentChange.Replace(
                        _oldLines[i].SourceExtent,
                        GetNewText(startNewLine + i - startOldLine)
                        )
                    );
                excessNewLineStart = startNewLine + i - startOldLine + 1;
            }

            if (oldLineCount > newLineCount)
            {
                // we end up w/ less lines, we need to delete some text
                edits.Add(
                    DocumentChange.Delete(new SourceSpan(
                                              _oldLines[endOldLine - (oldLineCount - newLineCount)].SourceStart,
                                              _oldLines[endOldLine - 1].SourceEndIncludingLineBreak
                                              ))
                    );
            }
            else if (oldLineCount < newLineCount)
            {
                // we end up w/ more lines, we need to insert some text
                edits.Add(
                    DocumentChange.Insert(
                        string.Join(
                            _newLine,
                            _newLines.Skip(excessNewLineStart).Take(endNewLine - excessNewLineStart).Select(x => GetNewText(x.LineNo))
                            ) + _newLine,
                        _oldLines[endOldLine - 1].SourceEndIncludingLineBreak
                        )
                    );
            }
        }
        public void DeleteMultipleDisjoint()
        {
            var doc = new DocumentBuffer();

            doc.SetContent(@"
line1
line2
line3
line4
");
            doc.Update(new[] {
                DocumentChange.Delete(new SourceSpan(5, 5, 5, 6)),
                DocumentChange.Delete(new SourceSpan(4, 5, 4, 6)),
                DocumentChange.Delete(new SourceSpan(3, 5, 3, 6)),
                DocumentChange.Delete(new SourceSpan(2, 5, 2, 6))
            });
            Assert.AreEqual(@"
line
line
line
line
", doc.Text);
        }
Esempio n. 10
0
        public IReadOnlyList <DocumentChange> ReplaceCode()
        {
            var edits          = new List <DocumentChange>();
            var oldLineMapping = new Dictionary <string, List <int> >();   // line to line #

            for (int i = 0; i < _oldLines.Count; i++)
            {
                List <int> lineInfo;
                if (!oldLineMapping.TryGetValue(GetOldText(i), out lineInfo))
                {
                    oldLineMapping[GetOldText(i)] = lineInfo = new List <int>();
                }
                lineInfo.Add(i);
            }

            int curOldLine = 0;

            for (int curNewLine = 0; curOldLine < _oldLines.Count && curNewLine < _newLines.Count; curOldLine++)
            {
                if (GetOldText(curOldLine) == GetNewText(curNewLine))
                {
                    curNewLine++;
                    continue;
                }

                bool replaced = false;
                // replace starts on this line, figure out where it ends...
                int startNewLine = curNewLine;
                for (curNewLine += 1; curNewLine < _newLines.Count; curNewLine++)
                {
                    List <int> lines;
                    if (oldLineMapping.TryGetValue(GetNewText(curNewLine), out lines))
                    {
                        foreach (var matchingLineNo in lines)
                        {
                            if (matchingLineNo > curOldLine)
                            {
                                // Replace the lines from curOldLine to matchingLineNo-1 with the text
                                // from startNewLine - curNewLine - 1.
                                ReplaceLines(edits, curOldLine, matchingLineNo, startNewLine, curNewLine);
                                replaced   = true;
                                curOldLine = matchingLineNo - 1;
                                break;
                            }
                        }
                    }

                    if (replaced)
                    {
                        break;
                    }
                }

                if (!replaced)
                {
                    ReplaceLines(edits, curOldLine, _oldLines.Count, startNewLine, _newLines.Count);
                    curOldLine = _oldLines.Count;
                    break;
                }
            }

            if (curOldLine < _oldLines.Count)
            {
                // remove the remaining new lines
                edits.Add(
                    DocumentChange.Delete(new SourceSpan(
                                              _oldLines[curOldLine].SourceStart,
                                              _oldLines[_oldLines.Count - 1].SourceEnd
                                              ))
                    );
            }
            return(edits.ToArray());
        }