-
Notifications
You must be signed in to change notification settings - Fork 133
Fix processing of forward references #304
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// Python Tools for Visual Studio | ||
// Copyright(c) Microsoft Corporation | ||
// All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the License); you may not use | ||
// this file except in compliance with the License. You may obtain a copy of the | ||
// License at http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS | ||
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY | ||
// IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, | ||
// MERCHANTABILITY OR NON-INFRINGEMENT. | ||
// | ||
// See the Apache Version 2.0 License for specific language governing | ||
// permissions and limitations under the License. | ||
|
||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Microsoft.PythonTools.Analysis.Infrastructure; | ||
using Microsoft.PythonTools.Parsing.Ast; | ||
|
||
namespace Microsoft.PythonTools.Interpreter.Ast { | ||
/// <summary> | ||
/// Represents set of function body walkers. Functions are walked after | ||
/// all classes are collected. If function or property return type is unknown, | ||
/// it can be walked, and so on recursively, until return type is determined | ||
/// or there is nothing left to walk. | ||
/// </summary> | ||
class AstAnalysisFunctionWalkerSet { | ||
private readonly Dictionary<FunctionDefinition, AstAnalysisFunctionWalker> _functionWalkers | ||
= new Dictionary<FunctionDefinition, AstAnalysisFunctionWalker>(); | ||
|
||
public void Add(AstAnalysisFunctionWalker walker) | ||
=> _functionWalkers[walker.Target] = walker; | ||
|
||
public void ProcessSet() { | ||
// Do not use foreach since walker list is dynamically modified and walkers are removed | ||
// after processing. Handle __init__ and __new__ first so class variables are initialized. | ||
var constructors = _functionWalkers | ||
.Where(kvp => kvp.Key.Name == "__init__" || kvp.Key.Name == "__new__") | ||
.Select(c => c.Value) | ||
.ExcludeDefault() | ||
.ToArray(); | ||
|
||
foreach (var ctor in constructors) { | ||
ProcessWalker(ctor); | ||
} | ||
|
||
while (_functionWalkers.Count > 0) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. var walkers = _functionWalkers.Values.ToArray();
_functionWalkers.Clear();
foreach (var walker in walkers) {
walker.Walk();
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, the point is in keeping walkers in the array for recursive processing. We don't walk in order. Ex A calls B which calls D which calls C. We take A which then, when it needs return type of B will call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So if walker is removed b/c it was called in some chain, we don't want to walk it again so that's why there is no |
||
var walker = _functionWalkers.First().Value; | ||
ProcessWalker(walker); | ||
} | ||
} | ||
|
||
public void ProcessFunction(FunctionDefinition fn) { | ||
if (_functionWalkers.TryGetValue(fn, out var w)) { | ||
AlexanderSher marked this conversation as resolved.
Show resolved
Hide resolved
|
||
ProcessWalker(w); | ||
} | ||
} | ||
|
||
private void ProcessWalker(AstAnalysisFunctionWalker walker) { | ||
// Remove walker before processing as to prevent reentrancy. | ||
_functionWalkers.Remove(walker.Target); | ||
var z = walker.Target.Name == "day"; | ||
walker.Walk(); | ||
} | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.