Ejemplo n.º 1
0
 public bool MustCaptureVariable(IKnownVariable variable)
 {
     if (CurrentAnonymousMethod == null)
     {
         return(false);
     }
     return(variable.Scope.TopLevel != CurrentScope.TopLevel);
 }
Ejemplo n.º 2
0
        internal void AddKnownVariable(string name, IKnownVariable variable)
        {
            if (_knownVariables == null)
            {
                _knownVariables = new Dictionary <string, IKnownVariable>();
            }

            if (!_knownVariables.ContainsKey(name))
            {
                _knownVariables[name] = variable;
            }

            if (Parent != null)
            {
                Parent.Explicit.AddKnownVariable(name, variable);
            }
        }
Ejemplo n.º 3
0
		// <summary>
		//   Marks a variable with name @name as being used in this or a child block.
		//   If a variable name has been used in a child block, it's illegal to
		//   declare a variable with the same name in the current block.
		// </summary>
		internal void AddKnownVariable (string name, IKnownVariable info)
		{
			if (known_variables == null)
				known_variables = new Dictionary<string, IKnownVariable> ();

			known_variables [name] = info;

			if (Parent != null)
				Parent.Explicit.AddKnownVariable (name, info);
		}
Ejemplo n.º 4
0
        public bool CheckInvariantMeaningInBlock(string name, Expression e, SourceSpan span)
        {
            var            b   = this;
            IKnownVariable kvi = b.Explicit.GetKnownVariable(name);

            while (kvi == null)
            {
                b = b.Explicit.Parent;
                if (b == null)
                {
                    return(true);
                }
                kvi = b.Explicit.GetKnownVariable(name);
            }

            if (kvi.Scope == b)
            {
                return(true);
            }

            // Is kvi.Block nested inside 'b'
            if (b.Explicit != kvi.Scope.Explicit)
            //if (kvi.Scope.Explicit.IsDescendantOf(b.Explicit))
            {
                //
                // If a variable by the same name it defined in a nested block of this
                // block, we violate the invariant meaning in a block.
                //
                if (b == this)
                {
                    _compilerContext.Errors.Add(
                        _compilerContext.SourceUnit,
                        string.Format("'{0}' conflicts with a declaration in a child block.", name),
                        span,
                        135,
                        Severity.Error);
                    return(false);
                }

                //
                // It's ok if the definition is in a nested subblock of b, but not
                // nested inside this block -- a definition in a sibling block
                // should not affect us.
                //
                return(true);
            }

            //
            // Block 'b' and kvi.Block are the same textual block.
            // However, different variables are extant.
            //
            // Check if the variable is in scope in both blocks.  We use
            // an indirect check that depends on AddVariable doing its
            // part in maintaining the invariant-meaning-in-block property.
            //
            if (e is ParameterReference)
            {
                return(true);
            }

            if (this is TopLevelScope)
            {
                _compilerContext.Errors.Add(
                    _compilerContext.SourceUnit,
                    string.Format("A local variable '{0}' cannot be used before it is declared.", name),
                    span,
                    841,
                    Severity.Error);
                return(false);
            }

            //
            // Even though we detected the error when the name is used, we
            // treat it as if the variable declaration was in error.
            //
            OnAlreadyDeclaredError(kvi.Span, name, "parent or current");
            return(false);
        }