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

Commit 70ac304

Browse files
author
Mikhail Arkhipov
authored
AST analyzer and assemblies split (microsoft#465)
* Types hierarchy cleanup * Test fixes, part I * Restore IPythonBoundFunction * Fix function instance types * More fixes * Fix overload handling * Fix properties * Fix type factory * Remove class built-in type * Simplify builtins, remove obsolete method * Fix typeshed merge * Allow declaring module to be null * Correct assertion * Simplify functions/methods * Fix stub merge tests * 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 * Fix list ctor argument unpacking
1 parent e534eae commit 70ac304

File tree

1,781 files changed

+93278
-6907
lines changed

Some content is hidden

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

1,781 files changed

+93278
-6907
lines changed

build/Common.Build.Core.settings

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,10 @@
1616
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
1717
<VSTarget Condition="$(VSTarget)=='' and '$(VisualStudioVersion)'=='16.0'">16.0</VSTarget>
1818
<VSTarget Condition="$(VSTarget)=='' and '$(VisualStudioVersion)'=='15.0'">15.0</VSTarget>
19-
<VSTarget Condition="$(VSTarget)=='' and '$(VisualStudioVersion)'=='14.0'">14.0</VSTarget>
20-
<VSTarget Condition="$(VSTarget)=='' and '$(VisualStudioVersion)'=='12.0'">12.0</VSTarget>
21-
<VSTarget Condition="$(VSTarget)=='' and '$(VisualStudioVersion)'=='11.0'">11.0</VSTarget>
22-
<VSTarget Condition="$(VSTarget)==''">10.0</VSTarget>
23-
19+
2420
<VSTargetName Condition="'$(VSTarget)' == '16.0'">2019</VSTargetName>
2521
<VSTargetName Condition="'$(VSTarget)' == '15.0'">2017</VSTargetName>
26-
<VSTargetName Condition="'$(VSTarget)' == '14.0'">2015</VSTargetName>
27-
<VSTargetName Condition="'$(VSTarget)' == '12.0'">2013</VSTargetName>
28-
<VSTargetName Condition="'$(VSTarget)' == '11.0'">2012</VSTargetName>
29-
<VSTargetName Condition="'$(VSTarget)' == '10.0'">2010</VSTargetName>
30-
22+
3123
<BuildNumber Condition="'$(BuildNumber)' == ''">$(BUILD_BUILDNUMBER)</BuildNumber>
3224
<BuildNumber Condition="'$(BuildNumber)' == ''">1000.00</BuildNumber>
3325
<!--
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
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.Linq;
18+
using System.Threading;
19+
using System.Threading.Tasks;
20+
using Microsoft.Python.Analysis.Analyzer.Evaluation;
21+
using Microsoft.Python.Analysis.Analyzer.Handlers;
22+
using Microsoft.Python.Analysis.Analyzer.Symbols;
23+
using Microsoft.Python.Analysis.Types;
24+
using Microsoft.Python.Core;
25+
using Microsoft.Python.Parsing.Ast;
26+
27+
namespace Microsoft.Python.Analysis.Analyzer {
28+
/// <summary>
29+
/// Base class with common functionality to module and function analysis walkers.
30+
/// </summary>
31+
internal abstract class AnalysisWalker : PythonWalkerAsync {
32+
protected ImportHandler ImportHandler { get; }
33+
protected FromImportHandler FromImportHandler { get; }
34+
protected LoopHandler LoopHandler { get; }
35+
protected ConditionalHandler ConditionalHandler { get; }
36+
protected AssignmentHandler AssignmentHandler { get; }
37+
protected WithHandler WithHandler { get; }
38+
protected TryExceptHandler TryExceptHandler { get; }
39+
protected NonLocalHandler NonLocalHandler { get; }
40+
41+
public ExpressionEval Eval { get; }
42+
public IPythonModule Module => Eval.Module;
43+
public IPythonInterpreter Interpreter => Eval.Interpreter;
44+
public PythonAst Ast => Eval.Ast;
45+
protected ModuleSymbolTable SymbolTable => Eval.SymbolTable;
46+
47+
protected AnalysisWalker(ExpressionEval eval) {
48+
Eval = eval;
49+
ImportHandler = new ImportHandler(this);
50+
FromImportHandler = new FromImportHandler(this);
51+
AssignmentHandler = new AssignmentHandler(this);
52+
LoopHandler = new LoopHandler(this);
53+
ConditionalHandler = new ConditionalHandler(this);
54+
WithHandler = new WithHandler(this);
55+
TryExceptHandler = new TryExceptHandler(this);
56+
NonLocalHandler = new NonLocalHandler(this);
57+
}
58+
59+
protected AnalysisWalker(IServiceContainer services, IPythonModule module, PythonAst ast)
60+
: this(new ExpressionEval(services, module, ast)) {
61+
}
62+
63+
#region AST walker overrides
64+
public override async Task<bool> WalkAsync(AssignmentStatement node, CancellationToken cancellationToken = default) {
65+
await AssignmentHandler.HandleAssignmentAsync(node, cancellationToken);
66+
return await base.WalkAsync(node, cancellationToken);
67+
}
68+
69+
public override async Task<bool> WalkAsync(ExpressionStatement node, CancellationToken cancellationToken = default) {
70+
await AssignmentHandler.HandleAnnotatedExpressionAsync(node.Expression as ExpressionWithAnnotation, null, cancellationToken);
71+
return false;
72+
}
73+
74+
public override async Task<bool> WalkAsync(ForStatement node, CancellationToken cancellationToken = default) {
75+
await LoopHandler.HandleForAsync(node, cancellationToken);
76+
return await base.WalkAsync(node, cancellationToken);
77+
}
78+
79+
public override Task<bool> WalkAsync(FromImportStatement node, CancellationToken cancellationToken = default)
80+
=> FromImportHandler.HandleFromImportAsync(node, cancellationToken);
81+
82+
public override Task<bool> WalkAsync(GlobalStatement node, CancellationToken cancellationToken = default)
83+
=> NonLocalHandler.HandleGlobalAsync(node, cancellationToken);
84+
85+
public override Task<bool> WalkAsync(IfStatement node, CancellationToken cancellationToken = default)
86+
=> ConditionalHandler.HandleIfAsync(node, cancellationToken);
87+
88+
public override Task<bool> WalkAsync(ImportStatement node, CancellationToken cancellationToken = default)
89+
=> ImportHandler.HandleImportAsync(node, cancellationToken);
90+
91+
public override Task<bool> WalkAsync(NonlocalStatement node, CancellationToken cancellationToken = default)
92+
=> NonLocalHandler.HandleNonLocalAsync(node, cancellationToken);
93+
94+
public override async Task<bool> WalkAsync(TryStatement node, CancellationToken cancellationToken = default) {
95+
await TryExceptHandler.HandleTryExceptAsync(node, cancellationToken);
96+
return await base.WalkAsync(node, cancellationToken);
97+
}
98+
99+
public override async Task<bool> WalkAsync(WhileStatement node, CancellationToken cancellationToken = default) {
100+
await LoopHandler.HandleWhileAsync(node, cancellationToken);
101+
return await base.WalkAsync(node, cancellationToken);
102+
}
103+
104+
public override async Task<bool> WalkAsync(WithStatement node, CancellationToken cancellationToken = default) {
105+
await WithHandler.HandleWithAsync(node, cancellationToken);
106+
return await base.WalkAsync(node, cancellationToken);
107+
}
108+
#endregion
109+
110+
protected T[] GetStatements<T>(ScopeStatement s)
111+
=> (s.Body as SuiteStatement)?.Statements.OfType<T>().ToArray() ?? Array.Empty<T>();
112+
}
113+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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+
namespace Microsoft.Python.Analysis.Analyzer {
17+
/// <summary>
18+
/// Represents document that can be analyzed asynchronously.
19+
/// </summary>
20+
internal interface IAnalyzable {
21+
/// <summary>
22+
/// Expected version of the analysis when asynchronous operations complete.
23+
/// Typically every change to the document or documents that depend on it
24+
/// increment the expected version. At the end of the analysis if the expected
25+
/// version is still the same, the analysis is applied to the document and
26+
/// becomes available to consumers.
27+
/// </summary>
28+
int ExpectedAnalysisVersion { get; }
29+
30+
/// <summary>
31+
/// Notifies document that analysis is now pending. Typically document increments
32+
/// the expected analysis version. The method can be called repeatedly without
33+
/// calling `CompleteAnalysis` first. The method is invoked for every dependency
34+
/// in the chain to ensure that objects know that their dependencies have been
35+
/// modified and the current analysis is no longer up to date.
36+
/// </summary>
37+
void NotifyAnalysisPending();
38+
39+
/// <summary>
40+
/// Notifies document that its analysis is now complete.
41+
/// </summary>
42+
/// <param name="analysis">Document analysis</param>
43+
/// (version of the snapshot in the beginning of analysis).</param>
44+
/// <returns>True if analysis was accepted, false if is is out of date.</returns>
45+
bool NotifyAnalysisComplete(IDocumentAnalysis analysis);
46+
}
47+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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.Threading;
17+
using System.Threading.Tasks;
18+
using Microsoft.Python.Analysis.Documents;
19+
20+
namespace Microsoft.Python.Analysis.Analyzer {
21+
public interface IPythonAnalyzer {
22+
/// <summary>
23+
/// Analyze single document.
24+
/// </summary>
25+
Task AnalyzeDocumentAsync(IDocument document, CancellationToken cancellationToken);
26+
27+
/// <summary>
28+
/// Analyze document with dependents.
29+
/// </summary>
30+
Task AnalyzeDocumentDependencyChainAsync(IDocument document, CancellationToken cancellationToken);
31+
}
32+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
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.Collections.Generic;
17+
using System.Linq;
18+
using Microsoft.Python.Analysis.Diagnostics;
19+
using Microsoft.Python.Analysis.Types;
20+
using Microsoft.Python.Analysis.Documents;
21+
using Microsoft.Python.Analysis.Values;
22+
using Microsoft.Python.Core;
23+
using Microsoft.Python.Core.Diagnostics;
24+
using Microsoft.Python.Core.Text;
25+
using Microsoft.Python.Parsing.Ast;
26+
27+
namespace Microsoft.Python.Analysis.Analyzer {
28+
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) {
32+
Check.ArgumentNotNull(nameof(document), document);
33+
Check.ArgumentNotNull(nameof(globalScope), globalScope);
34+
Document = document;
35+
Version = version;
36+
GlobalScope = globalScope;
37+
Ast = ast;
38+
}
39+
40+
#region IDocumentAnalysis
41+
/// <summary>
42+
/// Analyzed document.
43+
/// </summary>
44+
public IDocument Document { get; }
45+
46+
/// <summary>
47+
/// Version of the analysis. Usually matches document version,
48+
/// but can be lower when document or its dependencies were
49+
/// updated since.
50+
/// </summary>
51+
public int Version { get; }
52+
53+
/// <summary>
54+
/// AST that was used in the analysis.
55+
/// </summary>
56+
public PythonAst Ast { get; }
57+
58+
/// <summary>
59+
/// Document/module global scope.
60+
/// </summary>
61+
public IGlobalScope GlobalScope { get; }
62+
63+
/// <summary>
64+
/// Module top-level members
65+
/// </summary>
66+
public IVariableCollection TopLevelVariables => GlobalScope.Variables;
67+
68+
/// <summary>
69+
/// All module members from all scopes.
70+
/// </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>();
78+
#endregion
79+
80+
private sealed class EmptyAnalysis : IDocumentAnalysis {
81+
public EmptyAnalysis(IDocument document = null) {
82+
Document = document;
83+
GlobalScope = new EmptyGlobalScope(document);
84+
}
85+
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>();
97+
}
98+
}
99+
}

0 commit comments

Comments
 (0)