Skip to content
This repository was archived by the owner on Apr 14, 2022. It is now read-only.

Commit ebb70c7

Browse files
author
MikhailArkhipov
committed
Fix version matching
1 parent c28a553 commit ebb70c7

4 files changed

Lines changed: 30 additions & 31 deletions

File tree

src/Analysis/Engine/Impl/Definitions/IModuleAnalysis.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
namespace Microsoft.PythonTools.Analysis {
2222
public interface IModuleAnalysis {
23+
int Version { get; }
2324
IModuleContext InterpreterContext { get; }
2425
PythonAnalyzer ProjectState { get; }
2526
IScope Scope { get; }

src/Analysis/Engine/Impl/ModuleAnalysis.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,21 @@ namespace Microsoft.PythonTools.Analysis {
3434
///
3535
/// Can be queried for various information about the resulting analysis.
3636
/// </summary>
37-
public sealed class ModuleAnalysis: IModuleAnalysis {
37+
public sealed class ModuleAnalysis : IModuleAnalysis {
3838
private readonly AnalysisUnit _unit;
3939
private static Regex _otherPrivateRegex = new Regex("^_[a-zA-Z_]\\w*__[a-zA-Z_]\\w*$");
4040

4141
private static readonly IEnumerable<IOverloadResult> GetSignaturesError =
4242
new[] { new OverloadResult(new ParameterResult[0], "Unknown", "IntellisenseError_Sigs", null) };
4343

44-
internal ModuleAnalysis(AnalysisUnit unit, InterpreterScope scope) {
44+
internal ModuleAnalysis(AnalysisUnit unit, InterpreterScope scope, int version) {
4545
_unit = unit;
4646
Scope = scope;
47+
Version = version;
4748
}
4849

4950
#region Public API
50-
51+
public int Version { get; }
5152
/// <summary>
5253
/// Evaluates the given expression in at the provided line number and returns the values
5354
/// that the expression can evaluate to.
@@ -526,7 +527,7 @@ expr is TupleExpression ||
526527
/// specified location.
527528
/// </summary>
528529
/// <param name="index">The 0-based absolute index into the file.</param>
529-
internal IEnumerable<IMemberResult> GetDefinitionTreeByIndex(int index)
530+
internal IEnumerable<IMemberResult> GetDefinitionTreeByIndex(int index)
530531
=> GetDefinitionTree(_unit.Tree.IndexToLocation(index));
531532

532533
/// <summary>
@@ -989,9 +990,9 @@ private static bool IsInFunctionParameter(InterpreterScope scope, PythonAst tree
989990
}
990991

991992
return function.Parameters.Any(p => {
992-
var paramName = p.GetVerbatimImage(tree) ?? p.Name;
993-
return index >= p.StartIndex && index <= p.StartIndex + paramName.Length;
994-
});
993+
var paramName = p.GetVerbatimImage(tree) ?? p.Name;
994+
return index >= p.StartIndex && index <= p.StartIndex + paramName.Length;
995+
});
995996
}
996997

997998
private static int GetParentScopeIndent(InterpreterScope scope, PythonAst tree) {

src/Analysis/Engine/Impl/ProjectEntry.cs

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,15 @@ namespace Microsoft.PythonTools.Analysis {
4141
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable",
4242
Justification = "Unclear ownership makes it unlikely this object will be disposed correctly")]
4343
internal sealed class ProjectEntry : IPythonProjectEntry, IAggregateableProjectEntry, IDocument {
44-
private AnalysisUnit _unit;
45-
private TaskCompletionSource<IModuleAnalysis> _analysisTcs = new TaskCompletionSource<IModuleAnalysis>();
4644
private readonly SortedDictionary<int, DocumentBuffer> _buffers;
4745
private readonly ConcurrentQueue<WeakReference<ReferenceDict>> _backReferences = new ConcurrentQueue<WeakReference<ReferenceDict>>();
48-
internal readonly HashSet<AggregateProjectEntry> _aggregates = new HashSet<AggregateProjectEntry>();
46+
private readonly HashSet<AggregateProjectEntry> _aggregates = new HashSet<AggregateProjectEntry>();
47+
48+
private TaskCompletionSource<IModuleAnalysis> _analysisTcs = new TaskCompletionSource<IModuleAnalysis>();
49+
private AnalysisUnit _unit;
50+
private readonly ManualResetEventSlim _pendingParse = new ManualResetEventSlim(true);
51+
private long _expectedParseVersion;
52+
private long _expectedAnalysisVersion;
4953

5054
internal ProjectEntry(
5155
PythonAnalyzer state,
@@ -84,17 +88,14 @@ internal static Uri MakeDocumentUri(string filePath) {
8488
public event EventHandler<EventArgs> NewParseTree;
8589
public event EventHandler<EventArgs> NewAnalysis;
8690

87-
private readonly ManualResetEventSlim _pendingParse = new ManualResetEventSlim(true);
88-
private long _expectedParse;
89-
9091
private class ActivePythonParse : IPythonParse {
9192
private readonly ProjectEntry _entry;
92-
private readonly long _expected;
93+
private readonly long _expectedVersion;
9394
private bool _completed;
9495

95-
public ActivePythonParse(ProjectEntry entry, long expected) {
96+
public ActivePythonParse(ProjectEntry entry, long expectedVersion) {
9697
_entry = entry;
97-
_expected = expected;
98+
_expectedVersion = expectedVersion;
9899
}
99100

100101
public PythonAst Tree { get; set; }
@@ -105,7 +106,7 @@ public void Dispose() {
105106
return;
106107
}
107108
lock (_entry) {
108-
if (_entry._expectedParse == _expected) {
109+
if (_entry._expectedParseVersion == _expectedVersion) {
109110
_entry._pendingParse.Set();
110111
}
111112
}
@@ -114,7 +115,7 @@ public void Dispose() {
114115
public void Complete() {
115116
_completed = true;
116117
lock (_entry) {
117-
if (_entry._expectedParse == _expected) {
118+
if (_entry._expectedParseVersion == _expectedVersion) {
118119
_entry.SetCurrentParse(Tree, Cookie);
119120
_entry._pendingParse.Set();
120121
}
@@ -125,8 +126,8 @@ public void Complete() {
125126
public IPythonParse BeginParse() {
126127
_pendingParse.Reset();
127128
lock (this) {
128-
_expectedParse += 1;
129-
return new ActivePythonParse(this, _expectedParse);
129+
_expectedParseVersion += 1;
130+
return new ActivePythonParse(this, _expectedParseVersion);
130131
}
131132
}
132133

@@ -157,7 +158,7 @@ public IPythonParse GetCurrentParse() {
157158

158159
internal void SetCompleteAnalysis() {
159160
lock (this) {
160-
if (AnalysisVersion < _expectedParse) {
161+
if (_expectedAnalysisVersion != Analysis.Version) {
161162
return;
162163
}
163164
_analysisTcs.TrySetResult(Analysis);
@@ -166,8 +167,9 @@ internal void SetCompleteAnalysis() {
166167
}
167168

168169
internal void ResetCompleteAnalysis() {
169-
TaskCompletionSource<IModuleAnalysis> analysisTcs;
170+
TaskCompletionSource<IModuleAnalysis> analysisTcs = null;
170171
lock (this) {
172+
_expectedAnalysisVersion = AnalysisVersion + 1;
171173
analysisTcs = _analysisTcs;
172174
_analysisTcs = new TaskCompletionSource<IModuleAnalysis>(TaskCreationOptions.RunContinuationsAsynchronously);
173175
}
@@ -191,14 +193,9 @@ public void SetCurrentParse(PythonAst tree, IAnalysisCookie cookie, bool notify
191193
return GetCurrentParse();
192194
}
193195

196+
internal bool IsVisible(ProjectEntry assigningScope) => true;
194197

195-
internal bool IsVisible(ProjectEntry assigningScope) {
196-
return true;
197-
}
198-
199-
public void Analyze(CancellationToken cancel) {
200-
Analyze(cancel, false);
201-
}
198+
public void Analyze(CancellationToken cancel) => Analyze(cancel, false);
202199

203200
public void Analyze(CancellationToken cancel, bool enqueueOnly) {
204201
if (cancel.IsCancellationRequested) {
@@ -317,7 +314,8 @@ where lastDot > 0
317314
// publish the analysis now that it's complete/running
318315
Analysis = new ModuleAnalysis(
319316
_unit,
320-
((ModuleScope)_unit.Scope).CloneForPublish()
317+
((ModuleScope)_unit.Scope).CloneForPublish(),
318+
AnalysisVersion
321319
);
322320
}
323321

src/Analysis/Engine/Test/ThreadingTest.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@ class MyClass:
135135
// One analysis before we start
136136
foreach (var e in entries) {
137137
e.Analyze(cancel, true);
138-
e.ResetCompleteAnalysis();
139138
}
140139
state.AnalyzeQueuedEntries(cancel);
141140

0 commit comments

Comments
 (0)