internal override PythonVariable BindReference(PythonNameBinder binder, string name) { PythonVariable variable; // First try variables local to this scope if (TryGetVariable(name, out variable) && variable.Kind != VariableKind.Nonlocal) { if (variable.Kind == VariableKind.Global) { AddReferencedGlobal(name); } return(variable); } // Try to bind in outer scopes for (ScopeStatement parent = Parent; parent != null; parent = parent.Parent) { if (parent.TryBindOuter(this, name, true, out variable)) { return(variable); } } return(null); }
internal override PythonVariable BindReference(PythonNameBinder binder, string name) { PythonVariable variable; // Python semantics: The variables bound local in the class // scope are accessed by name - the dictionary behavior of classes if (TryGetVariable(name, out variable)) { // TODO: This results in doing a dictionary lookup to get/set the local, // when it should probably be an uninitialized check / global lookup for gets // and a direct set if (variable.Kind == VariableKind.Global) { AddReferencedGlobal(name); } else if (variable.Kind == VariableKind.Local) { return(null); } return(variable); } // Try to bind in outer scopes, if we have an unqualified exec we need to leave the // variables as free for the same reason that locals are accessed by name. for (ScopeStatement parent = Parent; parent != null; parent = parent.Parent) { if (parent.TryBindOuter(this, name, true, out variable)) { return(variable); } } return(null); }
internal virtual void FinishBind(PythonNameBinder binder) { List <ClosureInfo> closureVariables = null; if (_nonLocalVars != null) { foreach (var variableName in _nonLocalVars) { bool bound = false; for (ScopeStatement parent = Parent; parent != null; parent = parent.Parent) { PythonVariable variable; if (parent.TryBindOuter(this, variableName.Name, false, out variable)) { bound = !variable.IsGlobal; break; } } if (!bound) { binder.ReportSyntaxError(String.Format("no binding for nonlocal '{0}' found", variableName.Name), variableName); } } } if (FreeVariables != null && FreeVariables.Count > 0) { closureVariables = new List <ClosureInfo>(); foreach (var variable in FreeVariables) { closureVariables.Add(new ClosureInfo(variable, !(this is ClassDefinition))); } } if (Variables != null && Variables.Count > 0) { if (closureVariables == null) { closureVariables = new List <ClosureInfo>(); } foreach (PythonVariable variable in Variables.Values) { if (!HasClosureVariable(closureVariables, variable) && !variable.IsGlobal && (variable.AccessedInNestedScope || ExposesLocalVariable(variable))) { closureVariables.Add(new ClosureInfo(variable, true)); } if (variable.Kind == VariableKind.Local) { Debug.Assert(variable.Scope == this); } } } if (closureVariables != null) { _closureVariables = closureVariables.ToArray(); } // no longer needed _references = null; }