internal override JVariable BindReference(JNameBinder binder, string name) { JVariable 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; }
private void Verify(JNameBinder binder) { if (ContainsImportStar && IsClosure) { binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "import * is not allowed in function '{0}' because it is a nested function", Name), this); } if (ContainsImportStar && Parent is FunctionDefinition) { binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "import * is not allowed in function '{0}' because it is a nested function", Name), this); } if (ContainsImportStar && ContainsNestedFreeVariables) { binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "import * is not allowed in function '{0}' because it contains a nested function with free variables", Name), this); } if (ContainsUnqualifiedExec && ContainsNestedFreeVariables) { binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "unqualified exec is not allowed in function '{0}' because it contains a nested function with free variables", Name), this); } if (ContainsUnqualifiedExec && IsClosure) { binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "unqualified exec is not allowed in function '{0}' because it is a nested function", Name), this); } }
internal override JVariable BindReference(JNameBinder binder, string name) { JVariable variable; // J 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 override void Bind(JNameBinder binder) { base.Bind(binder); Verify(binder); }
internal virtual void FinishBind(JNameBinder 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) { JVariable 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) { var parentClosure = Parent._closureVariables; Debug.Assert(parentClosure != null); closureVariables.Add(new ClosureInfo(variable, !(this is ClassDefinition))); } } if (Variables != null && Variables.Count > 0) { if (closureVariables == null) { closureVariables = new List<ClosureInfo>(); } foreach (JVariable 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; }
internal abstract JVariable BindReference(JNameBinder binder, string name);
internal virtual void Bind(JNameBinder binder) { if (_references != null) { foreach (var refList in _references.Values) { foreach (var reference in refList) { JVariable variable; reference.Variable = variable = BindReference(binder, reference.Name); // Accessing outer scope variable which is being deleted? if (variable != null) { if (variable.Deleted && variable.Scope != this && !variable.Scope.IsGlobal && binder.LanguageVersion < JLanguageVersion.V32) { // report syntax error binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "can not delete variable '{0}' referenced in nested scope", reference.Name ), this); } } } } } }
internal override void FinishBind(JNameBinder binder) { }
internal override JVariable BindReference(JNameBinder binder, string name) { return EnsureVariable(name); }