/// <summary> /// Locates and opens existing scope for a node or creates a new scope /// as a child of the specified scope. Scope is pushed on the stack /// and will be removed when returned the disposable is disposed. /// </summary> public IDisposable OpenScope(IPythonModule module, ScopeStatement node, out Scope outerScope) { outerScope = null; if (node == null) { return(Disposable.Empty); } // During analysis module global scope has not changed yet since it updates // When the analysis completed. Therefore if module is the one we are // analyzing, use scope from the evaluator rather than from the module. var gs = Module.Equals(module) || module == null ? GlobalScope : module.GlobalScope as Scope; if (gs == null) { return(Disposable.Empty); } if (node.Parent != null) { if (!_scopeLookupCache.TryGetValue(node.Parent, out outerScope)) { outerScope = gs .TraverseDepthFirst(s => s.Children.OfType <Scope>()) .FirstOrDefault(s => s.Node == node.Parent); _scopeLookupCache[node.Parent] = outerScope; } } outerScope = outerScope ?? gs; if (outerScope != null) { Scope scope; if (node is PythonAst) { // node points to global scope, it is not a function or a class. scope = gs; } else { scope = outerScope.Children.OfType <Scope>().FirstOrDefault(s => s.Node == node); if (scope == null) { scope = new Scope(node, outerScope, Module); outerScope.AddChildScope(scope); _scopeLookupCache[node] = scope; } } _openScopes.Push(scope); CurrentScope = scope; } return(new ScopeTracker(this)); }
/// <summary> /// Locates and opens existing scope for a node or creates a new scope /// as a child of the specified scope. Scope is pushed on the stack /// and will be removed when returned the disposable is disposed. /// </summary> public IDisposable OpenScope(ScopeStatement node, out Scope fromScope) { fromScope = null; if (node.Parent != null) { fromScope = (GlobalScope as Scope) .TraverseBreadthFirst(s => s.Children.OfType <Scope>()) .FirstOrDefault(s => s.Node == node.Parent); } fromScope = fromScope ?? GlobalScope; var scope = fromScope.Children.OfType <Scope>().FirstOrDefault(s => s.Node == node); if (scope == null) { scope = new Scope(node, fromScope, true); fromScope.AddChildScope(scope); } _openScopes.Push(scope); CurrentScope = scope; return(new ScopeTracker(this)); }