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

Commit 9d26ad8

Browse files
author
Mikhail Arkhipov
committed
Ensure builtins module is created synchronously (#1798)
* Remove stale reference * Don't suppress LHS diagnostics on augmented assign * Revert "Don't suppress LHS diagnostics on augmented assign" This reverts commit 6109ac7. * Sync builtins creation * Sync builtins * Usings * Debug code
1 parent 5b339cc commit 9d26ad8

File tree

6 files changed

+57
-29
lines changed

6 files changed

+57
-29
lines changed

src/Analysis/Ast/Impl/Analyzer/Definitions/IAnalyzable.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
// permissions and limitations under the License.
1515

1616
using Microsoft.Python.Analysis.Dependencies;
17+
using Microsoft.Python.Parsing.Ast;
1718

1819
namespace Microsoft.Python.Analysis.Analyzer {
1920
/// <summary>
@@ -30,6 +31,11 @@ internal interface IAnalyzable {
3031
/// </summary>
3132
void NotifyAnalysisBegins();
3233

34+
/// <summary>
35+
/// Performs standard analysis pass. Does not include any restoration from databases.
36+
/// </summary>
37+
ModuleWalker Analyze(PythonAst ast);
38+
3339
/// <summary>
3440
/// Notifies document that its analysis is now complete.
3541
/// </summary>

src/Analysis/Ast/Impl/Analyzer/PythonAnalyzerSession.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -352,10 +352,11 @@ private IDocumentAnalysis DoAnalyzeEntry(IDependencyChainNode<PythonAnalyzerEntr
352352
return analysis;
353353
}
354354

355-
var walker = new ModuleWalker(_services, module, ast, _analyzerCancellationToken);
356-
ast.Walk(walker);
357-
walker.Complete();
358-
return CreateAnalysis(node, (IDocument)module, ast, version, walker);
355+
if (module is IAnalyzable analyzable) {
356+
var walker = analyzable.Analyze(ast);
357+
return CreateAnalysis(node, (IDocument)module, ast, version, walker);
358+
}
359+
return new EmptyAnalysis(_services, (IDocument)module);
359360
}
360361

361362
private bool MarkNodeWalked(IDependencyChainNode<PythonAnalyzerEntry> node) {

src/Analysis/Ast/Impl/Analyzer/PythonInterpreter.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
using Microsoft.Python.Analysis.Modules.Resolution;
2323
using Microsoft.Python.Analysis.Specializations.Typing;
2424
using Microsoft.Python.Analysis.Types;
25-
using Microsoft.Python.Analysis.Values;
2625
using Microsoft.Python.Core;
2726
using Microsoft.Python.Core.Collections;
2827
using Microsoft.Python.Core.Services;

src/Analysis/Ast/Impl/Modules/BuiltinsPythonModule.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
using System.Collections.Generic;
1818
using System.Diagnostics;
1919
using System.Linq;
20+
using System.Threading;
21+
using Microsoft.Python.Analysis.Analyzer;
2022
using Microsoft.Python.Analysis.Specializations;
21-
using Microsoft.Python.Analysis.Specializations.Typing;
2223
using Microsoft.Python.Analysis.Types;
2324
using Microsoft.Python.Analysis.Values;
2425
using Microsoft.Python.Core;
@@ -41,15 +42,28 @@ internal sealed class BuiltinsPythonModule : CompiledPythonModule, IBuiltinsPyth
4142
public BuiltinsPythonModule(string moduleName, string filePath, IServiceContainer services)
4243
: base(moduleName, ModuleType.Builtins, filePath, null, false, false, services) { } // TODO: builtins stub & persistence
4344

45+
#region IMemberContainer
4446
public override IMember GetMember(string name) => _hiddenNames.Contains(name) ? null : base.GetMember(name);
4547

4648
public IMember GetAnyMember(string name) => base.GetMember(name);
4749

4850
public override IEnumerable<string> GetMemberNames() => base.GetMemberNames().Except(_hiddenNames).ToArray();
51+
#endregion
52+
53+
public void Initialize() => ParseAndLogExceptions(CancellationToken.None);
4954

5055
protected override string[] GetScrapeArguments(IPythonInterpreter interpreter)
5156
=> !InstallPath.TryGetFile("scrape_module.py", out var sb) ? null : new[] { "-W", "ignore", "-B", "-E", sb };
5257

58+
protected override void Parse() { }
59+
60+
protected override void Analyze(PythonAst ast, int version) {
61+
NotifyAnalysisBegins();
62+
var walker = Analyze(ast);
63+
var analysis = new DocumentAnalysis(this, version, walker.GlobalScope, walker.Eval, walker.StarImportMemberNames);
64+
NotifyAnalysisComplete(analysis);
65+
}
66+
5367
protected override void OnAnalysisComplete() {
5468
SpecializeTypes();
5569
SpecializeFunctions();

src/Analysis/Ast/Impl/Modules/PythonModule.cs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@
2222
using System.Threading;
2323
using System.Threading.Tasks;
2424
using Microsoft.Python.Analysis.Analyzer;
25+
using Microsoft.Python.Analysis.Analyzer.Evaluation;
26+
using Microsoft.Python.Analysis.Analyzer.Handlers;
2527
using Microsoft.Python.Analysis.Dependencies;
2628
using Microsoft.Python.Analysis.Diagnostics;
2729
using Microsoft.Python.Analysis.Documents;
28-
using Microsoft.Python.Analysis.Specializations.Typing;
2930
using Microsoft.Python.Analysis.Types;
3031
using Microsoft.Python.Analysis.Values;
3132
using Microsoft.Python.Core;
@@ -332,7 +333,7 @@ public void Invalidate() {
332333
Services.GetService<IPythonAnalyzer>().InvalidateAnalysis(this);
333334
}
334335

335-
private void Parse() {
336+
protected virtual void Parse() {
336337
_parseCts?.Cancel();
337338
_parseCts = new CancellationTokenSource();
338339

@@ -343,7 +344,7 @@ private void Parse() {
343344
_parsingTask = Task.Run(() => ParseAndLogExceptions(_linkedParseCts.Token), _linkedParseCts.Token);
344345
}
345346

346-
private void ParseAndLogExceptions(CancellationToken cancellationToken) {
347+
protected void ParseAndLogExceptions(CancellationToken cancellationToken) {
347348
try {
348349
Parse(cancellationToken);
349350
} catch (Exception ex) when (!(ex is OperationCanceledException)) {
@@ -352,6 +353,15 @@ private void ParseAndLogExceptions(CancellationToken cancellationToken) {
352353
}
353354
}
354355

356+
protected virtual void Analyze(PythonAst ast, int version) {
357+
if (ContentState < State.Analyzing) {
358+
ContentState = State.Analyzing;
359+
360+
var analyzer = Services.GetService<IPythonAnalyzer>();
361+
analyzer.EnqueueDocumentForAnalysis(this, ast, version);
362+
}
363+
}
364+
355365
private void Parse(CancellationToken cancellationToken) {
356366
CollectingErrorSink sink = null;
357367
int version;
@@ -372,8 +382,7 @@ private void Parse(CancellationToken cancellationToken) {
372382
}
373383

374384
var ast = parser.ParseFile(Uri);
375-
376-
//Log?.Log(TraceEventType.Verbose, $"Parse complete: {Name}");
385+
// Log?.Log(TraceEventType.Verbose, $"Parse complete: {Name} ({ModuleType})");
377386

378387
lock (_syncObj) {
379388
cancellationToken.ThrowIfCancellationRequested();
@@ -397,13 +406,7 @@ private void Parse(CancellationToken cancellationToken) {
397406
}
398407

399408
NewAst?.Invoke(this, EventArgs.Empty);
400-
401-
if (ContentState < State.Analyzing) {
402-
ContentState = State.Analyzing;
403-
404-
var analyzer = Services.GetService<IPythonAnalyzer>();
405-
analyzer.EnqueueDocumentForAnalysis(this, ast, version);
406-
}
409+
Analyze(ast, version);
407410

408411
lock (_syncObj) {
409412
_parsingTask = null;
@@ -450,6 +453,14 @@ public void NotifyAnalysisBegins() {
450453
}
451454
}
452455

456+
public ModuleWalker Analyze(PythonAst ast) {
457+
var eval = new ExpressionEval(Services, this, ast);
458+
var walker = new ModuleWalker(eval, SimpleImportedVariableHandler.Instance);
459+
ast.Walk(walker);
460+
walker.Complete();
461+
return walker;
462+
}
463+
453464
public void NotifyAnalysisComplete(IDocumentAnalysis analysis) {
454465
lock (_syncObj) {
455466
if (analysis.Version < Analysis.Version) {

src/Analysis/Ast/Impl/Modules/Resolution/MainModuleResolution.cs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ namespace Microsoft.Python.Analysis.Modules.Resolution {
3939
internal sealed class MainModuleResolution : ModuleResolutionBase, IModuleManagement {
4040
private readonly ConcurrentDictionary<string, IPythonModule> _specialized = new ConcurrentDictionary<string, IPythonModule>();
4141
private readonly IUIService _ui;
42+
private BuiltinsPythonModule _builtins;
4243
private IModuleDatabaseService _dbService;
4344
private IRunningDocumentTable _rdt;
4445

@@ -53,7 +54,7 @@ public MainModuleResolution(string root, IServiceContainer services, ImmutableAr
5354
public string BuiltinModuleName => BuiltinTypeId.Unknown.GetModuleName(Interpreter.LanguageVersion);
5455
public ImmutableArray<PythonLibraryPath> LibraryPaths { get; private set; } = ImmutableArray<PythonLibraryPath>.Empty;
5556

56-
public IBuiltinsPythonModule BuiltinsModule { get; private set; }
57+
public IBuiltinsPythonModule BuiltinsModule => _builtins;
5758

5859
public IEnumerable<IPythonModule> GetImportedModules(CancellationToken cancellationToken) {
5960
foreach (var module in _specialized.Values) {
@@ -178,12 +179,8 @@ public IPythonModule GetSpecializedModule(string fullName, bool allowCreation =
178179
public bool IsSpecializedModule(string fullName, string modulePath = null)
179180
=> _specialized.ContainsKey(fullName);
180181

181-
private async Task AddBuiltinTypesToPathResolverAsync(CancellationToken cancellationToken = default) {
182-
var analyzer = Services.GetService<IPythonAnalyzer>();
183-
await analyzer.GetAnalysisAsync(BuiltinsModule, Timeout.Infinite, cancellationToken);
184-
182+
private void AddBuiltinTypesToPathResolver() {
185183
Check.InvalidOperation(!(BuiltinsModule.Analysis is EmptyAnalysis), "Builtins analysis did not complete correctly.");
186-
187184
// Add built-in module names
188185
var builtinModuleNamesMember = BuiltinsModule.GetAnyMember("__builtin_module_names__");
189186
var value = (builtinModuleNamesMember as IVariable)?.Value ?? builtinModuleNamesMember;
@@ -215,16 +212,16 @@ public async Task ReloadAsync(CancellationToken cancellationToken = default) {
215212
ReloadModulePaths(addedRoots, cancellationToken);
216213

217214
if (!builtinsIsCreated) {
218-
var builtinsModule = CreateBuiltinsModule(Services, Interpreter, StubCache);
219-
BuiltinsModule = builtinsModule;
220-
builtinsRef = new ModuleRef(builtinsModule);
215+
_builtins = CreateBuiltinsModule(Services, Interpreter, StubCache);
216+
builtinsRef = new ModuleRef(_builtins);
217+
_builtins.Initialize();
221218
}
222219

223220
Modules[BuiltinModuleName] = builtinsRef;
224-
await AddBuiltinTypesToPathResolverAsync(cancellationToken);
221+
AddBuiltinTypesToPathResolver();
225222
}
226223

227-
private static IBuiltinsPythonModule CreateBuiltinsModule(IServiceContainer services, IPythonInterpreter interpreter, IStubCache stubCache) {
224+
private static BuiltinsPythonModule CreateBuiltinsModule(IServiceContainer services, IPythonInterpreter interpreter, IStubCache stubCache) {
228225
var moduleName = BuiltinTypeId.Unknown.GetModuleName(interpreter.LanguageVersion);
229226
var modulePath = stubCache.GetCacheFilePath(interpreter.Configuration.InterpreterPath);
230227
return new BuiltinsPythonModule(moduleName, modulePath, services);

0 commit comments

Comments
 (0)