예제 #1
0
 public virtual object Visit(EraseStatement eraseStatement, object data)
 {
     Debug.Assert(eraseStatement != null);
     Debug.Assert(eraseStatement.Expressions != null);
     foreach (Expression e in eraseStatement.Expressions)
     {
         Debug.Assert(e != null);
         e.AcceptVisitor(this, data);
     }
     return(data);
 }
예제 #2
0
        public object VisitEraseStatement(EraseStatement eraseStatement, object data)
        {
            ArrayList statements = new ArrayList();

            foreach (Expression expr in eraseStatement.Expressions)
            {
                B.Expression e = ConvertExpression(expr);
                e = new B.BinaryExpression(B.BinaryOperatorType.Assign, e, new B.NullLiteralExpression());
                statements.Add(new B.ExpressionStatement(e));
            }
            return(statements);
        }
예제 #3
0
 public virtual T Visit(EraseStatement stmt) => Visit(stmt as Statement);
예제 #4
0
 public void VBNetEraseStatementTest()
 {
     EraseStatement eraseStatement = ParseUtil.ParseStatement <EraseStatement>("Erase a, b, c");
 }
예제 #5
0
 public virtual object VisitEraseStatement(EraseStatement eraseStatement, object data)
 {
     throw new global::System.NotImplementedException("EraseStatement");
 }
예제 #6
0
	void EmbeddedStatement(
#line  2755 "VBNET.ATG" 
out Statement statement) {

#line  2757 "VBNET.ATG" 
		Statement embeddedStatement = null;
		statement = null;
		Expression expr = null;
		string name = String.Empty;
		List<Expression> p = null;
		
		if (la.kind == 107) {
			lexer.NextToken();

#line  2763 "VBNET.ATG" 
			ExitType exitType = ExitType.None; 
			switch (la.kind) {
			case 195: {
				lexer.NextToken();

#line  2765 "VBNET.ATG" 
				exitType = ExitType.Sub; 
				break;
			}
			case 114: {
				lexer.NextToken();

#line  2767 "VBNET.ATG" 
				exitType = ExitType.Function; 
				break;
			}
			case 171: {
				lexer.NextToken();

#line  2769 "VBNET.ATG" 
				exitType = ExitType.Property; 
				break;
			}
			case 95: {
				lexer.NextToken();

#line  2771 "VBNET.ATG" 
				exitType = ExitType.Do; 
				break;
			}
			case 111: {
				lexer.NextToken();

#line  2773 "VBNET.ATG" 
				exitType = ExitType.For; 
				break;
			}
			case 203: {
				lexer.NextToken();

#line  2775 "VBNET.ATG" 
				exitType = ExitType.Try; 
				break;
			}
			case 216: {
				lexer.NextToken();

#line  2777 "VBNET.ATG" 
				exitType = ExitType.While; 
				break;
			}
			case 182: {
				lexer.NextToken();

#line  2779 "VBNET.ATG" 
				exitType = ExitType.Select; 
				break;
			}
			default: SynErr(273); break;
			}

#line  2781 "VBNET.ATG" 
			statement = new ExitStatement(exitType); 
		} else if (la.kind == 203) {
			TryStatement(
#line  2782 "VBNET.ATG" 
out statement);
		} else if (la.kind == 76) {
			lexer.NextToken();

#line  2783 "VBNET.ATG" 
			ContinueType continueType = ContinueType.None; 
			if (la.kind == 95 || la.kind == 111 || la.kind == 216) {
				if (la.kind == 95) {
					lexer.NextToken();

#line  2783 "VBNET.ATG" 
					continueType = ContinueType.Do; 
				} else if (la.kind == 111) {
					lexer.NextToken();

#line  2783 "VBNET.ATG" 
					continueType = ContinueType.For; 
				} else {
					lexer.NextToken();

#line  2783 "VBNET.ATG" 
					continueType = ContinueType.While; 
				}
			}

#line  2783 "VBNET.ATG" 
			statement = new ContinueStatement(continueType); 
		} else if (la.kind == 200) {
			lexer.NextToken();
			if (StartOf(29)) {
				Expr(
#line  2785 "VBNET.ATG" 
out expr);
			}

#line  2785 "VBNET.ATG" 
			statement = new ThrowStatement(expr); 
		} else if (la.kind == 180) {
			lexer.NextToken();
			if (StartOf(29)) {
				Expr(
#line  2787 "VBNET.ATG" 
out expr);
			}

#line  2787 "VBNET.ATG" 
			statement = new ReturnStatement(expr); 
		} else if (la.kind == 196) {
			lexer.NextToken();
			Expr(
#line  2789 "VBNET.ATG" 
out expr);
			EndOfStmt();
			Block(
#line  2789 "VBNET.ATG" 
out embeddedStatement);
			Expect(100);
			Expect(196);

#line  2790 "VBNET.ATG" 
			statement = new LockStatement(expr, embeddedStatement); 
		} else if (la.kind == 174) {
			lexer.NextToken();
			Identifier();

#line  2792 "VBNET.ATG" 
			name = t.val; 
			if (la.kind == 25) {
				lexer.NextToken();
				if (StartOf(37)) {
					ArgumentList(
#line  2793 "VBNET.ATG" 
out p);
				}
				Expect(26);
			}

#line  2795 "VBNET.ATG" 
			statement = new RaiseEventStatement(name, p);
			
		} else if (la.kind == 218) {
			WithStatement(
#line  2798 "VBNET.ATG" 
out statement);
		} else if (la.kind == 43) {
			lexer.NextToken();

#line  2800 "VBNET.ATG" 
			Expression handlerExpr = null; 
			Expr(
#line  2801 "VBNET.ATG" 
out expr);
			Expect(12);
			Expr(
#line  2801 "VBNET.ATG" 
out handlerExpr);

#line  2803 "VBNET.ATG" 
			statement = new AddHandlerStatement(expr, handlerExpr);
			
		} else if (la.kind == 178) {
			lexer.NextToken();

#line  2806 "VBNET.ATG" 
			Expression handlerExpr = null; 
			Expr(
#line  2807 "VBNET.ATG" 
out expr);
			Expect(12);
			Expr(
#line  2807 "VBNET.ATG" 
out handlerExpr);

#line  2809 "VBNET.ATG" 
			statement = new RemoveHandlerStatement(expr, handlerExpr);
			
		} else if (la.kind == 216) {
			lexer.NextToken();
			Expr(
#line  2812 "VBNET.ATG" 
out expr);
			EndOfStmt();
			Block(
#line  2813 "VBNET.ATG" 
out embeddedStatement);
			Expect(100);
			Expect(216);

#line  2815 "VBNET.ATG" 
			statement = new DoLoopStatement(expr, embeddedStatement, ConditionType.While, ConditionPosition.Start);
			
		} else if (la.kind == 95) {
			lexer.NextToken();

#line  2820 "VBNET.ATG" 
			ConditionType conditionType = ConditionType.None;
			
			if (la.kind == 209 || la.kind == 216) {
				WhileOrUntil(
#line  2823 "VBNET.ATG" 
out conditionType);
				Expr(
#line  2823 "VBNET.ATG" 
out expr);
				EndOfStmt();
				Block(
#line  2824 "VBNET.ATG" 
out embeddedStatement);
				Expect(138);

#line  2827 "VBNET.ATG" 
				statement = new DoLoopStatement(expr, 
				                               embeddedStatement, 
				                               conditionType == ConditionType.While ? ConditionType.DoWhile : conditionType, 
				                               ConditionPosition.Start);
				
			} else if (la.kind == 1 || la.kind == 11) {
				EndOfStmt();
				Block(
#line  2834 "VBNET.ATG" 
out embeddedStatement);
				Expect(138);
				if (la.kind == 209 || la.kind == 216) {
					WhileOrUntil(
#line  2835 "VBNET.ATG" 
out conditionType);
					Expr(
#line  2835 "VBNET.ATG" 
out expr);
				}

#line  2837 "VBNET.ATG" 
				statement = new DoLoopStatement(expr, embeddedStatement, conditionType, ConditionPosition.End);
				
			} else SynErr(274);
		} else if (la.kind == 111) {
			lexer.NextToken();

#line  2842 "VBNET.ATG" 
			Expression group = null;
			TypeReference typeReference;
			string        typeName;
			Location startLocation = t.Location;
			
			if (la.kind == 97) {
				lexer.NextToken();
				LoopControlVariable(
#line  2849 "VBNET.ATG" 
out typeReference, out typeName);
				Expect(125);
				Expr(
#line  2850 "VBNET.ATG" 
out group);
				EndOfStmt();
				Block(
#line  2851 "VBNET.ATG" 
out embeddedStatement);
				Expect(149);
				if (StartOf(29)) {
					Expr(
#line  2852 "VBNET.ATG" 
out expr);
				}

#line  2854 "VBNET.ATG" 
				statement = new ForeachStatement(typeReference, 
				                                typeName,
				                                group, 
				                                embeddedStatement, 
				                                expr);
				statement.StartLocation = startLocation;
				statement.EndLocation   = t.EndLocation;
				
				
			} else if (StartOf(38)) {

#line  2865 "VBNET.ATG" 
				Expression start = null;
				Expression end = null;
				Expression step = null;
				Expression variableExpr = null;
				Expression nextExpr = null;
				List<Expression> nextExpressions = null;
				
				if (
#line  2872 "VBNET.ATG" 
IsLoopVariableDeclaration()) {
					LoopControlVariable(
#line  2873 "VBNET.ATG" 
out typeReference, out typeName);
				} else {

#line  2875 "VBNET.ATG" 
					typeReference = null; typeName = null; 
					SimpleExpr(
#line  2876 "VBNET.ATG" 
out variableExpr);
				}
				Expect(10);
				Expr(
#line  2878 "VBNET.ATG" 
out start);
				Expect(201);
				Expr(
#line  2878 "VBNET.ATG" 
out end);
				if (la.kind == 190) {
					lexer.NextToken();
					Expr(
#line  2878 "VBNET.ATG" 
out step);
				}
				EndOfStmt();
				Block(
#line  2879 "VBNET.ATG" 
out embeddedStatement);
				Expect(149);
				if (StartOf(29)) {
					Expr(
#line  2882 "VBNET.ATG" 
out nextExpr);

#line  2884 "VBNET.ATG" 
					nextExpressions = new List<Expression>();
					nextExpressions.Add(nextExpr);
					
					while (la.kind == 12) {
						lexer.NextToken();
						Expr(
#line  2887 "VBNET.ATG" 
out nextExpr);

#line  2887 "VBNET.ATG" 
						nextExpressions.Add(nextExpr); 
					}
				}

#line  2890 "VBNET.ATG" 
				statement = new ForNextStatement {
				TypeReference = typeReference,
				VariableName = typeName, 
				LoopVariableExpression = variableExpr,
				Start = start, 
				End = end, 
				Step = step, 
				EmbeddedStatement = embeddedStatement, 
				NextExpressions = nextExpressions
				};
				
			} else SynErr(275);
		} else if (la.kind == 105) {
			lexer.NextToken();
			Expr(
#line  2903 "VBNET.ATG" 
out expr);

#line  2903 "VBNET.ATG" 
			statement = new ErrorStatement(expr); 
		} else if (la.kind == 176) {
			lexer.NextToken();

#line  2905 "VBNET.ATG" 
			bool isPreserve = false; 
			if (la.kind == 169) {
				lexer.NextToken();

#line  2905 "VBNET.ATG" 
				isPreserve = true; 
			}
			ReDimClause(
#line  2906 "VBNET.ATG" 
out expr);

#line  2908 "VBNET.ATG" 
			ReDimStatement reDimStatement = new ReDimStatement(isPreserve);
			statement = reDimStatement;
			SafeAdd(reDimStatement, reDimStatement.ReDimClauses, expr as InvocationExpression);
			
			while (la.kind == 12) {
				lexer.NextToken();
				ReDimClause(
#line  2912 "VBNET.ATG" 
out expr);

#line  2913 "VBNET.ATG" 
				SafeAdd(reDimStatement, reDimStatement.ReDimClauses, expr as InvocationExpression); 
			}
		} else if (la.kind == 104) {
			lexer.NextToken();
			Expr(
#line  2917 "VBNET.ATG" 
out expr);

#line  2919 "VBNET.ATG" 
			EraseStatement eraseStatement = new EraseStatement();
			if (expr != null) { SafeAdd(eraseStatement, eraseStatement.Expressions, expr);}
			
			while (la.kind == 12) {
				lexer.NextToken();
				Expr(
#line  2922 "VBNET.ATG" 
out expr);

#line  2922 "VBNET.ATG" 
				if (expr != null) { SafeAdd(eraseStatement, eraseStatement.Expressions, expr); }
			}

#line  2923 "VBNET.ATG" 
			statement = eraseStatement; 
		} else if (la.kind == 191) {
			lexer.NextToken();

#line  2925 "VBNET.ATG" 
			statement = new StopStatement(); 
		} else if (
#line  2927 "VBNET.ATG" 
la.kind == Tokens.If) {
			Expect(122);

#line  2928 "VBNET.ATG" 
			Location ifStartLocation = t.Location; 
			Expr(
#line  2928 "VBNET.ATG" 
out expr);
			if (la.kind == 199) {
				lexer.NextToken();
			}
			if (la.kind == 1 || la.kind == 11) {
				EndOfStmt();
				Block(
#line  2931 "VBNET.ATG" 
out embeddedStatement);

#line  2933 "VBNET.ATG" 
				IfElseStatement ifStatement = new IfElseStatement(expr, embeddedStatement);
				ifStatement.StartLocation = ifStartLocation;
				Location elseIfStart;
				
				while (la.kind == 99 || 
#line  2939 "VBNET.ATG" 
IsElseIf()) {
					if (
#line  2939 "VBNET.ATG" 
IsElseIf()) {
						Expect(98);

#line  2939 "VBNET.ATG" 
						elseIfStart = t.Location; 
						Expect(122);
					} else {
						lexer.NextToken();

#line  2940 "VBNET.ATG" 
						elseIfStart = t.Location; 
					}

#line  2942 "VBNET.ATG" 
					Expression condition = null; Statement block = null; 
					Expr(
#line  2943 "VBNET.ATG" 
out condition);
					if (la.kind == 199) {
						lexer.NextToken();
					}
					EndOfStmt();
					Block(
#line  2944 "VBNET.ATG" 
out block);

#line  2946 "VBNET.ATG" 
					ElseIfSection elseIfSection = new ElseIfSection(condition, block);
					elseIfSection.StartLocation = elseIfStart;
					elseIfSection.EndLocation = t.Location;
					elseIfSection.Parent = ifStatement;
					ifStatement.ElseIfSections.Add(elseIfSection);
					
				}
				if (la.kind == 98) {
					lexer.NextToken();
					EndOfStmt();
					Block(
#line  2955 "VBNET.ATG" 
out embeddedStatement);

#line  2957 "VBNET.ATG" 
					ifStatement.FalseStatement.Add(embeddedStatement);
					
				}
				Expect(100);
				Expect(122);

#line  2961 "VBNET.ATG" 
				ifStatement.EndLocation = t.Location;
				statement = ifStatement;
				
			} else if (StartOf(39)) {

#line  2966 "VBNET.ATG" 
				IfElseStatement ifStatement = new IfElseStatement(expr);
				ifStatement.StartLocation = ifStartLocation;
				
				SingleLineStatementList(
#line  2969 "VBNET.ATG" 
ifStatement.TrueStatement);
				if (la.kind == 98) {
					lexer.NextToken();
					if (StartOf(39)) {
						SingleLineStatementList(
#line  2972 "VBNET.ATG" 
ifStatement.FalseStatement);
					}
				}

#line  2974 "VBNET.ATG" 
				ifStatement.EndLocation = t.Location; statement = ifStatement; 
			} else SynErr(276);
		} else if (la.kind == 182) {
			lexer.NextToken();
			if (la.kind == 61) {
				lexer.NextToken();
			}
			Expr(
#line  2977 "VBNET.ATG" 
out expr);
			EndOfStmt();

#line  2978 "VBNET.ATG" 
			List<SwitchSection> selectSections = new List<SwitchSection>();
			Statement block = null;
			
			while (la.kind == 61) {

#line  2982 "VBNET.ATG" 
				List<CaseLabel> caseClauses = null; Location caseLocation = la.Location; 
				lexer.NextToken();
				CaseClauses(
#line  2983 "VBNET.ATG" 
out caseClauses);
				if (
#line  2983 "VBNET.ATG" 
IsNotStatementSeparator()) {
					lexer.NextToken();
				}
				EndOfStmt();

#line  2985 "VBNET.ATG" 
				SwitchSection selectSection = new SwitchSection(caseClauses);
				selectSection.StartLocation = caseLocation;
				
				Block(
#line  2988 "VBNET.ATG" 
out block);

#line  2990 "VBNET.ATG" 
				selectSection.Children = block.Children;
				selectSection.EndLocation = t.EndLocation;
				selectSections.Add(selectSection);
				
			}

#line  2996 "VBNET.ATG" 
			statement = new SwitchStatement(expr, selectSections);
			
			Expect(100);
			Expect(182);
		} else if (la.kind == 157) {

#line  2999 "VBNET.ATG" 
			OnErrorStatement onErrorStatement = null; 
			OnErrorStatement(
#line  3000 "VBNET.ATG" 
out onErrorStatement);

#line  3000 "VBNET.ATG" 
			statement = onErrorStatement; 
		} else if (la.kind == 119) {

#line  3001 "VBNET.ATG" 
			GotoStatement goToStatement = null; 
			GotoStatement(
#line  3002 "VBNET.ATG" 
out goToStatement);

#line  3002 "VBNET.ATG" 
			statement = goToStatement; 
		} else if (la.kind == 179) {

#line  3003 "VBNET.ATG" 
			ResumeStatement resumeStatement = null; 
			ResumeStatement(
#line  3004 "VBNET.ATG" 
out resumeStatement);

#line  3004 "VBNET.ATG" 
			statement = resumeStatement; 
		} else if (StartOf(38)) {

#line  3007 "VBNET.ATG" 
			Expression val = null;
			AssignmentOperatorType op;
			
			bool mustBeAssignment = la.kind == Tokens.Plus  || la.kind == Tokens.Minus ||
			                        la.kind == Tokens.Not   || la.kind == Tokens.Times;
			
			SimpleExpr(
#line  3013 "VBNET.ATG" 
out expr);
			if (StartOf(40)) {
				AssignmentOperator(
#line  3015 "VBNET.ATG" 
out op);
				Expr(
#line  3015 "VBNET.ATG" 
out val);

#line  3015 "VBNET.ATG" 
				expr = new AssignmentExpression(expr, op, val); 
			} else if (la.kind == 1 || la.kind == 11 || la.kind == 98) {

#line  3016 "VBNET.ATG" 
				if (mustBeAssignment) Error("error in assignment."); 
			} else SynErr(277);

#line  3019 "VBNET.ATG" 
			// a field reference expression that stands alone is a
			// invocation expression without parantheses and arguments
			if(expr is MemberReferenceExpression || expr is IdentifierExpression) {
				expr = new InvocationExpression(expr);
			}
			statement = new ExpressionStatement(expr);
			
		} else if (la.kind == 60) {
			lexer.NextToken();
			SimpleExpr(
#line  3026 "VBNET.ATG" 
out expr);

#line  3026 "VBNET.ATG" 
			statement = new ExpressionStatement(expr); 
		} else if (la.kind == 211) {
			lexer.NextToken();

#line  3028 "VBNET.ATG" 
			Statement block;  
			if (
#line  3029 "VBNET.ATG" 
Peek(1).kind == Tokens.As) {

#line  3030 "VBNET.ATG" 
				LocalVariableDeclaration resourceAquisition = new LocalVariableDeclaration(Modifiers.None); 
				VariableDeclarator(
#line  3031 "VBNET.ATG" 
resourceAquisition.Variables);
				while (la.kind == 12) {
					lexer.NextToken();
					VariableDeclarator(
#line  3033 "VBNET.ATG" 
resourceAquisition.Variables);
				}
				Block(
#line  3035 "VBNET.ATG" 
out block);

#line  3037 "VBNET.ATG" 
				statement = new UsingStatement(resourceAquisition, block);
				
			} else if (StartOf(29)) {
				Expr(
#line  3039 "VBNET.ATG" 
out expr);
				Block(
#line  3040 "VBNET.ATG" 
out block);

#line  3041 "VBNET.ATG" 
				statement = new UsingStatement(new ExpressionStatement(expr), block); 
			} else SynErr(278);
			Expect(100);
			Expect(211);
		} else if (StartOf(41)) {
			LocalDeclarationStatement(
#line  3044 "VBNET.ATG" 
out statement);
		} else SynErr(279);
	}
예제 #7
0
 public override object VisitEraseStatement(EraseStatement eraseStatement, object data)
 {
     return(base.VisitEraseStatement(eraseStatement, data));
 }
예제 #8
0
		public virtual object VisitEraseStatement(EraseStatement eraseStatement, object data) {
			Debug.Assert((eraseStatement != null));
			Debug.Assert((eraseStatement.Expressions != null));
			foreach (Expression o in eraseStatement.Expressions) {
				Debug.Assert(o != null);
				o.AcceptVisitor(this, data);
			}
			return null;
		}
 private bool IsMatch(EraseStatement left, EraseStatement data)
 {
     return(false);
 }
 public object VisitEraseStatement(EraseStatement eraseStatement, object data)
 {
     throw new NotImplementedException();
 }
		public virtual object VisitEraseStatement(EraseStatement eraseStatement, object data) {
			throw new global::System.NotImplementedException("EraseStatement");
		}
		public virtual object VisitEraseStatement(EraseStatement eraseStatement, object data) {
			Debug.Assert((eraseStatement != null));
			Debug.Assert((eraseStatement.Expressions != null));
			for (int i = 0; i < eraseStatement.Expressions.Count; i++) {
				Expression o = eraseStatement.Expressions[i];
				Debug.Assert(o != null);
				nodeStack.Push(o);
				o.AcceptVisitor(this, data);
				o = (Expression)nodeStack.Pop();
				if (o == null)
					eraseStatement.Expressions.RemoveAt(i--);
				else
					eraseStatement.Expressions[i] = o;
			}
			return null;
		}
        public TranslationResult Translate(EraseStatement eraseStatement, ScopeAccessInformation scopeAccessInformation, int indentationDepth)
        {
            if (eraseStatement == null)
            {
                throw new ArgumentNullException("eraseStatement");
            }
            if (scopeAccessInformation == null)
            {
                throw new ArgumentNullException("scopeAccessInformation");
            }
            if (indentationDepth < 0)
            {
                throw new ArgumentOutOfRangeException("indentationDepth", "must be zero or greater");
            }

            // We need to work out what tokens in the target(s) or their argument(s) reference any by-ref arguments in the containing function (where applicable). For the case
            // where there is a single target which is itself a single NameToken, if this is a by-ref argument of the containing function then this will definitely need rewriting.
            // The FuncByRefArgumentMapper doesn't know about this since it is not aware that that token will be reference inside a "targetSetter" lambda, so this needs to be
            // checked explicitly first. In an ideal world, this would be done later on, with the other "success case" logic - but then we'd also have to replicate the functionality
            // in the FuncByRefArgumentMapper that removes any duplicates from the byRefArgumentsToRewrite set (preferring any with read-write mappings over read-only). After this
            // case is handled, all other targets (and any arguments they have) can be rewritten. These won't introduce any "surprising" lambdas, but if there is any error-trapping
            // involved then the erase target evaluation will be wrapped in a HANDLEERROR lambda, but the FuncByRefArgumentMapper IS aware of that and will deal with it accordingly.
            var byRefMapper             = new FuncByRefArgumentMapper(_nameRewriter, _tempNameGenerator, _logger);
            var byRefArgumentsToRewrite = new NonNullImmutableList <FuncByRefMapping>();

            if (eraseStatement.Targets.Count() == 1)
            {
                var singleEraseTargetForByRefAliasingConsideration = eraseStatement.Targets.Single();
                if ((singleEraseTargetForByRefAliasingConsideration.Target.Tokens.Count() == 1) &&
                    (singleEraseTargetForByRefAliasingConsideration.ArgumentsIfAny == null) &&
                    !singleEraseTargetForByRefAliasingConsideration.WrappedInBraces)
                {
                    var singleTargetNameToken        = singleEraseTargetForByRefAliasingConsideration.Target.Tokens.Single() as NameToken;
                    var containingFunctionOrProperty = scopeAccessInformation.ScopeDefiningParent as AbstractFunctionBlock;
                    if ((singleTargetNameToken != null) && (containingFunctionOrProperty != null))
                    {
                        var targetByRefFunctionArgumentIfApplicable = containingFunctionOrProperty.Parameters
                                                                      .Where(p => p.ByRef)
                                                                      .FirstOrDefault(p => _nameRewriter.GetMemberAccessTokenName(p.Name) == _nameRewriter.GetMemberAccessTokenName(singleTargetNameToken));
                        if (targetByRefFunctionArgumentIfApplicable != null)
                        {
                            byRefArgumentsToRewrite = byRefArgumentsToRewrite.Add(new FuncByRefMapping(
                                                                                      targetByRefFunctionArgumentIfApplicable.Name,
                                                                                      _tempNameGenerator(new CSharpName("byrefalias"), scopeAccessInformation),
                                                                                      mappedValueIsReadOnly: false
                                                                                      ));
                        }
                    }
                }
            }
            foreach (var targetDetails in eraseStatement.Targets)
            {
                byRefArgumentsToRewrite = byRefMapper.GetByRefArgumentsThatNeedRewriting(
                    targetDetails.Target.ToStageTwoParserExpression(scopeAccessInformation, ExpressionReturnTypeOptions.NotSpecified, _logger.Warning),
                    scopeAccessInformation,
                    byRefArgumentsToRewrite
                    );
                if (targetDetails.ArgumentsIfAny != null)
                {
                    foreach (var argument in targetDetails.ArgumentsIfAny)
                    {
                        byRefArgumentsToRewrite = byRefMapper.GetByRefArgumentsThatNeedRewriting(
                            argument.ToStageTwoParserExpression(scopeAccessInformation, ExpressionReturnTypeOptions.NotSpecified, _logger.Warning),
                            scopeAccessInformation,
                            byRefArgumentsToRewrite
                            );
                    }
                }
            }
            if (byRefArgumentsToRewrite.Any())
            {
                eraseStatement = new EraseStatement(
                    eraseStatement.Targets.Select(targetDetails =>
                {
                    var rewrittenTarget = byRefArgumentsToRewrite.RewriteExpressionUsingByRefArgumentMappings(targetDetails.Target, _nameRewriter);
                    if (targetDetails.ArgumentsIfAny == null)
                    {
                        return(new EraseStatement.TargetDetails(rewrittenTarget, null, targetDetails.WrappedInBraces));
                    }
                    return(new EraseStatement.TargetDetails(
                               rewrittenTarget,
                               targetDetails.ArgumentsIfAny.Select(argument => byRefArgumentsToRewrite.RewriteExpressionUsingByRefArgumentMappings(argument, _nameRewriter)),
                               targetDetails.WrappedInBraces
                               ));
                }),
                    eraseStatement.KeywordLineIndex
                    );
            }

            // If the ERASE call is invalid (eg. zero targets "ERASE" or multiple "ERASE a, b" or not a possible by-ref target "ERASE (a)" or "ERASE a.Name" or an invalid array /
            // reference / method call "ERASE a()") then evaluate the targets (to be consistent with VBScript's behaviour) but then raise an error.
            string exceptionStatementIfTargetConfigurationIsInvalid;

            if (eraseStatement.Targets.Count() != 1)
            {
                exceptionStatementIfTargetConfigurationIsInvalid = string.Format(
                    "throw new Exception(\"Wrong number of arguments: 'Erase' (line {0})\");",
                    eraseStatement.KeywordLineIndex + 1
                    );
            }
            else
            {
                var eraseTargetToValidate = eraseStatement.Targets.Single();
                if ((eraseTargetToValidate.WrappedInBraces) || (eraseTargetToValidate.Target.Tokens.Count() > 1) || !(eraseTargetToValidate.Target.Tokens.Single() is NameToken))
                {
                    // "Erase (a)" is invalid, it would result in "a" being passed by-val, which would be senseless when trying to erase a dynamic array
                    // "Erase a.Roles" is invalid, the target must be a direct reference (again, since an indirect reference like this would not be passed by-ref)
                    exceptionStatementIfTargetConfigurationIsInvalid = string.Format(
                        "throw new TypeMismatchException(\"'Erase' (line {0})\");",
                        eraseStatement.KeywordLineIndex + 1
                        );
                }
                else
                {
                    // Ensure that the single NameToken in the single erase target is a variable (a function call will result in a "Type mismatch" error)
                    var singleTargetNameToken  = (NameToken)eraseTargetToValidate.Target.Tokens.Single();
                    var targetReferenceDetails = scopeAccessInformation.TryToGetDeclaredReferenceDetails(singleTargetNameToken, _nameRewriter);
                    if ((targetReferenceDetails != null) && (targetReferenceDetails.ReferenceType != ReferenceTypeOptions.Variable))
                    {
                        // Note: If the variable has not been declared then targetReferenceDetails will be null, but that means that it will become an undeclared variable later on,
                        // it means that it's definitely not a function
                        exceptionStatementIfTargetConfigurationIsInvalid = string.Format(
                            "throw new TypeMismatchException(\"'Erase' (line {0})\");",
                            eraseStatement.KeywordLineIndex + 1
                            );
                    }
                    else
                    {
                        exceptionStatementIfTargetConfigurationIsInvalid = null;
                    }
                }
            }

            var translationResult = TranslationResult.Empty;
            int numberOfIndentationLevelsToWithDrawAfterByRefArgumentsProcessed;

            if (byRefArgumentsToRewrite.Any())
            {
                scopeAccessInformation = scopeAccessInformation.ExtendVariables(
                    byRefArgumentsToRewrite
                    .Select(r => new ScopedNameToken(r.To.Name, r.From.LineIndex, ScopeLocationOptions.WithinFunctionOrPropertyOrWith))
                    .ToNonNullImmutableList()
                    );
                var byRefMappingOpeningTranslationDetails = byRefArgumentsToRewrite.OpenByRefReplacementDefinitionWork(translationResult, indentationDepth, _nameRewriter);
                translationResult = byRefMappingOpeningTranslationDetails.TranslationResult;
                numberOfIndentationLevelsToWithDrawAfterByRefArgumentsProcessed = byRefMappingOpeningTranslationDetails.DistanceToIndentCodeWithMappedValues;
                indentationDepth += numberOfIndentationLevelsToWithDrawAfterByRefArgumentsProcessed;
            }
            else
            {
                numberOfIndentationLevelsToWithDrawAfterByRefArgumentsProcessed = 0;
            }
            if (exceptionStatementIfTargetConfigurationIsInvalid != null)
            {
                foreach (var target in eraseStatement.Targets)
                {
                    var targetExpressionTokens = target.Target.Tokens.ToList();
                    if (target.ArgumentsIfAny != null)
                    {
                        targetExpressionTokens.Add(new OpenBrace(targetExpressionTokens.Last().LineIndex));
                        foreach (var indexedArgument in target.ArgumentsIfAny.Select((a, i) => new { Index = i, Argument = a }))
                        {
                            if (indexedArgument.Index > 0)
                            {
                                targetExpressionTokens.Add(new ArgumentSeparatorToken(targetExpressionTokens.Last().LineIndex));
                            }
                            targetExpressionTokens.AddRange(indexedArgument.Argument.Tokens);
                        }
                        targetExpressionTokens.Add(new CloseBrace(targetExpressionTokens.Last().LineIndex));
                    }
                    var translatedTarget = _statementTranslator.Translate(
                        new Expression(targetExpressionTokens),
                        scopeAccessInformation,
                        ExpressionReturnTypeOptions.NotSpecified,
                        _logger.Warning
                        );
                    var undeclaredVariablesReferencedByTarget = translatedTarget.GetUndeclaredVariablesAccessed(scopeAccessInformation, _nameRewriter);
                    foreach (var undeclaredVariable in undeclaredVariablesReferencedByTarget)
                    {
                        _logger.Warning("Undeclared variable: \"" + undeclaredVariable.Content + "\" (line " + (undeclaredVariable.LineIndex + 1) + ")");
                    }
                    translationResult = translationResult.Add(new TranslatedStatement(
                                                                  string.Format(
                                                                      "var {0} = {1};",
                                                                      _tempNameGenerator(new CSharpName("invalidEraseTarget"), scopeAccessInformation).Name,
                                                                      translatedTarget.TranslatedContent
                                                                      ),
                                                                  indentationDepth,
                                                                  target.Target.Tokens.First().LineIndex
                                                                  ));
                    translationResult = translationResult.AddUndeclaredVariables(undeclaredVariablesReferencedByTarget);
                }
                translationResult = translationResult.Add(new TranslatedStatement(
                                                              exceptionStatementIfTargetConfigurationIsInvalid,
                                                              indentationDepth,
                                                              eraseStatement.KeywordLineIndex
                                                              ));
            }
            else
            {
                // If there are no target arguments then we use the ERASE signature that takes only the target (by-ref). Otherwise call the signature that tries to map the
                // arguments as indices on an array and then erases that element (which must also be an array) - in this case the target need not be passed by-ref.
                // - We know that the ArgumentsIfAny set will be null if there are no items in it, since a non-null-but-empty set is an error condition handled above
                var singleEraseTarget           = eraseStatement.Targets.Single();
                var translatedSingleEraseTarget = _statementTranslator.Translate(
                    singleEraseTarget.Target,
                    scopeAccessInformation,
                    ExpressionReturnTypeOptions.NotSpecified,
                    _logger.Warning
                    );
                var undeclaredVariablesInSingleEraseTarget = translatedSingleEraseTarget.GetUndeclaredVariablesAccessed(scopeAccessInformation, _nameRewriter).ToArray();
                foreach (var undeclaredVariable in undeclaredVariablesInSingleEraseTarget)
                {
                    _logger.Warning("Undeclared variable: \"" + undeclaredVariable.Content + "\" (line " + (undeclaredVariable.LineIndex + 1) + ")");
                }
                translationResult = translationResult.AddUndeclaredVariables(undeclaredVariablesInSingleEraseTarget);
                if (singleEraseTarget.ArgumentsIfAny == null)
                {
                    translationResult = translationResult.Add(new TranslatedStatement(
                                                                  string.Format(
                                                                      "{0}.ERASE({1}, {2} => {{ {1} = {2}; }});",
                                                                      _supportRefName.Name,
                                                                      translatedSingleEraseTarget.TranslatedContent,
                                                                      _tempNameGenerator(new CSharpName("v"), scopeAccessInformation).Name
                                                                      ),
                                                                  indentationDepth,
                                                                  singleEraseTarget.Target.Tokens.First().LineIndex
                                                                  ));
                }
                else
                {
                    // Note: "Erase a()" is a runtime error condition - either "a" is an array, in which case it will be a "Subscript out of range" or "a" is a variable that
                    // is not an array, in which case it will be a "Type mismatch" (we verified earlier that "a" is in fact a variable - and not a function, for example).
                    // We have no choice but to let the ERASE function work this out at runtime (which the non-by-ref-argument signature will do).
                    var translatedArguments = singleEraseTarget.ArgumentsIfAny
                                              .Select(argument => _statementTranslator.Translate(
                                                          argument,
                                                          scopeAccessInformation,
                                                          ExpressionReturnTypeOptions.NotSpecified,
                                                          _logger.Warning
                                                          ))
                                              .ToArray();   // Going to evaluate everything twice, might as well ToArray it
                    translationResult = translationResult.Add(new TranslatedStatement(
                                                                  string.Format(
                                                                      "{0}.ERASE({1}{2}{3});",
                                                                      _supportRefName.Name,
                                                                      translatedSingleEraseTarget.TranslatedContent,
                                                                      translatedArguments.Any() ? ", " : "",
                                                                      string.Join(", ", translatedArguments.Select(a => a.TranslatedContent))
                                                                      ),
                                                                  indentationDepth,
                                                                  singleEraseTarget.Target.Tokens.First().LineIndex
                                                                  ));
                    var undeclaredVariablesInArguments = translatedArguments.SelectMany(arg => arg.GetUndeclaredVariablesAccessed(scopeAccessInformation, _nameRewriter)).ToArray();
                    foreach (var undeclaredVariable in undeclaredVariablesInArguments)
                    {
                        _logger.Warning("Undeclared variable: \"" + undeclaredVariable.Content + "\" (line " + (undeclaredVariable.LineIndex + 1) + ")");
                    }
                    translationResult = translationResult.AddUndeclaredVariables(undeclaredVariablesInArguments);
                }
            }
            if (byRefArgumentsToRewrite.Any())
            {
                indentationDepth -= numberOfIndentationLevelsToWithDrawAfterByRefArgumentsProcessed;
                translationResult = byRefArgumentsToRewrite.CloseByRefReplacementDefinitionWork(translationResult, indentationDepth, _nameRewriter);
            }
            return(translationResult);
        }
		public sealed override object VisitEraseStatement(EraseStatement eraseStatement, object data) {
			BeginVisit(eraseStatement);
			object result = TrackedVisitEraseStatement(eraseStatement, data);
			EndVisit(eraseStatement);
			return result;
		}
		public virtual object TrackedVisitEraseStatement(EraseStatement eraseStatement, object data) {
			return base.VisitEraseStatement(eraseStatement, data);
		}