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); }
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); }
public virtual T Visit(EraseStatement stmt) => Visit(stmt as Statement);
public void VBNetEraseStatementTest() { EraseStatement eraseStatement = ParseUtil.ParseStatement <EraseStatement>("Erase a, b, c"); }
public virtual object VisitEraseStatement(EraseStatement eraseStatement, object data) { throw new global::System.NotImplementedException("EraseStatement"); }
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); }
public override object VisitEraseStatement(EraseStatement eraseStatement, object data) { return(base.VisitEraseStatement(eraseStatement, data)); }
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) { 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); }