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

Commit ab8ecaf

Browse files
author
MikhailArkhipov
committed
Merge master
2 parents b2c9afb + 3d5e6f9 commit ab8ecaf

Some content is hidden

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

55 files changed

+417
-597
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public IMember GetValueFromIndex(IndexExpression expr) {
4949
}
5050
var index = GetValueFromExpression(expr.Index);
5151
if (index != null) {
52-
return type.Index(instance, index);
52+
return type.Index(instance, new ArgumentSet(new []{index}, expr, this));
5353
}
5454
}
5555

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ private void AssignVariables(FromImportStatement node, IImportSearchResult impor
5959
// TODO: warn this is not a good style per
6060
// TODO: https://docs.python.org/3/faq/programming.html#what-are-the-best-practices-for-using-import-in-a-module
6161
// TODO: warn this is invalid if not in the global scope.
62-
HandleModuleImportStar(variableModule);
62+
HandleModuleImportStar(variableModule, imports is ImplicitPackageImport);
6363
return;
6464
}
6565

@@ -75,14 +75,16 @@ private void AssignVariables(FromImportStatement node, IImportSearchResult impor
7575
}
7676
}
7777

78-
private void HandleModuleImportStar(PythonVariableModule variableModule) {
78+
private void HandleModuleImportStar(PythonVariableModule variableModule, bool isImplicitPackage) {
7979
if (variableModule.Module == Module) {
8080
// from self import * won't define any new members
8181
return;
8282
}
8383

8484
// If __all__ is present, take it, otherwise declare all members from the module that do not begin with an underscore.
85-
var memberNames = variableModule.Analysis.StarImportMemberNames ?? variableModule.GetMemberNames().Where(s => !s.StartsWithOrdinal("_"));
85+
var memberNames = isImplicitPackage
86+
? variableModule.GetMemberNames()
87+
: variableModule.Analysis.StarImportMemberNames ?? variableModule.GetMemberNames().Where(s => !s.StartsWithOrdinal("_"));
8688

8789
foreach (var memberName in memberNames) {
8890
var member = variableModule.GetMember(memberName);

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

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,25 +55,28 @@ private void HandleImport(ModuleName moduleImportExpression, NameExpression asNa
5555
// import_module('fob.oar')
5656
// import_module('fob.oar.baz')
5757
var importNames = ImmutableArray<string>.Empty;
58-
var variableModule = default(PythonVariableModule);
59-
var importedNamesCount = 0;
58+
var lastModule = default(PythonVariableModule);
59+
var firstModule = default(PythonVariableModule);
6060
foreach (var nameExpression in moduleImportExpression.Names) {
6161
importNames = importNames.Add(nameExpression.Name);
6262
var imports = ModuleResolution.CurrentPathResolver.GetImportsFromAbsoluteName(Module.FilePath, importNames, forceAbsolute);
63-
if (!HandleImportSearchResult(imports, variableModule, asNameExpression, moduleImportExpression, out variableModule)) {
63+
if (!HandleImportSearchResult(imports, lastModule, asNameExpression, moduleImportExpression, out lastModule)) {
64+
lastModule = default;
6465
break;
6566
}
6667

67-
importedNamesCount++;
68+
if (firstModule == default) {
69+
firstModule = lastModule;
70+
}
6871
}
6972

7073
// "import fob.oar.baz as baz" is handled as baz = import_module('fob.oar.baz')
7174
// "import fob.oar.baz" is handled as fob = import_module('fob')
72-
if (!string.IsNullOrEmpty(asNameExpression?.Name) && importedNamesCount == moduleImportExpression.Names.Count) {
73-
Eval.DeclareVariable(asNameExpression.Name, variableModule, VariableSource.Import, asNameExpression);
74-
} else if (importedNamesCount > 0 && !string.IsNullOrEmpty(importNames[0]) && _variableModules.TryGetValue(importNames[0], out variableModule)) {
75+
if (!string.IsNullOrEmpty(asNameExpression?.Name) && lastModule != default) {
76+
Eval.DeclareVariable(asNameExpression.Name, lastModule, VariableSource.Import, asNameExpression);
77+
} else if (firstModule != default && !string.IsNullOrEmpty(importNames[0])) {
7578
var firstName = moduleImportExpression.Names[0];
76-
Eval.DeclareVariable(importNames[0], variableModule, VariableSource.Import, firstName);
79+
Eval.DeclareVariable(importNames[0], firstModule, VariableSource.Import, firstName);
7780
}
7881
}
7982

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ public bool IsUserModule {
6565
}
6666
}
6767

68+
public bool IsAnalyzedLibrary(int analysisVersion) {
69+
lock (_syncObj) {
70+
return analysisVersion == _analysisVersion && _analysisTcs.Task.Status == TaskStatus.RanToCompletion && _analysisTcs.Task.Result is LibraryAnalysis;
71+
}
72+
}
73+
6874
public IDocumentAnalysis PreviousAnalysis {
6975
get {
7076
lock (_syncObj) {

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

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ private async Task<int> AnalyzeAffectedEntriesAsync(Stopwatch stopWatch) {
195195
isCanceled = _isCanceled;
196196
}
197197

198-
if (isCanceled && !node.Value.NotAnalyzed) {
198+
if (isCanceled && !node.Value.NotAnalyzed || IsAnalyzedLibraryInLoop(node)) {
199199
remaining++;
200200
node.MoveNext();
201201
continue;
@@ -230,6 +230,9 @@ private async Task<int> AnalyzeAffectedEntriesAsync(Stopwatch stopWatch) {
230230
}
231231

232232

233+
private bool IsAnalyzedLibraryInLoop(IDependencyChainNode<PythonAnalyzerEntry> node)
234+
=> !node.HasMissingDependencies && node.Value.IsAnalyzedLibrary(_walker.Version) && node.IsWalkedWithDependencies && node.IsValidVersion;
235+
233236
private Task StartAnalysis(IDependencyChainNode<PythonAnalyzerEntry> node, AsyncCountdownEvent ace, Stopwatch stopWatch)
234237
=> Task.Run(() => Analyze(node, ace, stopWatch));
235238

@@ -311,10 +314,6 @@ private void AnalyzeEntry() {
311314
}
312315

313316
private void AnalyzeEntry(IDependencyChainNode<PythonAnalyzerEntry> node, PythonAnalyzerEntry entry, IPythonModule module, PythonAst ast, int version) {
314-
if (entry.PreviousAnalysis is LibraryAnalysis) {
315-
_log?.Log(TraceEventType.Verbose, $"Request to re-analyze finalized {module.Name}.");
316-
}
317-
318317
// Now run the analysis.
319318
var analyzable = module as IAnalyzable;
320319
analyzable?.NotifyAnalysisBegins();
@@ -349,7 +348,7 @@ private void AnalyzeEntry(IDependencyChainNode<PythonAnalyzerEntry> node, Python
349348

350349
private void LogCompleted(IDependencyChainNode<PythonAnalyzerEntry> node, IPythonModule module, Stopwatch stopWatch, TimeSpan startTime) {
351350
if (_log != null) {
352-
var completed = node != null && module.Analysis is LibraryAnalysis ? "completed for library" : "completed";
351+
var completed = node != null && module.Analysis is LibraryAnalysis ? "completed for library" : "completed ";
353352
var message = node != null
354353
? $"Analysis of {module.Name}({module.ModuleType}) on depth {node.VertexDepth} {completed} in {(stopWatch.Elapsed - startTime).TotalMilliseconds} ms."
355354
: $"Out of order analysis of {module.Name}({module.ModuleType}) completed in {(stopWatch.Elapsed - startTime).TotalMilliseconds} ms.";

src/Analysis/Ast/Impl/Analyzer/Symbols/ClassEvaluator.cs

Lines changed: 12 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,19 @@ public void EvaluateClass() {
5353
EvaluateInnerClasses(_classDef);
5454

5555
_class = classInfo;
56-
57-
var bases = ProcessBases(outerScope);
58-
56+
// Set bases to the class.
57+
var bases = new List<IPythonType>();
58+
foreach (var a in _classDef.Bases.Where(a => string.IsNullOrEmpty(a.Name))) {
59+
// We cheat slightly and treat base classes as annotations.
60+
var b = Eval.GetTypeFromAnnotation(a.Expression);
61+
if (b != null) {
62+
var t = b.GetPythonType();
63+
bases.Add(t);
64+
t.AddReference(Eval.GetLocationOfName(a.Expression));
65+
}
66+
}
5967
_class.SetBases(bases);
68+
6069
// Declare __class__ variable in the scope.
6170
Eval.DeclareVariable("__class__", _class, VariableSource.Declaration);
6271
ProcessClassBody();
@@ -111,47 +120,6 @@ private void ProcessClassBody() {
111120
UpdateClassMembers();
112121
}
113122

114-
private IEnumerable<IPythonType> ProcessBases(Scope outerScope) {
115-
var bases = new List<IPythonType>();
116-
foreach (var a in _classDef.Bases.Where(a => string.IsNullOrEmpty(a.Name))) {
117-
var expr = a.Expression;
118-
119-
switch (expr) {
120-
// class declared in the current module
121-
case NameExpression nameExpression:
122-
var name = Eval.GetInScope(nameExpression.Name, outerScope);
123-
switch (name) {
124-
case PythonClassType classType:
125-
bases.Add(classType);
126-
break;
127-
case IPythonConstant constant:
128-
ReportInvalidBase(constant.Value);
129-
break;
130-
default:
131-
TryAddBase(bases, a);
132-
break;
133-
}
134-
break;
135-
default:
136-
TryAddBase(bases, a);
137-
break;
138-
}
139-
}
140-
return bases;
141-
}
142-
143-
private void TryAddBase(List<IPythonType> bases, Arg arg) {
144-
// We cheat slightly and treat base classes as annotations.
145-
var b = Eval.GetTypeFromAnnotation(arg.Expression);
146-
if (b != null) {
147-
var t = b.GetPythonType();
148-
bases.Add(t);
149-
t.AddReference(Eval.GetLocationOfName(arg.Expression));
150-
} else {
151-
ReportInvalidBase(arg.ToCodeString(Eval.Ast, CodeFormattingOptions.Traditional));
152-
}
153-
}
154-
155123
private void EvaluateConstructors(ClassDefinition cd) {
156124
// Do not use foreach since walker list is dynamically modified and walkers are removed
157125
// after processing. Handle __init__ and __new__ first so class variables are initialized.
@@ -186,17 +154,6 @@ private void UpdateClassMembers() {
186154
_class.AddMembers(members, false);
187155
}
188156

189-
private void ReportInvalidBase(object argVal) {
190-
Eval.ReportDiagnostics(Eval.Module.Uri,
191-
new DiagnosticsEntry(
192-
Resources.InheritNonClass.FormatInvariant(argVal),
193-
_classDef.NameExpression.GetLocation(Eval)?.Span ?? default,
194-
Diagnostics.ErrorCodes.InheritNonClass,
195-
Severity.Error,
196-
DiagnosticSource.Analysis
197-
));
198-
}
199-
200157
// Classes and functions are walked by their respective evaluators
201158
public override bool Walk(ClassDefinition node) => false;
202159
public override bool Walk(FunctionDefinition node) => false;

src/Analysis/Ast/Impl/Dependencies/DependencyResolver.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,7 @@ private sealed class DependencyChainNode : IDependencyChainNode<TValue> {
691691
public int VertexDepth { get; }
692692
public bool HasMissingDependencies => _vertex.HasMissingDependencies;
693693
public bool HasOnlyWalkedDependencies => _vertex.HasOnlyWalkedIncoming && _vertex.SecondPass == default;
694+
public bool IsWalkedWithDependencies => _vertex.HasOnlyWalkedIncoming && _vertex.DependencyVertex.IsWalked;
694695
public bool IsValidVersion => _walker.IsValidVersion;
695696

696697
public DependencyChainNode(DependencyChainWalker walker, WalkingVertex<TKey, TValue> vertex, int depth) {

src/Analysis/Ast/Impl/Dependencies/IDependencyChainNode.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ internal interface IDependencyChainNode<out TValue> {
2626
/// </summary>
2727
bool HasOnlyWalkedDependencies { get; }
2828
/// <summary>
29+
/// Returns true if node has been walked and all its direct and indirect dependencies have been walked, otherwise false
30+
/// </summary>
31+
bool IsWalkedWithDependencies { get; }
32+
/// <summary>
2933
/// Returns true if node version matches version of the walked graph
3034
/// </summary>
3135
bool IsValidVersion { get; }

src/Analysis/Ast/Impl/Diagnostics/ErrorCodes.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,5 @@ public static class ErrorCodes {
2929
public const string ReturnInInit = "return-in-init";
3030
public const string TypingNewTypeArguments = "typing-newtype-arguments";
3131
public const string TypingGenericArguments = "typing-generic-arguments";
32-
public const string InheritNonClass = "inherit-non-class";
3332
}
3433
}

src/Analysis/Ast/Impl/Extensions/NodeExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public static LocationInfo GetLocation(this Node node, IExpressionEvaluator eval
2626

2727
return GetLocation(node, eval.Ast, eval.Module);
2828
}
29+
2930
public static LocationInfo GetLocation(this Node node, IDocumentAnalysis analysis) {
3031
if (node == null || node.StartIndex >= node.EndIndex) {
3132
return LocationInfo.Empty;

0 commit comments

Comments
 (0)