Skip to content
This repository was archived by the owner on Apr 14, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/Analysis/Ast/Impl/Documents/Definitions/IDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@ public interface IDocument: IPythonModule, IDisposable {
void Update(IEnumerable<DocumentChange> changes);

/// <summary>
/// Resets document buffer to the provided content or tries to load it if content is null, then parses and analyzes document.
/// Marks document as changed and advances its version.
/// Leads to new parse and analysis of the document.
/// </summary>
void Reset(string content);
void Invalidate();

/// <summary>
/// Provides collection of parsing errors, if any.
Expand Down
30 changes: 27 additions & 3 deletions src/Analysis/Ast/Impl/Documents/DocumentBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Python.Core.Diagnostics;
using Microsoft.Python.Parsing;

namespace Microsoft.Python.Analysis.Documents {
internal sealed class DocumentBuffer {
private readonly object _lock = new object();
private StringBuilder _sb = new StringBuilder();
private string _content;
private bool _cleared;
private bool _initialized;

public int Version { get; private set; }

Expand All @@ -34,16 +37,38 @@ public string Text {
}
}

public void Reset(int version, string content) {
public void SetContent(string content) {
lock (_lock) {
Version = version;
Check.InvalidOperation(!_initialized, "Buffer is already initialized.");
Check.InvalidOperation(!_cleared, "Buffer cannot be updated since its content was dropped.");
Version = 0;
_content = content ?? string.Empty;
_sb = null;
_initialized = true;
}
}

public void Clear() {
lock (_lock) {
_content = string.Empty;
_sb = null;
_cleared = true;
}
}

public void MarkChanged() {
lock (_lock) {
Check.InvalidOperation(_initialized, "Buffer is not initialized.");
Check.InvalidOperation(!_cleared, "Buffer cannot be updated since its content was dropped.");
Version++;
}
}

public void Update(IEnumerable<DocumentChange> changes) {
lock (_lock) {
Check.InvalidOperation(_initialized, "Buffer is not initialized.");
Check.InvalidOperation(!_cleared, "Buffer cannot be updated since its content was dropped.");

_sb = _sb ?? new StringBuilder(_content);

foreach (var change in changes) {
Expand Down Expand Up @@ -98,7 +123,6 @@ public IEnumerable<NewLineLocation> GetNewLineLocations() {
if (i == _sb.Length - 1) {
yield return new NewLineLocation(i + 1, NewLineKind.None);
}

break;
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/Analysis/Ast/Impl/Documents/RunningDocumentTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ public void ReloadAll() {
}

foreach (var (_, entry) in opened) {
entry.Document.Reset(null);
entry.Document.Invalidate();
}
}

Expand Down Expand Up @@ -280,7 +280,6 @@ private bool TryAddModulePath(ModuleCreationOptions mco) {
private bool TryOpenDocument(DocumentEntry entry, string content) {
if (!entry.Document.IsOpen) {
entry.Document.IsOpen = true;
entry.Document.Reset(content);
entry.LockCount++;
return true;
}
Expand Down
26 changes: 11 additions & 15 deletions src/Analysis/Ast/Impl/Modules/PythonModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -311,18 +311,15 @@ public void Update(IEnumerable<DocumentChange> changes) {

Parse();
}

Services.GetService<IPythonAnalyzer>().InvalidateAnalysis(this);
}

public void Reset(string content) {
public void Invalidate() {
lock (_syncObj) {
if (content != Content) {
ContentState = State.None;
InitializeContent(content, _buffer.Version + 1);
}
ContentState = State.None;
_buffer.MarkChanged();
Parse();
}

Services.GetService<IPythonAnalyzer>().InvalidateAnalysis(this);
}

Expand Down Expand Up @@ -451,7 +448,7 @@ public void NotifyAnalysisComplete(IDocumentAnalysis analysis) {
ContentState = State.Analyzed;

if (ModuleType != ModuleType.User) {
_buffer.Reset(_buffer.Version, string.Empty);
_buffer.Clear();
}
}

Expand Down Expand Up @@ -487,7 +484,7 @@ public void AddAstNode(object o, Node n) {
public void ClearContent() {
lock (_syncObj) {
if (ModuleType != ModuleType.User) {
_buffer.Reset(_buffer.Version, string.Empty);
_buffer.Clear();
_astMap.Clear();
}
}
Expand Down Expand Up @@ -517,24 +514,23 @@ protected virtual string LoadContent() {

private void InitializeContent(string content, int version) {
lock (_syncObj) {
LoadContent(content, version);

var startParse = ContentState < State.Parsing && (_parsingTask == null || version > 0);
if (startParse) {
SetOrLoadContent(content);
if (ContentState < State.Parsing && _parsingTask == null) {
Parse();
}
}
Services.GetService<IPythonAnalyzer>().InvalidateAnalysis(this);
}

private void LoadContent(string content, int version) {
private void SetOrLoadContent(string content) {
if (ContentState < State.Loading) {
try {
if (IsPersistent) {
content = string.Empty;
} else {
content = content ?? LoadContent();
}
_buffer.Reset(version, content);
_buffer.SetContent(content);
ContentState = State.Loaded;
} catch (IOException) { } catch (UnauthorizedAccessException) { }
}
Expand Down
23 changes: 9 additions & 14 deletions src/Analysis/Ast/Test/DocumentBufferTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class DocumentBufferTests {
[TestMethod, Priority(0)]
public void BasicDocumentBuffer() {
var doc = new DocumentBuffer();
doc.Reset(0, @"def f(x):
doc.SetContent(@"def f(x):
return

def g(y):
Expand Down Expand Up @@ -77,7 +77,7 @@ def g(y):
public void ResetDocumentBuffer() {
var doc = new DocumentBuffer();

doc.Reset(0, string.Empty);
doc.SetContent(string.Empty);
Assert.AreEqual(string.Empty, doc.Text);

doc.Update(new[] {
Expand All @@ -86,18 +86,13 @@ public void ResetDocumentBuffer() {

Assert.AreEqual("text", doc.Text);
Assert.AreEqual(1, doc.Version);

doc.Reset(0, @"abcdef");

Assert.AreEqual(@"abcdef", doc.Text);
Assert.AreEqual(0, doc.Version);
}

[TestMethod, Priority(0)]
public void ReplaceAllDocumentBuffer() {
var doc = new DocumentBuffer();

doc.Reset(0, string.Empty);
doc.SetContent(string.Empty);
Assert.AreEqual(string.Empty, doc.Text);

doc.Update(new[] {
Expand Down Expand Up @@ -134,7 +129,7 @@ public void ReplaceAllDocumentBuffer() {
[TestMethod, Priority(0)]
public void DeleteMultipleDisjoint() {
var doc = new DocumentBuffer();
doc.Reset(0, @"
doc.SetContent(@"
line1
line2
line3
Expand All @@ -157,7 +152,7 @@ public void DeleteMultipleDisjoint() {
[TestMethod, Priority(0)]
public void InsertMultipleDisjoint() {
var doc = new DocumentBuffer();
doc.Reset(0, @"
doc.SetContent(@"
line
line
line
Expand All @@ -180,7 +175,7 @@ public void InsertMultipleDisjoint() {
[TestMethod, Priority(0)]
public void DeleteAcrossLines() {
var doc = new DocumentBuffer();
doc.Reset(0, @"
doc.SetContent(@"
line1
line2
line3
Expand All @@ -199,7 +194,7 @@ public void DeleteAcrossLines() {
[TestMethod, Priority(0)]
public void SequentialChanges() {
var doc = new DocumentBuffer();
doc.Reset(0, @"
doc.SetContent(@"
line1
line2
line3
Expand All @@ -218,7 +213,7 @@ public void SequentialChanges() {
[TestMethod, Priority(0)]
public void InsertTopToBottom() {
var doc = new DocumentBuffer();
doc.Reset(0, @"linelinelineline");
doc.SetContent(@"linelinelineline");
doc.Update(new[] {
DocumentChange.Insert("\n", new SourceLocation(1, 1)),
DocumentChange.Insert("1\n", new SourceLocation(2, 5)),
Expand All @@ -233,7 +228,7 @@ public void InsertTopToBottom() {
[DataTestMethod, Priority(0)]
public void NewLines(string s, NewLineLocation[] expected) {
var doc = new DocumentBuffer();
doc.Reset(0, s);
doc.SetContent(s);
var nls = doc.GetNewLineLocations().ToArray();
for (var i = 0; i < nls.Length; i++) {
Assert.AreEqual(nls[i].Kind, expected[i].Kind);
Expand Down