Skip to content
This repository was archived by the owner on Nov 4, 2024. It is now read-only.

Commit ad10d69

Browse files
author
Mikhail Arkhipov
authored
Language server using new analysis (microsoft#546)
* Fix tests * Baselines * Null ref * Build break * Overrides signatures * Fix typeinfo tests * PR feedback * Infra to separate assembly * Parser to own assembly * Parser tests to own assembly * Unify to IndexSpan * Better handle overloads * Reorg, part I * Part II * Part III * Part 4 * Part 5 * Build breaks * Baselines * PR fix * Merge build issues * Part 6 * Part 7 * Buildable * PR feedback * Merge conflict * Fix microsoft#446 * Fix microsoft#446 * Part 8 * Part 9 * Buildable * Part 10 * Part 11 * Part 12 * Buildable * Part 14 * First passing test * Simplify configuration * Style * Fix test and move code to folders * Builtins import * Fluents * Add search path * Import analysis, part I * Simplify builtins handling * Remove IMember * Handle import specific * More tests * Add typeshed * Renames * Make sure lazy modules are loaded * Renames * Move/rename * Rework importing * Derivation rework * Part 2 * Part 3 * Buildable * Module members * Async walk * Imports test pass * Remove lazy types * Fix from import * Stubs * Double overloads * Fix datetime test * Couple more tests + fluents * Few more tests * Additionl test + union type * Built-in scrape tests * Full stdlib scrape test * Complete async AST walker * Conditional defines test + variable loc cleanup * More stub tests Fix stub loading for packages (port from DDG) Split walker into multiple files * Add some (broken mostly) tests from DDG * Move document tests * Function arg eval, part I * Instance/factory * Builds * Test fixes * Fix static and instance call eval * More tests * More ported tests * Specialize builtin functions * Make walkers common and handle nested functions * Moar tests * Parser fixes + more tests * Handle negative numbers * Fix null ref * Basic list support * Few more list tests * Basic iterators * Support __iter__ * Iterators * Fix couple of tests * Add decorator test * Generics, part I * Generics, part 2 * Generics, part 3 * Basic TypeVar test * Typings, part 4 * Fix test * Generics, part 6 * Generics, part 7 * More tests (failing) * Forward ref fixes * Reorg * Improve symbol resolution + test fixes * Test fixes * Dictionary, part I * Part 11 * Fix test * Tests * Tests * More dict work * List ctor * Skip some tests for now * Fix iterators * Tuple slicing * Polish type comparo in return types * Add Mapping and tests * Add Iterable * Fix typo * Add Iterator[T] + test * Simplify typing types * Class reduction * Fix tests * Test fix * Handle 'with' statement * Handle try-except * Class method inheritance + NewType * Container types * Containers test * Tests * Handle generic type alias * Named tuple * Global/non-local * Handle tuples in for Handle custom iterators * Basic generator * Any/AnyStr * Test fixes * Type/Optional/etc handling * Proper doc population * Tests + range * Argument match * Basic argset and diagnostics * Argset tests * Exclude WIP * Exclude WIP * Arg eval * Arg match, part 2 * Tests and generic arg comparisons * Function eval with arguments * Baselines * Fix test * Undo AST formatting change and update baseline * LS cleanup 1 * Fix list ctor argument unpacking * Cleanup 2 * Builds * Partial completions * Partial * Partial * Simple test * Tests * Basic startup * Clean up a bit * Remove debug code * Port formatter tests * Fix tokenizer crash * Async fixes * Hover * Basic hover * Adjust expression options * Basic signature help * Fix class/instance * Update test * Fix builtin creation exception * Fix tests * Actually provide declared module * Completion test (partial) * Undo * Fix null await Fix override completions + test * Exports filtering Prevent augmenting imported types * Filter variables & exports * Ported tests * Test fixes * More ported tests * Fix exception completions * Import completions * Scope completions * With completions * Test fixes * WIP * Test fix * Better arg match * Temp disable WIP * First cut * Fix type leak * WIP * Remove ConfigureAwait and handle canceled and failed in the analysis notifications * WIP * Generic class base * Generic forward reference resolution * Suppress completion in strings + test * Prevent recursion on generic resolution Better match arguments * Handle call expression in generics * Relax condition as it happens in tensorflow * Fix typeshed version search Make writing cached modules async Fix module doc fetching * Hover tests * Fix prom import hover * Hover tests * Synchronize test cache writing * First cut * Test * Fixes * Add tests for os.path Null ref fix * Fix cache check * Improve resolution of builtins and typing in stubs * Merge tests * Add ntst for requests * Handle typeshed better * Fix custom stub handling * Better sync * Move files * Fix parameter locations * Hover improvement * PEP hints * One more test for PEP hints * Better handle hover over import as * Text based generic constraints * Handle with better with generic stubs * Undo debug * Handle non-binary open() Temporary fix 'with' handler since we haven't specialized IO/TextIO/BinaryIO yet.
1 parent 70ac304 commit ad10d69

File tree

213 files changed

+8832
-6302
lines changed

Some content is hidden

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

213 files changed

+8832
-6302
lines changed

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ namespace Microsoft.Python.Analysis.Analyzer {
3030
/// </summary>
3131
internal abstract class AnalysisWalker : PythonWalkerAsync {
3232
protected ImportHandler ImportHandler { get; }
33-
protected FromImportHandler FromImportHandler { get; }
3433
protected LoopHandler LoopHandler { get; }
3534
protected ConditionalHandler ConditionalHandler { get; }
3635
protected AssignmentHandler AssignmentHandler { get; }
@@ -47,7 +46,6 @@ internal abstract class AnalysisWalker : PythonWalkerAsync {
4746
protected AnalysisWalker(ExpressionEval eval) {
4847
Eval = eval;
4948
ImportHandler = new ImportHandler(this);
50-
FromImportHandler = new FromImportHandler(this);
5149
AssignmentHandler = new AssignmentHandler(this);
5250
LoopHandler = new LoopHandler(this);
5351
ConditionalHandler = new ConditionalHandler(this);
@@ -77,7 +75,7 @@ public override async Task<bool> WalkAsync(ForStatement node, CancellationToken
7775
}
7876

7977
public override Task<bool> WalkAsync(FromImportStatement node, CancellationToken cancellationToken = default)
80-
=> FromImportHandler.HandleFromImportAsync(node, cancellationToken);
78+
=> ImportHandler.HandleFromImportAsync(node, cancellationToken);
8179

8280
public override Task<bool> WalkAsync(GlobalStatement node, CancellationToken cancellationToken = default)
8381
=> NonLocalHandler.HandleGlobalAsync(node, cancellationToken);

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
// See the Apache Version 2.0 License for specific language governing
1414
// permissions and limitations under the License.
1515

16+
using System;
17+
1618
namespace Microsoft.Python.Analysis.Analyzer {
1719
/// <summary>
1820
/// Represents document that can be analyzed asynchronously.
@@ -40,8 +42,17 @@ internal interface IAnalyzable {
4042
/// Notifies document that its analysis is now complete.
4143
/// </summary>
4244
/// <param name="analysis">Document analysis</param>
43-
/// (version of the snapshot in the beginning of analysis).</param>
4445
/// <returns>True if analysis was accepted, false if is is out of date.</returns>
4546
bool NotifyAnalysisComplete(IDocumentAnalysis analysis);
47+
48+
/// <summary>
49+
/// Notifies module that analysis has been canceled.
50+
/// </summary>
51+
void NotifyAnalysisCanceled();
52+
53+
/// <summary>
54+
/// Notifies module that analysis has thrown an exception.
55+
/// </summary>
56+
void NotifyAnalysisFailed(Exception ex);
4657
}
4758
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright(c) Microsoft Corporation
2+
// All rights reserved.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the License); you may not use
5+
// this file except in compliance with the License. You may obtain a copy of the
6+
// License at http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
9+
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY
10+
// IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
11+
// MERCHANTABILITY OR NON-INFRINGEMENT.
12+
//
13+
// See the Apache Version 2.0 License for specific language governing
14+
// permissions and limitations under the License.
15+
16+
using System;
17+
using System.Threading;
18+
using System.Threading.Tasks;
19+
using Microsoft.Python.Analysis.Types;
20+
using Microsoft.Python.Analysis.Values;
21+
using Microsoft.Python.Core;
22+
using Microsoft.Python.Parsing.Ast;
23+
24+
namespace Microsoft.Python.Analysis.Analyzer {
25+
public interface IExpressionEvaluator {
26+
/// <summary>
27+
/// Opens existing scope for a node. The scope is pushed
28+
/// on the stack and will be removed when the returned
29+
/// disposable is disposed.
30+
/// </summary>
31+
IDisposable OpenScope(IScope scope);
32+
33+
/// <summary>
34+
/// Opens existing scope for a node. The scope is pushed
35+
/// on the stack and will be removed when the returned
36+
/// disposable is disposed.
37+
/// </summary>
38+
IDisposable OpenScope(IPythonModule module, ScopeStatement scope);
39+
40+
/// <summary>
41+
/// Currently opened (deep-most) scope.
42+
/// </summary>
43+
IScope CurrentScope { get; }
44+
45+
/// <summary>
46+
/// Module global scope.
47+
/// </summary>
48+
IGlobalScope GlobalScope { get; }
49+
50+
/// <summary>
51+
/// Determines node location in the module source code.
52+
/// </summary>
53+
LocationInfo GetLocation(Node node);
54+
55+
/// <summary>
56+
/// Evaluates expression in the currently open scope.
57+
/// </summary>
58+
Task<IMember> GetValueFromExpressionAsync(Expression expr, CancellationToken cancellationToken = default);
59+
60+
IMember LookupNameInScopes(string name, out IScope scope);
61+
62+
IPythonType GetTypeFromPepHint(Node node);
63+
IPythonType GetTypeFromString(string typeString);
64+
65+
PythonAst Ast { get; }
66+
IPythonModule Module { get; }
67+
IPythonInterpreter Interpreter { get; }
68+
IServiceContainer Services { get; }
69+
}
70+
}

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

Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,31 @@
1313
// See the Apache Version 2.0 License for specific language governing
1414
// permissions and limitations under the License.
1515

16+
using System;
1617
using System.Collections.Generic;
18+
using System.IO;
1719
using System.Linq;
20+
using Microsoft.Python.Analysis.Analyzer.Evaluation;
21+
using Microsoft.Python.Analysis.Analyzer.Expressions;
1822
using Microsoft.Python.Analysis.Diagnostics;
1923
using Microsoft.Python.Analysis.Types;
2024
using Microsoft.Python.Analysis.Documents;
2125
using Microsoft.Python.Analysis.Values;
2226
using Microsoft.Python.Core;
2327
using Microsoft.Python.Core.Diagnostics;
2428
using Microsoft.Python.Core.Text;
29+
using Microsoft.Python.Parsing;
2530
using Microsoft.Python.Parsing.Ast;
2631

2732
namespace Microsoft.Python.Analysis.Analyzer {
2833
internal sealed class DocumentAnalysis : IDocumentAnalysis {
29-
public static readonly IDocumentAnalysis Empty = new EmptyAnalysis();
30-
31-
public DocumentAnalysis(IDocument document, int version, IGlobalScope globalScope, PythonAst ast) {
34+
public DocumentAnalysis(IDocument document, int version, IGlobalScope globalScope, IExpressionEvaluator eval) {
3235
Check.ArgumentNotNull(nameof(document), document);
3336
Check.ArgumentNotNull(nameof(globalScope), globalScope);
3437
Document = document;
3538
Version = version;
3639
GlobalScope = globalScope;
37-
Ast = ast;
40+
ExpressionEvaluator = eval;
3841
}
3942

4043
#region IDocumentAnalysis
@@ -53,47 +56,37 @@ public DocumentAnalysis(IDocument document, int version, IGlobalScope globalScop
5356
/// <summary>
5457
/// AST that was used in the analysis.
5558
/// </summary>
56-
public PythonAst Ast { get; }
59+
public PythonAst Ast => ExpressionEvaluator.Ast;
5760

5861
/// <summary>
5962
/// Document/module global scope.
6063
/// </summary>
6164
public IGlobalScope GlobalScope { get; }
6265

6366
/// <summary>
64-
/// Module top-level members
65-
/// </summary>
66-
public IVariableCollection TopLevelVariables => GlobalScope.Variables;
67-
68-
/// <summary>
69-
/// All module members from all scopes.
67+
/// Expression evaluator used in the analysis.
7068
/// </summary>
71-
public IEnumerable<IVariable> AllVariables
72-
=> (GlobalScope as IScope).TraverseBreadthFirst(s => s.Children).SelectMany(s => s.Variables);
73-
74-
public IEnumerable<IPythonType> GetAllAvailableItems(SourceLocation location) => Enumerable.Empty<IPythonType>();
75-
public IEnumerable<IPythonType> GetMembers(SourceLocation location) => Enumerable.Empty<IPythonType>();
76-
public IEnumerable<IPythonFunctionOverload> GetSignatures(SourceLocation location) => Enumerable.Empty<IPythonFunctionOverload>();
77-
public IEnumerable<IPythonType> GetValues(SourceLocation location) => Enumerable.Empty<IPythonType>();
69+
public IExpressionEvaluator ExpressionEvaluator { get; }
7870
#endregion
71+
}
7972

80-
private sealed class EmptyAnalysis : IDocumentAnalysis {
81-
public EmptyAnalysis(IDocument document = null) {
82-
Document = document;
83-
GlobalScope = new EmptyGlobalScope(document);
84-
}
73+
public sealed class EmptyAnalysis : IDocumentAnalysis {
74+
private static PythonAst _emptyAst;
8575

86-
public IDocument Document { get; }
87-
public int Version { get; } = -1;
88-
public IGlobalScope GlobalScope { get; }
89-
public PythonAst Ast => null;
90-
public IEnumerable<IPythonType> GetAllAvailableItems(SourceLocation location) => Enumerable.Empty<IPythonType>();
91-
public IEnumerable<DiagnosticsEntry> Diagnostics => Enumerable.Empty<DiagnosticsEntry>();
92-
public IVariableCollection TopLevelVariables => VariableCollection.Empty;
93-
public IEnumerable<IVariable> AllVariables => Enumerable.Empty<IVariable>();
94-
public IEnumerable<IPythonType> GetMembers(SourceLocation location) => Enumerable.Empty<IPythonType>();
95-
public IEnumerable<IPythonFunctionOverload> GetSignatures(SourceLocation location) => Enumerable.Empty<IPythonFunctionOverload>();
96-
public IEnumerable<IPythonType> GetValues(SourceLocation location) => Enumerable.Empty<IPythonType>();
76+
public EmptyAnalysis(IServiceContainer services, IDocument document) {
77+
Document = document ?? throw new ArgumentNullException(nameof(document));
78+
GlobalScope = new EmptyGlobalScope(document);
79+
80+
_emptyAst = _emptyAst ?? (_emptyAst = Parser.CreateParser(new StringReader(string.Empty), PythonLanguageVersion.None).ParseFile());
81+
ExpressionEvaluator = new ExpressionEval(services, document, Ast);
9782
}
83+
84+
public IDocument Document { get; }
85+
public int Version { get; } = -1;
86+
public IGlobalScope GlobalScope { get; }
87+
public PythonAst Ast => _emptyAst;
88+
public IExpressionEvaluator ExpressionEvaluator { get; }
89+
public IEnumerable<DiagnosticsEntry> Diagnostics => Enumerable.Empty<DiagnosticsEntry>();
9890
}
91+
9992
}

0 commit comments

Comments
 (0)