Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Apr 14, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
b605b76
Remove old qualified name
May 17, 2019
5471ce4
Node storage
May 17, 2019
8a8d847
Class and scope to use AST map
May 17, 2019
89ce2ca
Library analysis
May 17, 2019
7a93bf7
Fix SO
May 18, 2019
2a2bdf8
Keep small AST with imports
May 18, 2019
3edaa73
AST reduction
May 18, 2019
73371e1
Final field
May 18, 2019
7d60edc
Initial
May 20, 2019
02475f4
Reload
May 22, 2019
835eeac
Merge master
May 25, 2019
6b6e928
Ignore post-final requests
May 25, 2019
9692397
Drop AST
May 25, 2019
080beab
Remove local variables
May 25, 2019
93a6915
Test fixes
May 26, 2019
cadd7ce
Fix overload match
May 26, 2019
f61b1a7
Tests
May 26, 2019
1b20326
Add locks
May 27, 2019
d7efdac
Remove local variables
May 25, 2019
98934d4
Drop file content to save memory
May 27, 2019
417ae03
Cache PEP hints
May 28, 2019
ec5605f
Recreate AST
May 28, 2019
713d87f
Fix specialization
May 28, 2019
50e63e6
Fix locations
May 28, 2019
fcd0c06
usings
May 28, 2019
f6a992b
Test fixes
May 28, 2019
acad202
Add options to keep data in memory
May 28, 2019
f176b2f
Merge branch 'master' of https://github.com/microsoft/python-language…
May 28, 2019
4225337
Merge master
May 28, 2019
86e36a6
Fix test
May 28, 2019
ba97e9f
Fix lambda parameters
May 28, 2019
ffed87e
Fix argument set
May 29, 2019
186a9c6
Fix overload doc
May 29, 2019
4196699
Fix stub merge errors
May 29, 2019
93249d4
Fix async issues
May 29, 2019
5e61392
Undo some changes
May 29, 2019
130b95d
Fix test
May 29, 2019
a6676f1
Fix race condition
May 30, 2019
18b61ad
Merge master
Jun 1, 2019
0850544
Merge master
Jun 3, 2019
7d0bf5b
Merge branch 'proxymod' into db
Jun 4, 2019
663dc8f
Partial
Jun 4, 2019
86544a6
Models and views
Jun 4, 2019
67b06c2
Merge branch 'master' of https://github.com/microsoft/python-language…
Jun 4, 2019
9daf4a9
Merge master
Jun 4, 2019
90318e9
Restore log null checks
Jun 4, 2019
b79d918
Merge master
Jun 4, 2019
a02c6f3
Fix merge conflict
Jun 4, 2019
8a6b055
Merge master
Jun 5, 2019
57358eb
Fix merge issue
Jun 5, 2019
41ef00f
Merge branch 'master' of https://github.com/microsoft/python-language…
Jun 5, 2019
814cd64
Merge master
Jun 6, 2019
6ceb9b8
Null check
Jun 6, 2019
74bb061
Merge branch 'noast5' into db
Jun 6, 2019
478ce37
Partial
Jun 6, 2019
cb46e68
Partial
Jun 6, 2019
ef2981c
Partial
Jun 6, 2019
2164ad5
Fix test
Jun 6, 2019
1a48790
Merge branch 'noast5' into db
Jun 6, 2019
319c416
Partial
Jun 6, 2019
86b0ee6
Partial
Jun 7, 2019
1670c9d
First test
Jun 7, 2019
ab69cfd
Baseline comparison
Jun 7, 2019
e00c197
Builtins
Jun 7, 2019
4e1657c
Partial
Jun 7, 2019
ade00f4
Type fixes
Jun 10, 2019
e2fc221
Fix type names, part I
Jun 11, 2019
aaf40bb
Qualified name
Jun 11, 2019
a5b3b20
Properly write variables
Jun 11, 2019
f23a487
Partial
Jun 11, 2019
e6373a7
Construct module from model
Jun 12, 2019
6f6737d
Test
Jun 12, 2019
081f475
Variable creations
Jun 12, 2019
42fa4dc
Factories
Jun 13, 2019
2f03cb9
Factories
Jun 13, 2019
1dc3339
Split construction
Jun 13, 2019
9535bad
Restore
Jun 13, 2019
bec2a82
Save builtins
Jun 13, 2019
80c9b1c
Test passes
Jun 13, 2019
5b372f7
Qualified name
Jun 13, 2019
3066554
Better export detection
Jun 14, 2019
91491d4
Test fixes
Jun 14, 2019
bc4f587
More consistent qualified names
Jun 14, 2019
af69880
Sys test
Jun 14, 2019
5c1a0c3
Demo
Jun 14, 2019
4146690
Complete sys write/read
Jun 17, 2019
48763aa
Partial
Jun 17, 2019
93bece3
Partial
Jun 18, 2019
55b6a3f
Test staility
Jun 18, 2019
5e9bf8e
Perf bug
Jun 18, 2019
c152e67
Merge master
Jun 18, 2019
eadd622
Baseline, remove debug code, deactivate db
Jun 18, 2019
ba87581
Test fixes
Jun 18, 2019
a797593
Test fix
Jun 18, 2019
db6c7fc
Simplify a bit
Jun 19, 2019
f73fed0
Baselines and use : separator
Jun 19, 2019
4054d5a
Baselines
Jun 19, 2019
4ef96d8
PR feedback
Jun 19, 2019
c7436ed
Merge branch 'master' of https://github.com/microsoft/python-language…
Jun 19, 2019
f3860e6
Merge master
Jun 19, 2019
cab0fce
Remove registry reference
Jun 19, 2019
b9c1e14
PR feedback
Jun 19, 2019
14df8d4
Avoid empty node in empty global scope (#1226)
Jun 20, 2019
18a6cf5
Lock content since it is locked in other cases (#1227)
Jun 20, 2019
a3c675c
Fix addBrackets setting (#1241)
Jun 21, 2019
53de3cd
Handle library analysis better (#1246)
Jun 21, 2019
d61f63d
Trying to augment argument set with Evaluator and Expression context …
CTrando Jun 28, 2019
b917bda
When returning in init method, report a diagnostic error (#1261)
CTrando Jul 2, 2019
89bafc3
Give Diagnostic messages on improper usage of Generic (#1248)
CTrando Jul 2, 2019
753220f
Adding diagnostic error on binary operations with incompatible types …
CTrando Jul 2, 2019
4ece7cb
When NewType is called and the first argument is not a string, make a…
CTrando Jul 3, 2019
b826df7
Fix typo in TROUBLESHOOTING.md (#1285)
m8mble Jul 8, 2019
5f322f0
Multiple analysis fixes (#1297)
AlexanderSher Jul 9, 2019
76098c1
Rework search path resolution (#1289)
jakebailey Jul 10, 2019
4812d92
No diagnostic message when Generic is called with no args (#1305)
CTrando Jul 10, 2019
39d7437
When a class inherits from something that is not a class, give a diag…
CTrando Jul 11, 2019
4fbdcb9
Merge master
Jul 11, 2019
c7b1a5d
Merge db
Jul 11, 2019
90d1429
PR feedback
Jul 11, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion TROUBLESHOOTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Python is a requirement for the language server to run. In VS Code, an interpret
_must_ be selected in order for the language server to properly initialize. If your
language server fails to start, be sure that you have selected an interpreter.

The language server can only run on platforms where the .NET Core can run. This rougly means:
The language server can only run on platforms where the .NET Core can run. This roughly means:

- Windows, 32/64 bit
- macOS, 64 bit
Expand Down
42 changes: 4 additions & 38 deletions src/Analysis/Ast/Impl/Analyzer/ActivityTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,48 +19,21 @@

namespace Microsoft.Python.Analysis.Analyzer {
internal static class ActivityTracker {
private static readonly Dictionary<string, AnalysisState> _modules = new Dictionary<string, AnalysisState>();
private static readonly HashSet<string> _modules = new HashSet<string>();
private static readonly object _lock = new object();
private static bool _tracking;
private static Stopwatch _sw;

private struct AnalysisState {
public int Count;
public bool IsComplete;
}

public static void OnEnqueueModule(string path) {
if (string.IsNullOrEmpty(path)) {
return;
}

lock (_lock) {
if (!_modules.TryGetValue(path, out var st)) {
_modules[path] = default;
} else {
st.IsComplete = false;
}
}
}

public static void OnModuleAnalysisComplete(string path) {
lock (_lock) {
if (_modules.TryGetValue(path, out var st)) {
st.Count++;
st.IsComplete = true;
}
_modules.Add(path);
}
}

public static bool IsAnalysisComplete {
get {
lock (_lock) {
return _modules.All(m => m.Value.IsComplete);
}
}
}


public static void StartTracking() {
lock (_lock) {
if (!_tracking) {
Expand All @@ -71,22 +44,15 @@ public static void StartTracking() {
}
}

public static void EndTracking() {
public static (int modulesCount, double totalMilliseconds) EndTracking() {
lock (_lock) {
if (_tracking) {
_sw?.Stop();
_tracking = false;
}
}
}

public static int ModuleCount {
get {
lock (_lock) {
return _modules.Count;
}
return (_modules.Count, _sw?.Elapsed.TotalMilliseconds ?? 0);
}
}
public static double MillisecondsElapsed => _sw?.Elapsed.TotalMilliseconds ?? 0;
}
}
29 changes: 23 additions & 6 deletions src/Analysis/Ast/Impl/Analyzer/AnalysisModuleKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,56 @@

using System;
using System.Diagnostics;
using Microsoft.Python.Analysis.Documents;
using Microsoft.Python.Analysis.Modules;
using Microsoft.Python.Analysis.Types;
using Microsoft.Python.Core;

namespace Microsoft.Python.Analysis.Analyzer {
[DebuggerDisplay("{Name} : {FilePath}")]
internal struct AnalysisModuleKey : IEquatable<AnalysisModuleKey> {
internal readonly struct AnalysisModuleKey : IEquatable<AnalysisModuleKey> {
private enum KeyType { Default, Typeshed, LibraryAsDocument }

private readonly KeyType _type;
public string Name { get; }
public string FilePath { get; }
public bool IsTypeshed { get; }
public bool IsTypeshed => _type == KeyType.Typeshed;
public bool IsLibraryAsDocument => _type == KeyType.LibraryAsDocument;

public AnalysisModuleKey(IPythonModule module) {
Name = module.Name;
FilePath = module.ModuleType == ModuleType.CompiledBuiltin ? null : module.FilePath;
IsTypeshed = module is StubPythonModule stub && stub.IsTypeshed;
_type = module is StubPythonModule stub && stub.IsTypeshed
? KeyType.Typeshed
: module.ModuleType == ModuleType.Library && module is IDocument document && document.IsOpen
? KeyType.LibraryAsDocument
: KeyType.Default;
}

public AnalysisModuleKey(string name, string filePath, bool isTypeshed) {
Name = name;
FilePath = filePath;
IsTypeshed = isTypeshed;
_type = isTypeshed ? KeyType.Typeshed : KeyType.Default;
}

private AnalysisModuleKey(string name, string filePath, KeyType type) {
Name = name;
FilePath = filePath;
_type = type;
}

public AnalysisModuleKey GetLibraryAsDocumentKey() => new AnalysisModuleKey(Name, FilePath, KeyType.LibraryAsDocument);

public bool Equals(AnalysisModuleKey other)
=> Name.EqualsOrdinal(other.Name) && FilePath.PathEquals(other.FilePath) && IsTypeshed == other.IsTypeshed;
=> Name.EqualsOrdinal(other.Name) && FilePath.PathEquals(other.FilePath) && _type == other._type;

public override bool Equals(object obj) => obj is AnalysisModuleKey other && Equals(other);

public override int GetHashCode() {
unchecked {
var hashCode = (Name != null ? Name.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (FilePath != null ? FilePath.GetPathHashCode() : 0);
hashCode = (hashCode * 397) ^ IsTypeshed.GetHashCode();
hashCode = (hashCode * 397) ^ _type.GetHashCode();
return hashCode;
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/Analysis/Ast/Impl/Analyzer/Definitions/IAnalyzable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ internal interface IAnalyzable {
/// <summary>
/// Notifies document that its analysis is now complete.
/// </summary>
void NotifyAnalysisComplete(int version, ModuleWalker walker, bool isFinalPass);
/// <param name="analysis">Document analysis</param>
void NotifyAnalysisComplete(IDocumentAnalysis analysis);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@
using Microsoft.Python.Analysis.Diagnostics;
using Microsoft.Python.Analysis.Types;
using Microsoft.Python.Core.Collections;
using Microsoft.Python.Parsing.Ast;

namespace Microsoft.Python.Analysis.Analyzer {
public interface IPythonAnalyzer {
Task WaitForCompleteAnalysisAsync(CancellationToken cancellationToken = default);
/// <summary>
/// Schedules module for analysis. Module will be scheduled if version of AST is greater than the one used to get previous analysis
/// </summary>
void EnqueueDocumentForAnalysis(IPythonModule module, int version);
void EnqueueDocumentForAnalysis(IPythonModule module, PythonAst ast, int version);

/// <summary>
/// Schedules module for analysis for its existing AST, but with new dependencies.
Expand Down
2 changes: 1 addition & 1 deletion src/Analysis/Ast/Impl/Analyzer/EmptyAnalysis.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public EmptyAnalysis(IServiceContainer services, IDocument document) {
Document = document ?? throw new ArgumentNullException(nameof(document));
GlobalScope = new EmptyGlobalScope(document);
Ast = AstUtilities.MakeEmptyAst(document.Uri);
ExpressionEvaluator = new ExpressionEval(services, document);
ExpressionEvaluator = new ExpressionEval(services, document, Ast);
}

public IDocument Document { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@ public IMember GetValueFromLambda(LambdaExpression expr) {
public IMember GetValueFromClassCtor(IPythonClassType cls, CallExpression expr) {
SymbolTable.Evaluate(cls.ClassDefinition);
// Determine argument types
var args = ArgumentSet.Empty;
var args = ArgumentSet.Empty(expr, this);
var init = cls.GetMember<IPythonFunctionType>(@"__init__");
if (init != null) {
using (OpenScope(cls.DeclaringModule, cls.ClassDefinition, out _)) {
var a = new ArgumentSet(init, 0, new PythonInstance(cls), expr, Module, this);
var a = new ArgumentSet(init, 0, new PythonInstance(cls), expr, this);
if (a.Errors.Count > 0) {
// AddDiagnostics(Module.Uri, a.Errors);
}
Expand All @@ -108,7 +108,7 @@ private IMember GetValueFromBound(IPythonBoundType t, CallExpression expr) {
case IPythonFunctionType fn:
return GetValueFromFunctionType(fn, t.Self, expr);
case IPythonPropertyType p:
return GetValueFromProperty(p, t.Self);
return GetValueFromProperty(p, t.Self, expr);
case IPythonIteratorType _ when t.Self is IPythonCollection seq:
return seq.GetIterator();
}
Expand Down Expand Up @@ -201,10 +201,10 @@ public IMember GetValueFromFunctionType(IPythonFunctionType fn, IPythonInstance
return UnknownType;
}

private IMember GetValueFromProperty(IPythonPropertyType p, IPythonInstance instance) {
private IMember GetValueFromProperty(IPythonPropertyType p, IPythonInstance instance, CallExpression expr) {
// Function may not have been walked yet. Do it now.
SymbolTable.Evaluate(p.FunctionDefinition);
return instance.Call(p.Name, ArgumentSet.Empty);
return instance.Call(p.Name, ArgumentSet.Empty(expr, this));
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Python.Analysis.Diagnostics;
using Microsoft.Python.Analysis.Specializations.Typing;
using Microsoft.Python.Analysis.Specializations.Typing.Types;
using Microsoft.Python.Analysis.Types;
using Microsoft.Python.Analysis.Values;
using Microsoft.Python.Core;
using Microsoft.Python.Parsing;
using Microsoft.Python.Parsing.Ast;
using ErrorCodes = Microsoft.Python.Analysis.Diagnostics.ErrorCodes;

namespace Microsoft.Python.Analysis.Analyzer.Evaluation {
internal sealed partial class ExpressionEval {
Expand Down Expand Up @@ -59,40 +62,58 @@ private IMember GetValueFromGeneric(IMember target, Expression expr) {
}

/// <summary>
/// Given generic type and list of indices in the expression like
/// Generic[T1, T2, ...] or List[str] creates generic class base
/// (if the former) on specific type (if the latter).
/// Returns whether the arguments to Generic are valid
/// </summary>
private IMember CreateSpecificTypeFromIndex(IGenericType gt, IReadOnlyList<IMember> indices, Expression expr) {
// See which ones are generic parameters as defined by TypeVar()
// and which are specific types. Normally there should not be a mix.
var genericTypeArgs = indices.OfType<IGenericTypeDefinition>().ToArray();
var specificTypes = indices.Where(i => !(i is IGenericTypeDefinition)).OfType<IPythonType>().ToArray();

if (genericTypeArgs.Length > 0 && genericTypeArgs.Length != indices.Count) {
// TODO: report that some type arguments are not declared with TypeVar.
private bool GenericClassParameterValid(IReadOnlyList<IGenericTypeDefinition> genericTypeArgs, IReadOnlyList<IMember> args, Expression expr) {
// All arguments to Generic must be type parameters
// e.g. Generic[T, str] throws a runtime error
if (genericTypeArgs.Count != args.Count) {
ReportDiagnostics(Module.Uri, new DiagnosticsEntry(
Resources.GenericNotAllTypeParameters,
GetLocation(expr).Span,
ErrorCodes.TypingGenericArguments,
Severity.Error,
DiagnosticSource.Analysis));
return false;
}
if (specificTypes.Length > 0 && specificTypes.Length != indices.Count) {
// TODO: report that arguments are not specific types or are not declared.

// All arguments to Generic must be distinct
if (genericTypeArgs.Distinct().Count() != genericTypeArgs.Count) {
ReportDiagnostics(Module.Uri, new DiagnosticsEntry(
Resources.GenericNotAllUnique,
GetLocation(expr).Span,
ErrorCodes.TypingGenericArguments,
Severity.Error,
DiagnosticSource.Analysis));
return false;
}

return true;
}

/// <summary>
/// Given generic type and list of arguments in the expression like
/// Generic[T1, T2, ...] or List[str] creates generic class base
/// (if the former) on specific type (if the latter).
/// </summary>
private IMember CreateSpecificTypeFromIndex(IGenericType gt, IReadOnlyList<IMember> args, Expression expr) {
var genericTypeArgs = args.OfType<IGenericTypeDefinition>().ToArray();

if (gt.Name.EqualsOrdinal("Generic")) {
// Generic[T1, T2, ...] expression. Create generic base for the class.
if (genericTypeArgs.Length > 0) {
return new GenericClassParameter(genericTypeArgs, Module);
} else {
// TODO: report too few type arguments for Generic[].
if (!GenericClassParameterValid(genericTypeArgs, args, expr)) {
return UnknownType;
}

// Generic[T1, T2, ...] expression. Create generic base for the class.
return new GenericClassParameter(genericTypeArgs, Module);
}

// For other types just use supplied arguments
if (indices.Count > 0) {
return gt.CreateSpecificType(new ArgumentSet(indices));
if (args.Count > 0) {
return gt.CreateSpecificType(new ArgumentSet(args, expr, this));
}
// TODO: report too few type arguments for the generic expression.
return UnknownType;

return UnknownType;
}

private IReadOnlyList<IMember> EvaluateIndex(IndexExpression expr) {
Expand All @@ -104,7 +125,10 @@ private IReadOnlyList<IMember> EvaluateIndex(IndexExpression expr) {
}
} else {
var index = GetValueFromExpression(expr.Index);
indices.Add(index ?? UnknownType);
// Don't count null indexes as arguments
if (index != null) {
indices.Add(index);
}
}
return indices;
}
Expand Down Expand Up @@ -132,7 +156,7 @@ private IMember CreateClassInstance(PythonClassType cls, IReadOnlyList<IMember>

var argSet = initOverload != null
? new ArgumentSet(initFunc, 0, null, callExpr, this)
: new ArgumentSet(constructorArguments);
: new ArgumentSet(constructorArguments, callExpr, this);

argSet.Evaluate();
var specificType = cls.CreateSpecificType(argSet);
Expand Down Expand Up @@ -194,7 +218,7 @@ private static IReadOnlyList<IPythonType> GetSpecificTypeFromArgumentValue(objec
var itemType = iter.GetIterator().Next.GetPythonType();
if (!itemType.IsUnknown()) {
specificTypes.Add(itemType);
} else if(argumentValue is IPythonInstance inst) {
} else if (argumentValue is IPythonInstance inst) {
specificTypes.Add(inst.GetPythonType());
}
break;
Expand Down
Loading