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

Commit 838ba78

Browse files
author
Mikhail Arkhipov
authored
Undo loop optimization (#2077)
* Undo loop optimization * Undo loop optimization * Restore changes from unmergeable PRs * Unused file * Port changes from skipper PRs * Minimize changes * Further minimize * Further simplify * Fix test
1 parent 2aef1f8 commit 838ba78

File tree

137 files changed

+1920
-2594
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

137 files changed

+1920
-2594
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ private AnalysisModuleKey(string name, string filePath, bool isTypeshed, bool is
4040
Name = name;
4141
FilePath = filePath;
4242
IsTypeshed = isTypeshed;
43+
IsNonUserAsDocument = isNonUserAsDocument;
4344
}
4445

4546
public AnalysisModuleKey GetNonUserAsDocumentKey() => new AnalysisModuleKey(Name, FilePath, IsTypeshed, true);
@@ -70,6 +71,8 @@ public void Deconstruct(out string moduleName, out string filePath, out bool isT
7071

7172
public override string ToString() => $"{Name}({FilePath})";
7273

74+
public bool IsNonUserAsDocument { get; }
75+
7376
private static bool IsNonUserAsDocumentModule(IPythonModule module)
7477
=> (module.IsNonUserFile() || module.IsCompiled()) && module is IDocument document && document.IsOpen;
7578
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ internal abstract class AnalysisWalker : PythonWalker {
4040
public PythonAst Ast => Eval.Ast;
4141
protected ModuleSymbolTable SymbolTable => Eval.SymbolTable;
4242

43-
protected AnalysisWalker(ExpressionEval eval, IImportedVariableHandler importedVariableHandler) {
43+
protected AnalysisWalker(ExpressionEval eval) {
4444
Eval = eval;
45-
ImportHandler = new ImportHandler(this, importedVariableHandler);
45+
ImportHandler = new ImportHandler(this);
4646
AssignmentHandler = new AssignmentHandler(this);
4747
LoopHandler = new LoopHandler(this);
4848
ConditionalHandler = new ConditionalHandler(this);

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ namespace Microsoft.Python.Analysis.Analyzer {
2121
/// Represents document that can be analyzed asynchronously.
2222
/// </summary>
2323
internal interface IAnalyzable {
24+
/// <summary>
25+
/// Returns object that can calculate dependencies of this entry.
26+
/// </summary>
27+
IDependencyProvider DependencyProvider { get; }
28+
2429
/// <summary>
2530
/// Notifies document that analysis is about to begin.
2631
/// </summary>

src/Analysis/Ast/Impl/Analyzer/Evaluation/ExpressionEval.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ public ExpressionEval(IServiceContainer services, IPythonModule module, PythonAs
6060
public LocationInfo GetLocationInfo(Node node) => node?.GetLocation(this) ?? LocationInfo.Empty;
6161

6262
public Location GetLocationOfName(Node node) {
63-
if (node == null ||
64-
Module.ModuleType == ModuleType.Specialized || Module.ModuleType == ModuleType.Compiled ||
63+
if (node == null ||
64+
Module.ModuleType == ModuleType.Specialized || Module.ModuleType == ModuleType.Compiled ||
6565
Module.ModuleType == ModuleType.CompiledBuiltin || Module.ModuleType == ModuleType.Builtins) {
6666
return DefaultLocation;
6767
}

src/Analysis/Ast/Impl/Analyzer/Evaluation/FunctionCallEvaluator.cs

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

1616
using System;
17-
using Microsoft.Python.Analysis.Analyzer.Handlers;
1817
using Microsoft.Python.Analysis.Analyzer.Symbols;
1918
using Microsoft.Python.Analysis.Types;
2019
using Microsoft.Python.Parsing.Ast;
@@ -29,7 +28,7 @@ internal sealed class FunctionCallEvaluator: AnalysisWalker {
2928
private readonly FunctionDefinition _function;
3029
private IMember _result;
3130

32-
public FunctionCallEvaluator(IPythonModule declaringModule, FunctionDefinition fd, ExpressionEval eval): base(eval, SimpleImportedVariableHandler.Instance) {
31+
public FunctionCallEvaluator(IPythonModule declaringModule, FunctionDefinition fd, ExpressionEval eval): base(eval) {
3332
_declaringModule = declaringModule ?? throw new ArgumentNullException(nameof(declaringModule));
3433
_eval = eval ?? throw new ArgumentNullException(nameof(eval));
3534
_function = fd ?? throw new ArgumentNullException(nameof(fd));

src/Analysis/Ast/Impl/Analyzer/Handlers/FromImportHandler.cs

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,6 @@ private void AssignVariables(FromImportStatement node, IImportSearchResult impor
6868
if (!string.IsNullOrEmpty(variableName)) {
6969
DeclareVariable(variableModule, memberName, imports, variableName, node.StartIndex, nameExpression);
7070
}
71-
72-
if (imports is IImportChildrenSource cs
73-
&& cs.TryGetChildImport(memberName, out var csr)
74-
&& HandleImportSearchResult(csr, variableModule, null, names[i], out var childModule)) {
75-
76-
_importedVariableHandler.EnsureModule(childModule);
77-
}
7871
}
7972
}
8073

@@ -83,11 +76,11 @@ private void HandleModuleImportStar(PythonVariableModule variableModule, IImport
8376
// from self import * won't define any new members
8477
return;
8578
}
86-
8779
// If __all__ is present, take it, otherwise declare all members from the module that do not begin with an underscore.
8880
var memberNames = imports is ImplicitPackageImport
8981
? variableModule.GetMemberNames()
90-
: _importedVariableHandler.GetMemberNames(variableModule).ToArray();
82+
: variableModule.Analysis.StarImportMemberNames
83+
?? variableModule.GetMemberNames().Where(s => !s.StartsWithOrdinal("_")).ToArray();
9184

9285
foreach (var memberName in memberNames) {
9386
DeclareVariable(variableModule, memberName, imports, memberName, importPosition, nameExpression);
@@ -114,27 +107,14 @@ private void DeclareVariable(PythonVariableModule variableModule, string memberN
114107
value = GetValueFromImports(variableModule, imports as IImportChildrenSource, memberName);
115108

116109
// First try exported or child submodules.
117-
var member = variableModule.GetMember(memberName);
110+
value = value ?? variableModule.GetMember(memberName);
118111

119112
// Value may be variable or submodule. If it is variable, we need it in order to add reference.
120-
var variable = _importedVariableHandler.GetVariable(variableModule, memberName);
121-
122-
if (member is PythonVariableModule vm && vm.Equals(variable?.Value)) {
123-
// If member is submodule, use actual variable so it can be linked through for goto definition.
124-
value = variable;
125-
} else if (value == null) {
126-
if (member is PythonVariableModule) {
127-
// If member is submodule, use it.
128-
value = member;
129-
} else if (variable?.Value != null) {
130-
// Otherwise use variable, if available so references can be linked.
131-
value = variable;
132-
} else if (member != null) {
133-
value = member;
134-
} else {
135-
value = Eval.UnknownType;
136-
}
137-
}
113+
var variable = variableModule.Analysis?.GlobalScope?.Variables[memberName];
114+
value = variable?.Value?.Equals(value) == true ? variable : value;
115+
116+
// If nothing is exported, variables are still accessible.
117+
value = value ?? variableModule.Analysis?.GlobalScope?.Variables[memberName]?.Value ?? Eval.UnknownType;
138118
}
139119

140120
// Do not allow imported variables to override local declarations

src/Analysis/Ast/Impl/Analyzer/Handlers/ImportHandler.cs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,9 @@
2929

3030
namespace Microsoft.Python.Analysis.Analyzer.Handlers {
3131
internal sealed partial class ImportHandler : StatementHandler {
32-
private readonly IImportedVariableHandler _importedVariableHandler;
3332
private readonly Dictionary<string, PythonVariableModule> _variableModules = new Dictionary<string, PythonVariableModule>();
3433

35-
public ImportHandler(AnalysisWalker walker, in IImportedVariableHandler importedVariableHandler) : base(walker) {
36-
_importedVariableHandler = importedVariableHandler;
37-
}
34+
public ImportHandler(AnalysisWalker walker) : base(walker) { }
3835

3936
public bool HandleImport(ImportStatement node) {
4037
if (Module.ModuleType == ModuleType.Specialized) {
@@ -68,9 +65,7 @@ private void HandleImport(ModuleName moduleImportExpression, NameExpression asNa
6865
lastModule = default;
6966
break;
7067
}
71-
7268
resolvedModules[i] = (nameExpression.Name, lastModule);
73-
_importedVariableHandler.EnsureModule(lastModule);
7469
}
7570

7671
// "import fob.oar.baz as baz" is handled as baz = import_module('fob.oar.baz')
@@ -94,6 +89,15 @@ private void HandleImport(ModuleName moduleImportExpression, NameExpression asNa
9489
Eval.DeclareVariable(importNames[0], firstModule, VariableSource.Import, moduleImportExpression.Names[0]);
9590
}
9691
}
92+
93+
// import a.b.c.d => declares a, b in the current module, c in b, d in c.
94+
for (var i = 1; i < resolvedModules.Length - 1; i++) {
95+
var (childName, childModule) = resolvedModules[i + 1];
96+
if (!string.IsNullOrEmpty(childName) && childModule != null) {
97+
var parent = resolvedModules[i].module;
98+
parent?.AddChildModule(childName, childModule);
99+
}
100+
}
97101
}
98102

99103
private bool HandleImportSearchResult(in IImportSearchResult imports, in PythonVariableModule parent, in NameExpression asNameExpression, in Node location, out PythonVariableModule variableModule) {
@@ -108,7 +112,8 @@ private bool HandleImportSearchResult(in IImportSearchResult imports, in PythonV
108112
return TryGetPackageFromImport(packageImport, parent, out variableModule);
109113
case RelativeImportBeyondTopLevel importBeyondTopLevel:
110114
var message = Resources.ErrorRelativeImportBeyondTopLevel.FormatInvariant(importBeyondTopLevel.RelativeImportName);
111-
Eval.ReportDiagnostics(Eval.Module.Uri, new DiagnosticsEntry(message, location.GetLocation(Eval).Span, ErrorCodes.UnresolvedImport, Severity.Warning, DiagnosticSource.Analysis));
115+
Eval.ReportDiagnostics(Eval.Module.Uri,
116+
new DiagnosticsEntry(message, location.GetLocation(Eval).Span, ErrorCodes.UnresolvedImport, Severity.Warning, DiagnosticSource.Analysis));
112117
variableModule = default;
113118
return false;
114119
case ImportNotFound importNotFound:
@@ -172,7 +177,7 @@ private bool TryGetModulePossibleImport(PossibleModuleImport possibleModuleImpor
172177
return false;
173178
}
174179
}
175-
180+
176181
return true;
177182
}
178183

@@ -195,7 +200,7 @@ private PythonVariableModule GetOrCreateVariableModule(in string fullName, in Py
195200
variableModule = new PythonVariableModule(fullName, Eval.Interpreter);
196201
_variableModules[fullName] = variableModule;
197202
}
198-
203+
199204
parentModule?.AddChildModule(memberName, variableModule);
200205
return variableModule;
201206
}

src/Analysis/Ast/Impl/Analyzer/Handlers/LoopImportedVariableHandler.cs

Lines changed: 0 additions & 124 deletions
This file was deleted.

src/Analysis/Ast/Impl/Analyzer/Handlers/SimpleImportedVariableHandler.cs

Lines changed: 0 additions & 36 deletions
This file was deleted.

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
using System.Linq;
1919
using System.Threading;
2020
using Microsoft.Python.Analysis.Analyzer.Evaluation;
21-
using Microsoft.Python.Analysis.Analyzer.Handlers;
2221
using Microsoft.Python.Analysis.Documents;
2322
using Microsoft.Python.Analysis.Types;
2423
using Microsoft.Python.Analysis.Types.Collections;
@@ -38,7 +37,8 @@ internal class ModuleWalker : AnalysisWalker {
3837
private int _allReferencesCount;
3938
private bool _allIsUsable = true;
4039

41-
public ModuleWalker(ExpressionEval eval, IImportedVariableHandler importedVariableHandler) : base(eval, importedVariableHandler) {
40+
public ModuleWalker(IServiceContainer services, IPythonModule module, PythonAst ast, CancellationToken cancellationToken)
41+
: base(new ExpressionEval(services, module, ast)) {
4242
_stubAnalysis = Module.Stub is IDocument doc ? doc.GetAnyAnalysis() : null;
4343
_cancellationToken = CancellationToken.None;
4444
}
@@ -206,7 +206,7 @@ public void Complete() {
206206
new StubMerger(Eval).MergeStub(_stubAnalysis, _cancellationToken);
207207

208208
if (_allIsUsable && _allReferencesCount >= 1 && GlobalScope.Variables.TryGetVariable(AllVariableName, out var variable)
209-
&& variable.Value is IPythonCollection collection && collection.IsExact) {
209+
&& variable?.Value is IPythonCollection collection && collection.IsExact) {
210210
StarImportMemberNames = collection.Contents
211211
.OfType<IPythonConstant>()
212212
.Select(c => c.GetString())

0 commit comments

Comments
 (0)