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

Commit 905c6d2

Browse files
authored
Rewrite gen.py for new LS (#1141)
1 parent 53eb588 commit 905c6d2

1 file changed

Lines changed: 50 additions & 40 deletions

File tree

src/gen.py

Lines changed: 50 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def main():
1515
script_dir, "UnitTests", "TestData", "gen", "completion"
1616
)
1717
default_output = os.path.join(
18-
script_dir, "Analysis", "Engine", "Test", "GenTests.cs"
18+
script_dir, "LanguageServer", "Test", "GenTests.cs"
1919
)
2020

2121
parser = argparse.ArgumentParser(
@@ -202,62 +202,72 @@ def create_tests(name, filename, ignored_lines):
202202
using System.Linq;
203203
using System.Threading;
204204
using System.Threading.Tasks;
205-
using AnalysisTests;
206205
using FluentAssertions;
207-
using Microsoft.Python.LanguageServer.Implementation;
208-
using Microsoft.PythonTools.Analysis;
209-
using Microsoft.PythonTools.Analysis.FluentAssertions;
210-
using Microsoft.PythonTools.Interpreter;
211-
using Microsoft.PythonTools.Parsing;
206+
using Microsoft.Python.Analysis;
207+
using Microsoft.Python.Analysis.Analyzer;
208+
using Microsoft.Python.Analysis.Core.Interpreter;
209+
using Microsoft.Python.Analysis.Documents;
210+
using Microsoft.Python.Core.Idle;
211+
using Microsoft.Python.Core.Services;
212+
using Microsoft.Python.Core.Text;
213+
using Microsoft.Python.LanguageServer;
214+
using Microsoft.Python.LanguageServer.Completion;
215+
using Microsoft.Python.LanguageServer.Sources;
216+
using Microsoft.Python.LanguageServer.Tests;
217+
using Microsoft.Python.Parsing;
218+
using Microsoft.Python.Parsing.Tests;
212219
using Microsoft.VisualStudio.TestTools.UnitTesting;
220+
using NSubstitute;
213221
using TestUtilities;
214222
215223
namespace GenTests {"""
216224

217225
POSTAMBLE = """
218-
public class GenTest : ServerBasedTest {
219-
private static Server _server;
220-
private static readonly SemaphoreSlim _sem = new SemaphoreSlim(1, 1);
226+
public class GenTest : LanguageServerTestBase {
227+
private static readonly Dictionary<string, Task<IDocumentAnalysis>> _analysis = new Dictionary<string, Task<IDocumentAnalysis>>();
228+
221229
private static readonly InterpreterConfiguration _interpreter = PythonVersions.LatestAvailable3X;
222230
private static readonly PythonLanguageVersion _version = _interpreter.Version.ToLanguageVersion();
223-
private static readonly ConcurrentDictionary<string, Task> _opened = new ConcurrentDictionary<string, Task>();
224231
225-
private async Task<Server> SharedServer() {
226-
if (_server != null) {
227-
return _server;
228-
}
232+
private static readonly CompletionSource _cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion);
233+
private static readonly HoverSource _hs = new HoverSource(new PlainTextDocumentationSource());
229234
230-
await _sem.WaitAsync();
231-
try {
232-
var root = new Uri(TestData.GetPath("TestData", "gen", "completion"));
233-
_server = await CreateServerAsync(_interpreter, root);
234-
} finally {
235-
_sem.Release();
235+
static GenTest() {
236+
_interpreter.TypeshedPath = TestData.GetDefaultTypeshedPath();
237+
}
238+
239+
protected async Task<IDocumentAnalysis> GetGenAnalysisAsync(string module) {
240+
// Create an analyzer per module. This is slower than creating a single
241+
// analyzer shared between all GenTest instances, but sharing them makes
242+
// the "types" module fail (due to a bug where the name "types" shadows
243+
// a builtin module name).
244+
if (_analysis.TryGetValue(module, out var analysis)) {
245+
return await analysis;
236246
}
237247
238-
return _server;
239-
}
248+
var root = TestData.GetPath("TestData", "gen", "completion");
240249
241-
protected async Task<Uri> OpenAndWait(string module) {
242-
var server = await SharedServer();
250+
var sm = CreateServiceManager();
251+
sm.AddService(new PythonAnalyzer(sm));
252+
sm.AddService(await PythonInterpreter.CreateAsync(_interpreter, root, sm));
253+
sm.AddService(new RunningDocumentTable(sm));
243254
244255
var src = TestData.GetPath("TestData", "gen", "completion", module + ".py");
245-
var uri = new Uri(src);
256+
analysis = GetAnalysisAsync(File.ReadAllText(src), sm, modulePath: src);
257+
_analysis[module] = analysis;
246258
247-
await _opened.GetOrAdd(src, f => server.SendDidOpenTextDocument(uri, File.ReadAllText(f)));
248-
await server.WaitForCompleteAnalysisAsync(CancellationToken.None);
249-
250-
return uri;
259+
return await analysis;
251260
}
252261
253262
protected async Task DoCompletionTest(string module, int lineNum, int col, string args, string filter) {
254-
var server = await SharedServer();
255-
256263
var tests = string.IsNullOrWhiteSpace(args) ? new List<string>() : ParseStringList(args);
257-
var uri = await OpenAndWait(module);
258264
259-
var res = await server.SendCompletion(uri, lineNum, col);
260-
var items = res.items?.Select(item => item.insertText).Where(t => t.Contains(filter)).ToList() ?? new List<string>();
265+
var analysis = await GetGenAnalysisAsync(module);
266+
267+
var res = _cs.GetCompletions(analysis, new SourceLocation(lineNum + 1, col + 1));
268+
res.Should().NotBeNull();
269+
270+
var items = res.Completions?.Select(item => item.insertText).Where(t => t.Contains(filter)).ToList() ?? new List<string>();
261271
262272
if (tests.Count == 0) {
263273
items.Should().BeEmpty();
@@ -267,15 +277,14 @@ def create_tests(name, filename, ignored_lines):
267277
}
268278
269279
protected async Task DoHoverTest(string module, int lineNum, int col, string args) {
270-
var server = await SharedServer();
271-
272280
var tests = string.IsNullOrWhiteSpace(args)
273281
? new List<string>()
274282
: args.Split(' ', options: StringSplitOptions.RemoveEmptyEntries).Select(s => s.EndsWith("()") ? s.Substring(0, s.Length - 2) : s).ToList();
275283
276-
var uri = await OpenAndWait(module);
284+
var analysis = await GetGenAnalysisAsync(module);
277285
278-
var res = await server.SendHover(uri, lineNum, col);
286+
var res = _hs.GetHover(analysis, new SourceLocation(lineNum + 1, col + 1));
287+
res.Should().NotBeNull();
279288
280289
if (tests.Count == 0) {
281290
res.contents.value.Should().BeEmpty();
@@ -309,7 +318,8 @@ def create_tests(name, filename, ignored_lines):
309318
return list;
310319
}
311320
}
312-
}"""
321+
}
322+
"""
313323

314324
CLASS_PREAMBLE = """ [TestClass]
315325
public class {name}Tests : GenTest {{

0 commit comments

Comments
 (0)