示例#1
0
        public override void TraverseChildren(IBlockStatement block)
        {
            Contract.Assume(block is BlockStatement);
            var mutableBlock = (BlockStatement)block;

            this.Traverse(mutableBlock.Statements);
            foreach (var pair in this.declaringBlockMap)
            {
                if (pair.Value != mutableBlock)
                {
                    continue;
                }
                var boundExpr = this.closureFieldToLocalOrParameterMap[pair.Key] as BoundExpression;
                if (boundExpr == null)
                {
                    Contract.Assume(false); continue;
                }
                var local = boundExpr.Definition as ILocalDefinition;
                if (local == null)
                {
                    Contract.Assume(false); continue;
                }
                var localDecl = new LocalDeclarationStatement()
                {
                    LocalVariable = local
                };
                mutableBlock.Statements.Insert(0, localDecl);
            }
        }
示例#2
0
        protected override IPyStatement[] VisitLocalDeclarationStatement(LocalDeclarationStatement src)
        {
            var s = new List <IPyStatement>();

            foreach (var i in src.Declaration.Declarators)
            {
                // to jest przypadek z c# 'int x;', dla Py można to pominąć
                if (i.Value == null)
                {
                    continue;
                }
                if (i.Value is UnknownIdentifierValue)
                {
                    throw new NotImplementedException();
                }
                var l  = new PyVariableExpression(i.Name, PyVariableKind.Local);
                var r  = TransValue(i.Value);
                var tt = new PyAssignExpression(l, r);
                s.Add(new PyExpressionStatement(tt));

                //var r = new PyAssignVariable( PyVariableExpression.AddDollar(i.Name), false );
                //// r.Name = "$" + i.Name;
                //r.Value = TV(i.Value);
                //s.Add(r);
            }

            return(s.ToArray());
        }
        public LogicalBody(Member member, BlockSyntax block, SemanticModel semanticModel)
        {
            this.member = member;
            this.block  = block;

            // parse statments
            statements = new List <Statement>();
            foreach (var s in block.Statements)
            {
                var       kind = s.Kind();
                Statement statement;
                switch (kind)
                {
                case SyntaxKind.ExpressionStatement: statement = new ExpressionStatement((ExpressionStatementSyntax)s, semanticModel); break;

                case SyntaxKind.ReturnStatement: statement = new ReturnStatement((ReturnStatementSyntax)s, semanticModel); break;

                case SyntaxKind.LocalDeclarationStatement: statement = new LocalDeclarationStatement((LocalDeclarationStatementSyntax)s, semanticModel); break;

                default: throw new NotImplementedException("Unsuported Statement SyntaxKind: " + kind);
                }

                statements.Add(statement);
            }
        }
示例#4
0
        public override void TraverseChildren(IBlockStatement block)
        {
            BasicBlock basicBlock = (BasicBlock)block;
            List <ILocalDefinition> /*?*/ localsInCurrentScope = basicBlock.LocalVariables;

            if (localsInCurrentScope != null)
            {
                this.AddDeclarationsWithInitialValues(localsInCurrentScope, basicBlock);
                List <IStatement> prelude = new List <IStatement>(localsInCurrentScope.Count);
                foreach (ILocalDefinition localDef in localsInCurrentScope)
                {
                    if (this.declaredLocals.ContainsKey(localDef))
                    {
                        continue;
                    }
                    LocalDeclarationStatement localDecl = new LocalDeclarationStatement();
                    localDecl.LocalVariable = localDef;
                    prelude.Add(localDecl);
                }
                if (prelude.Count > 0)
                {
                    basicBlock.Statements.InsertRange(0, prelude); //TODO: use pdb info to insert them in the same order they appear in the source
                }
            }
            this.Traverse(basicBlock.Statements);
        }
示例#5
0
 public void VisitDeclaration(LocalDeclarationStatement node)
 {
     for (int i = 0; i < node.DeclarationExpressions.Count; i++)
     {
         node.DeclarationExpressions[i].Accept(this);
     }
 }
        public override IStatement VisitVariableDeclaration(VariableDeclarationSyntax node)
        {
            ITypeReference t = null;

            if (!node.Type.IsVar)
            {
                var o = this.semanticModel.GetTypeInfo(node.Type);
                t = this.mapper.Map(o.Type);
            }
            var decls = new List <IStatement>();

            foreach (var v in node.Variables)
            {
                var         s            = (Microsoft.CodeAnalysis.CSharp.Symbols.LocalSymbol) this.semanticModel.GetDeclaredSymbol(v);
                IExpression initialValue = null;
                if (v.Initializer != null)
                {
                    var evc = v.Initializer.Value;
                    initialValue = this.expressionVisitor.Visit(evc);
                }
                var local = new LocalDefinition()
                {
                    Name             = this.host.NameTable.GetNameFor(s.Name),
                    MethodDefinition = this.method,
                };
                this.expressionVisitor.RegisterLocal(s, local);
                if (t != null)
                {
                    local.Type = t;
                }
                else if (initialValue != null)
                {
                    local.Type = initialValue.Type;
                }
                var ldc = new LocalDeclarationStatement()
                {
                    InitialValue  = initialValue != null ? initialValue : null,
                    LocalVariable = local,
                    Locations     = Helper.SourceLocation(this.tree, node),
                };
                decls.Add(ldc);
            }
            if (decls.Count == 1)
            {
                return(decls[0]);
            }
            else
            {
                var bs = new BlockStatement()
                {
                    Statements = decls,
                };
                return(bs);
            }
        }
示例#7
0
        public override void ExtendDeclaration(IDeclarationModel declaration, CompilationModel model)
        {
            // this only applies to methods
            var methodDecl = declaration as MethodDeclaration;
            if (methodDecl == null || methodDecl.Container == null)
                return;

            if (!methodDecl.Definition.Symbol.IsExtensionMethod)
                throw new CompilationException("The ScriptMixin attribute can only be applied to extension methods.", declaration);

            // remove the function from the container
            methodDecl.Container.RemoveMember(methodDecl);

            // get the extension target info
            var extTarget = methodDecl.Parameters[0];
            var extType = extTarget.Definition.Type;

            // rewrite first param as a local declaration to this context
            var thisDecl = new LocalDeclarationStatement { VariableDeclaration = new VariableDeclaration() };
            thisDecl.VariableDeclaration.Variables.Add(new VariableDeclarator
            {
                Definition = new LocalDefinition
                {
                    Name = extTarget.Name,
                    Type = extType
                },
                EqualsValueExpression = new LiteralExpression { Text = "this" }
            });

            // add the declaration to the method body
            methodDecl.Body.Statements.Insert(0, thisDecl);

            // create a lambda using the method body.
            var lambdaExpression = new LambdaExpression();
            lambdaExpression.Body = methodDecl.Body;

            for (int i = 1; i < methodDecl.Parameters.Count; i++)
                lambdaExpression.Parameters.Add(methodDecl.Parameters[i]);

            // create a global statement to set the prototype value
            var target = extType.GetFullName() + ".prototype." + methodDecl.Definition.Name;

            model.GlobalStatements.Add(new ExpressionStatement
            {
                Expression = new BinaryExpression
                {
                    LeftExpression = new LiteralExpression { Text = target },
                    RightExpression = lambdaExpression,
                    Operator = "="
                }
            });
        }
示例#8
0
 private static void WriteLocalDeclarationStatement(LocalDeclarationStatement statement, StreamWriter writer)
 {
     foreach (var variable in statement.variables)
     {
         writer.WritePrefix(string.Format("{0} {1} ", variable.typeFullNameFlat, variable.fullNameFlat));
         if (variable.initializeExpression != null)
         {
             writer.Write("= ");
             WriteExperesion(variable.initializeExpression, writer);
         }
         writer.WriteLine(';');
     }
 }
示例#9
0
        bool ParseLocalDeclarationStatement(out LocalDeclarationStatement localDeclarationStatement)
        {
            localDeclarationStatement = new LocalDeclarationStatement();

            if (tokenReader.Expect(LexKind.Keyword))
            {
                if (tokenReader.Expect(LexKind.Identifier, 1))
                {
                    if (DataType.IsDataType(tokenReader.Peek().Value))
                    {
                        localDeclarationStatement = new LocalDeclarationStatement()
                        {
                            DataType = new DataType(tokenReader.Peek().Value, true),
                            Name     = tokenReader.Peek(1).Value
                        };

                        /* If local is assigned at creation */
                        if (tokenReader.Expect(LexKind.Equals, 2))
                        {
                            tokenReader.Skip(3);
                            if (ParseExpression(out Expression local))
                            {
                                localDeclarationStatement.Value = local;
                            }
                            else
                            {
                                Console.WriteLine("Unable to parse expression @ line " + tokenReader.Peek().Line);
                            }
                        }
                        else
                        {
                            tokenReader.Skip(2);
                        }

                        tokenReader.ExpectFatal(LexKind.Semicolon);

                        return(true);
                    }
                }
            }

            return(false);
        }
示例#10
0
        static dynamic handle(LocalDeclarationStatement v)
        {
            print("creating local variable");

            string typename = ((dynamic)v.Type).GenericIdentifier;

            //TODO: handle more complex local variable delcaration than this. Like templates or something, or "var t = new T(param1, param2)"
            executingFunction.Localvars[v.Declarators[0].Identifier.Identifier] = new ObjectInstance(typename, v.Declarators[0].Identifier.Identifier);

            //is this accounting for "Object o = new Object(..."? If so, this is where the identifier is.
            if (v.Declarators[0].Initializer != null)
            {
                executingFunction.Localvars[v.Declarators[0].Identifier.Identifier].value = handle_dyn(v.Declarators[0].Initializer);
            }

            //If the ".Initializer" is null, it has a null value, and is waiting to be written to.

            //we store the name for the object instance creation call ("new T(...)") - see use of "ObjectCreationExpression".
            localVarDeclarationName = v.Declarators[0].Identifier.Identifier;

            return(null);
        }
示例#11
0
        internal void Traverse(SourceMethodBody body, BasicBlock rootBlock)
        {
            this.Traverse(rootBlock);
            //Now add declarations for any locals declared only on the body (for example temporary variables introduced by Unstacker).
            List <IStatement> prelude = new List <IStatement>();
            var localsAndTemps        = body.localVariablesAndTemporaries;

            this.AddDeclarationsWithInitialValues(localsAndTemps, rootBlock);
            foreach (var localDef in localsAndTemps)
            {
                if (this.declaredLocals.ContainsKey(localDef))
                {
                    continue;
                }
                LocalDeclarationStatement localDecl = new LocalDeclarationStatement();
                localDecl.LocalVariable = localDef;
                prelude.Add(localDecl);
            }
            if (prelude.Count > 0)
            {
                rootBlock.Statements.InsertRange(0, prelude); //TODO: use pdb info to insert them in the same order they appear in the source
            }
        }
示例#12
0
文件: Unstacker.cs 项目: xornand/cci
        public static IBlockStatement GetRidOfStack(SourceMethodBody methodBody, IBlockStatement block)
        {
            var me     = new Unstacker(methodBody);
            var result = me.Rewrite(block);
            var stmts  = new List <IStatement>();

            foreach (var loc in me.createdLocals.Values)
            {
                var decl = new LocalDeclarationStatement()
                {
                    InitialValue  = null,
                    LocalVariable = loc,
                };
                stmts.Add(decl);
            }
            stmts.AddRange(result.Statements);
            var newBlock = new BlockStatement()
            {
                Statements = stmts,
                Locations  = new List <ILocation>(result.Locations),
            };

            return(newBlock);
        }
示例#13
0
        public static Doc Print(SyntaxNode syntaxNode)
        {
            if (syntaxNode == null)
            {
                return(Doc.Null);
            }

            // TODO 0 kill? runtime repo has files that will fail on deep recursion
            if (depth > 200)
            {
                throw new InTooDeepException();
            }

            depth++;
            try
            {
                switch (syntaxNode)
                {
                case AliasQualifiedNameSyntax aliasQualifiedNameSyntax:
                    return(AliasQualifiedName.Print(aliasQualifiedNameSyntax));

                case AnonymousMethodExpressionSyntax anonymousMethodExpressionSyntax:
                    return(AnonymousMethodExpression.Print(anonymousMethodExpressionSyntax));

                case AnonymousObjectCreationExpressionSyntax anonymousObjectCreationExpressionSyntax:
                    return(AnonymousObjectCreationExpression.Print(
                               anonymousObjectCreationExpressionSyntax
                               ));

                case AnonymousObjectMemberDeclaratorSyntax anonymousObjectMemberDeclaratorSyntax:
                    return(AnonymousObjectMemberDeclarator.Print(
                               anonymousObjectMemberDeclaratorSyntax
                               ));

                case ArgumentListSyntax argumentListSyntax:
                    return(ArgumentList.Print(argumentListSyntax));

                case ArgumentSyntax argumentSyntax:
                    return(Argument.Print(argumentSyntax));

                case ArrayCreationExpressionSyntax arrayCreationExpressionSyntax:
                    return(ArrayCreationExpression.Print(arrayCreationExpressionSyntax));

                case ArrayRankSpecifierSyntax arrayRankSpecifierSyntax:
                    return(ArrayRankSpecifier.Print(arrayRankSpecifierSyntax));

                case ArrayTypeSyntax arrayTypeSyntax:
                    return(ArrayType.Print(arrayTypeSyntax));

                case ArrowExpressionClauseSyntax arrowExpressionClauseSyntax:
                    return(ArrowExpressionClause.Print(arrowExpressionClauseSyntax));

                case AssignmentExpressionSyntax assignmentExpressionSyntax:
                    return(AssignmentExpression.Print(assignmentExpressionSyntax));

                case AttributeListSyntax attributeListSyntax:
                    return(AttributeList.Print(attributeListSyntax));

                case AwaitExpressionSyntax awaitExpressionSyntax:
                    return(AwaitExpression.Print(awaitExpressionSyntax));

                case BaseExpressionSyntax baseExpressionSyntax:
                    return(BaseExpression.Print(baseExpressionSyntax));

                case BaseFieldDeclarationSyntax baseFieldDeclarationSyntax:
                    return(BaseFieldDeclaration.Print(baseFieldDeclarationSyntax));

                case BaseListSyntax baseListSyntax:
                    return(BaseList.Print(baseListSyntax));

                case BaseMethodDeclarationSyntax baseMethodDeclarationSyntax:
                    return(BaseMethodDeclaration.Print(baseMethodDeclarationSyntax));

                case BasePropertyDeclarationSyntax basePropertyDeclarationSyntax:
                    return(BasePropertyDeclaration.Print(basePropertyDeclarationSyntax));

                case BaseTypeDeclarationSyntax baseTypeDeclarationSyntax:
                    return(BaseTypeDeclaration.Print(baseTypeDeclarationSyntax));

                case BinaryExpressionSyntax binaryExpressionSyntax:
                    return(BinaryExpression.Print(binaryExpressionSyntax));

                case BinaryPatternSyntax binaryPatternSyntax:
                    return(BinaryPattern.Print(binaryPatternSyntax));

                case BlockSyntax blockSyntax:
                    return(Block.Print(blockSyntax));

                case BracketedArgumentListSyntax bracketedArgumentListSyntax:
                    return(BracketedArgumentList.Print(bracketedArgumentListSyntax));

                case BracketedParameterListSyntax bracketedParameterListSyntax:
                    return(BracketedParameterList.Print(bracketedParameterListSyntax));

                case BreakStatementSyntax breakStatementSyntax:
                    return(BreakStatement.Print(breakStatementSyntax));

                case CasePatternSwitchLabelSyntax casePatternSwitchLabelSyntax:
                    return(CasePatternSwitchLabel.Print(casePatternSwitchLabelSyntax));

                case CaseSwitchLabelSyntax caseSwitchLabelSyntax:
                    return(CaseSwitchLabel.Print(caseSwitchLabelSyntax));

                case CastExpressionSyntax castExpressionSyntax:
                    return(CastExpression.Print(castExpressionSyntax));

                case CatchClauseSyntax catchClauseSyntax:
                    return(CatchClause.Print(catchClauseSyntax));

                case CheckedExpressionSyntax checkedExpressionSyntax:
                    return(CheckedExpression.Print(checkedExpressionSyntax));

                case CheckedStatementSyntax checkedStatementSyntax:
                    return(CheckedStatement.Print(checkedStatementSyntax));

                case ClassOrStructConstraintSyntax classOrStructConstraintSyntax:
                    return(ClassOrStructConstraint.Print(classOrStructConstraintSyntax));

                case CompilationUnitSyntax compilationUnitSyntax:
                    return(CompilationUnit.Print(compilationUnitSyntax));

                case ConditionalAccessExpressionSyntax conditionalAccessExpressionSyntax:
                    return(ConditionalAccessExpression.Print(conditionalAccessExpressionSyntax));

                case ConditionalExpressionSyntax conditionalExpressionSyntax:
                    return(ConditionalExpression.Print(conditionalExpressionSyntax));

                case ConstantPatternSyntax constantPatternSyntax:
                    return(ConstantPattern.Print(constantPatternSyntax));

                case ConstructorConstraintSyntax constructorConstraintSyntax:
                    return(ConstructorConstraint.Print(constructorConstraintSyntax));

                case ConstructorInitializerSyntax constructorInitializerSyntax:
                    return(ConstructorInitializer.Print(constructorInitializerSyntax));

                case ContinueStatementSyntax continueStatementSyntax:
                    return(ContinueStatement.Print(continueStatementSyntax));

                case DeclarationExpressionSyntax declarationExpressionSyntax:
                    return(DeclarationExpression.Print(declarationExpressionSyntax));

                case DeclarationPatternSyntax declarationPatternSyntax:
                    return(DeclarationPattern.Print(declarationPatternSyntax));

                case DefaultConstraintSyntax defaultConstraintSyntax:
                    return(DefaultConstraint.Print(defaultConstraintSyntax));

                case DefaultExpressionSyntax defaultExpressionSyntax:
                    return(DefaultExpression.Print(defaultExpressionSyntax));

                case DefaultSwitchLabelSyntax defaultSwitchLabelSyntax:
                    return(DefaultSwitchLabel.Print(defaultSwitchLabelSyntax));

                case DelegateDeclarationSyntax delegateDeclarationSyntax:
                    return(DelegateDeclaration.Print(delegateDeclarationSyntax));

                case DiscardDesignationSyntax discardDesignationSyntax:
                    return(DiscardDesignation.Print(discardDesignationSyntax));

                case DiscardPatternSyntax discardPatternSyntax:
                    return(DiscardPattern.Print(discardPatternSyntax));

                case DoStatementSyntax doStatementSyntax:
                    return(DoStatement.Print(doStatementSyntax));

                case ElementAccessExpressionSyntax elementAccessExpressionSyntax:
                    return(ElementAccessExpression.Print(elementAccessExpressionSyntax));

                case ElementBindingExpressionSyntax elementBindingExpressionSyntax:
                    return(ElementBindingExpression.Print(elementBindingExpressionSyntax));

                case ElseClauseSyntax elseClauseSyntax:
                    return(ElseClause.Print(elseClauseSyntax));

                case EmptyStatementSyntax emptyStatementSyntax:
                    return(EmptyStatement.Print(emptyStatementSyntax));

                case EnumMemberDeclarationSyntax enumMemberDeclarationSyntax:
                    return(EnumMemberDeclaration.Print(enumMemberDeclarationSyntax));

                case EqualsValueClauseSyntax equalsValueClauseSyntax:
                    return(EqualsValueClause.Print(equalsValueClauseSyntax));

                case ExpressionStatementSyntax expressionStatementSyntax:
                    return(ExpressionStatement.Print(expressionStatementSyntax));

                case ExternAliasDirectiveSyntax externAliasDirectiveSyntax:
                    return(ExternAliasDirective.Print(externAliasDirectiveSyntax));

                case FinallyClauseSyntax finallyClauseSyntax:
                    return(FinallyClause.Print(finallyClauseSyntax));

                case FixedStatementSyntax fixedStatementSyntax:
                    return(FixedStatement.Print(fixedStatementSyntax));

                case ForEachStatementSyntax forEachStatementSyntax:
                    return(ForEachStatement.Print(forEachStatementSyntax));

                case ForEachVariableStatementSyntax forEachVariableStatementSyntax:
                    return(ForEachVariableStatement.Print(forEachVariableStatementSyntax));

                case ForStatementSyntax forStatementSyntax:
                    return(ForStatement.Print(forStatementSyntax));

                case FromClauseSyntax fromClauseSyntax:
                    return(FromClause.Print(fromClauseSyntax));

                case FunctionPointerTypeSyntax functionPointerTypeSyntax:
                    return(FunctionPointerType.Print(functionPointerTypeSyntax));

                case GenericNameSyntax genericNameSyntax:
                    return(GenericName.Print(genericNameSyntax));

                case GlobalStatementSyntax globalStatementSyntax:
                    return(GlobalStatement.Print(globalStatementSyntax));

                case GotoStatementSyntax gotoStatementSyntax:
                    return(GotoStatement.Print(gotoStatementSyntax));

                case GroupClauseSyntax groupClauseSyntax:
                    return(GroupClause.Print(groupClauseSyntax));

                case IdentifierNameSyntax identifierNameSyntax:
                    return(IdentifierName.Print(identifierNameSyntax));

                case IfStatementSyntax ifStatementSyntax:
                    return(IfStatement.Print(ifStatementSyntax));

                case ImplicitArrayCreationExpressionSyntax implicitArrayCreationExpressionSyntax:
                    return(ImplicitArrayCreationExpression.Print(
                               implicitArrayCreationExpressionSyntax
                               ));

                case ImplicitElementAccessSyntax implicitElementAccessSyntax:
                    return(ImplicitElementAccess.Print(implicitElementAccessSyntax));

                case ImplicitObjectCreationExpressionSyntax implicitObjectCreationExpressionSyntax:
                    return(ImplicitObjectCreationExpression.Print(
                               implicitObjectCreationExpressionSyntax
                               ));

                case ImplicitStackAllocArrayCreationExpressionSyntax implicitStackAllocArrayCreationExpressionSyntax:
                    return(ImplicitStackAllocArrayCreationExpression.Print(
                               implicitStackAllocArrayCreationExpressionSyntax
                               ));

                case IncompleteMemberSyntax incompleteMemberSyntax:
                    return(IncompleteMember.Print(incompleteMemberSyntax));

                case InitializerExpressionSyntax initializerExpressionSyntax:
                    return(InitializerExpression.Print(initializerExpressionSyntax));

                case InterpolatedStringExpressionSyntax interpolatedStringExpressionSyntax:
                    return(InterpolatedStringExpression.Print(
                               interpolatedStringExpressionSyntax
                               ));

                case InterpolatedStringTextSyntax interpolatedStringTextSyntax:
                    return(InterpolatedStringText.Print(interpolatedStringTextSyntax));

                case InterpolationSyntax interpolationSyntax:
                    return(Interpolation.Print(interpolationSyntax));

                case InvocationExpressionSyntax invocationExpressionSyntax:
                    return(InvocationExpression.Print(invocationExpressionSyntax));

                case IsPatternExpressionSyntax isPatternExpressionSyntax:
                    return(IsPatternExpression.Print(isPatternExpressionSyntax));

                case JoinClauseSyntax joinClauseSyntax:
                    return(JoinClause.Print(joinClauseSyntax));

                case LabeledStatementSyntax labeledStatementSyntax:
                    return(LabeledStatement.Print(labeledStatementSyntax));

                case LetClauseSyntax letClauseSyntax:
                    return(LetClause.Print(letClauseSyntax));

                case LiteralExpressionSyntax literalExpressionSyntax:
                    return(LiteralExpression.Print(literalExpressionSyntax));

                case LocalDeclarationStatementSyntax localDeclarationStatementSyntax:
                    return(LocalDeclarationStatement.Print(localDeclarationStatementSyntax));

                case LocalFunctionStatementSyntax localFunctionStatementSyntax:
                    return(LocalFunctionStatement.Print(localFunctionStatementSyntax));

                case LockStatementSyntax lockStatementSyntax:
                    return(LockStatement.Print(lockStatementSyntax));

                case MakeRefExpressionSyntax makeRefExpressionSyntax:
                    return(MakeRefExpression.Print(makeRefExpressionSyntax));

                case MemberAccessExpressionSyntax memberAccessExpressionSyntax:
                    return(MemberAccessExpression.Print(memberAccessExpressionSyntax));

                case MemberBindingExpressionSyntax memberBindingExpressionSyntax:
                    return(MemberBindingExpression.Print(memberBindingExpressionSyntax));

                case NameColonSyntax nameColonSyntax:
                    return(NameColon.Print(nameColonSyntax));

                case NameEqualsSyntax nameEqualsSyntax:
                    return(NameEquals.Print(nameEqualsSyntax));

                case NamespaceDeclarationSyntax namespaceDeclarationSyntax:
                    return(NamespaceDeclaration.Print(namespaceDeclarationSyntax));

                case NullableTypeSyntax nullableTypeSyntax:
                    return(NullableType.Print(nullableTypeSyntax));

                case ObjectCreationExpressionSyntax objectCreationExpressionSyntax:
                    return(ObjectCreationExpression.Print(objectCreationExpressionSyntax));

                case OmittedArraySizeExpressionSyntax omittedArraySizeExpressionSyntax:
                    return(OmittedArraySizeExpression.Print(omittedArraySizeExpressionSyntax));

                case OmittedTypeArgumentSyntax omittedTypeArgumentSyntax:
                    return(OmittedTypeArgument.Print(omittedTypeArgumentSyntax));

                case OrderByClauseSyntax orderByClauseSyntax:
                    return(OrderByClause.Print(orderByClauseSyntax));

                case ParameterListSyntax parameterListSyntax:
                    return(ParameterList.Print(parameterListSyntax));

                case ParameterSyntax parameterSyntax:
                    return(Parameter.Print(parameterSyntax));

                case ParenthesizedExpressionSyntax parenthesizedExpressionSyntax:
                    return(ParenthesizedExpression.Print(parenthesizedExpressionSyntax));

                case ParenthesizedLambdaExpressionSyntax parenthesizedLambdaExpressionSyntax:
                    return(ParenthesizedLambdaExpression.Print(
                               parenthesizedLambdaExpressionSyntax
                               ));

                case ParenthesizedPatternSyntax parenthesizedPatternSyntax:
                    return(ParenthesizedPattern.Print(parenthesizedPatternSyntax));

                case ParenthesizedVariableDesignationSyntax parenthesizedVariableDesignationSyntax:
                    return(ParenthesizedVariableDesignation.Print(
                               parenthesizedVariableDesignationSyntax
                               ));

                case PointerTypeSyntax pointerTypeSyntax:
                    return(PointerType.Print(pointerTypeSyntax));

                case PostfixUnaryExpressionSyntax postfixUnaryExpressionSyntax:
                    return(PostfixUnaryExpression.Print(postfixUnaryExpressionSyntax));

                case PredefinedTypeSyntax predefinedTypeSyntax:
                    return(PredefinedType.Print(predefinedTypeSyntax));

                case PrefixUnaryExpressionSyntax prefixUnaryExpressionSyntax:
                    return(PrefixUnaryExpression.Print(prefixUnaryExpressionSyntax));

                case PrimaryConstructorBaseTypeSyntax primaryConstructorBaseTypeSyntax:
                    return(PrimaryConstructorBaseType.Print(primaryConstructorBaseTypeSyntax));

                case QualifiedNameSyntax qualifiedNameSyntax:
                    return(QualifiedName.Print(qualifiedNameSyntax));

                case QueryBodySyntax queryBodySyntax:
                    return(QueryBody.Print(queryBodySyntax));

                case QueryContinuationSyntax queryContinuationSyntax:
                    return(QueryContinuation.Print(queryContinuationSyntax));

                case QueryExpressionSyntax queryExpressionSyntax:
                    return(QueryExpression.Print(queryExpressionSyntax));

                case RangeExpressionSyntax rangeExpressionSyntax:
                    return(RangeExpression.Print(rangeExpressionSyntax));

                case RecursivePatternSyntax recursivePatternSyntax:
                    return(RecursivePattern.Print(recursivePatternSyntax));

                case RefExpressionSyntax refExpressionSyntax:
                    return(RefExpression.Print(refExpressionSyntax));

                case RefTypeExpressionSyntax refTypeExpressionSyntax:
                    return(RefTypeExpression.Print(refTypeExpressionSyntax));

                case RefTypeSyntax refTypeSyntax:
                    return(RefType.Print(refTypeSyntax));

                case RefValueExpressionSyntax refValueExpressionSyntax:
                    return(RefValueExpression.Print(refValueExpressionSyntax));

                case RelationalPatternSyntax relationalPatternSyntax:
                    return(RelationalPattern.Print(relationalPatternSyntax));

                case ReturnStatementSyntax returnStatementSyntax:
                    return(ReturnStatement.Print(returnStatementSyntax));

                case SelectClauseSyntax selectClauseSyntax:
                    return(SelectClause.Print(selectClauseSyntax));

                case SimpleBaseTypeSyntax simpleBaseTypeSyntax:
                    return(SimpleBaseType.Print(simpleBaseTypeSyntax));

                case SimpleLambdaExpressionSyntax simpleLambdaExpressionSyntax:
                    return(SimpleLambdaExpression.Print(simpleLambdaExpressionSyntax));

                case SingleVariableDesignationSyntax singleVariableDesignationSyntax:
                    return(SingleVariableDesignation.Print(singleVariableDesignationSyntax));

                case SizeOfExpressionSyntax sizeOfExpressionSyntax:
                    return(SizeOfExpression.Print(sizeOfExpressionSyntax));

                case StackAllocArrayCreationExpressionSyntax stackAllocArrayCreationExpressionSyntax:
                    return(StackAllocArrayCreationExpression.Print(
                               stackAllocArrayCreationExpressionSyntax
                               ));

                case SwitchExpressionSyntax switchExpressionSyntax:
                    return(SwitchExpression.Print(switchExpressionSyntax));

                case SwitchSectionSyntax switchSectionSyntax:
                    return(SwitchSection.Print(switchSectionSyntax));

                case SwitchStatementSyntax switchStatementSyntax:
                    return(SwitchStatement.Print(switchStatementSyntax));

                case ThisExpressionSyntax thisExpressionSyntax:
                    return(ThisExpression.Print(thisExpressionSyntax));

                case ThrowExpressionSyntax throwExpressionSyntax:
                    return(ThrowExpression.Print(throwExpressionSyntax));

                case ThrowStatementSyntax throwStatementSyntax:
                    return(ThrowStatement.Print(throwStatementSyntax));

                case TryStatementSyntax tryStatementSyntax:
                    return(TryStatement.Print(tryStatementSyntax));

                case TupleElementSyntax tupleElementSyntax:
                    return(TupleElement.Print(tupleElementSyntax));

                case TupleExpressionSyntax tupleExpressionSyntax:
                    return(TupleExpression.Print(tupleExpressionSyntax));

                case TupleTypeSyntax tupleTypeSyntax:
                    return(TupleType.Print(tupleTypeSyntax));

                case TypeArgumentListSyntax typeArgumentListSyntax:
                    return(TypeArgumentList.Print(typeArgumentListSyntax));

                case TypeConstraintSyntax typeConstraintSyntax:
                    return(TypeConstraint.Print(typeConstraintSyntax));

                case TypeOfExpressionSyntax typeOfExpressionSyntax:
                    return(TypeOfExpression.Print(typeOfExpressionSyntax));

                case TypeParameterConstraintClauseSyntax typeParameterConstraintClauseSyntax:
                    return(TypeParameterConstraintClause.Print(
                               typeParameterConstraintClauseSyntax
                               ));

                case TypeParameterListSyntax typeParameterListSyntax:
                    return(TypeParameterList.Print(typeParameterListSyntax));

                case TypeParameterSyntax typeParameterSyntax:
                    return(TypeParameter.Print(typeParameterSyntax));

                case TypePatternSyntax typePatternSyntax:
                    return(TypePattern.Print(typePatternSyntax));

                case UnaryPatternSyntax unaryPatternSyntax:
                    return(UnaryPattern.Print(unaryPatternSyntax));

                case UnsafeStatementSyntax unsafeStatementSyntax:
                    return(UnsafeStatement.Print(unsafeStatementSyntax));

                case UsingDirectiveSyntax usingDirectiveSyntax:
                    return(UsingDirective.Print(usingDirectiveSyntax));

                case UsingStatementSyntax usingStatementSyntax:
                    return(UsingStatement.Print(usingStatementSyntax));

                case VariableDeclarationSyntax variableDeclarationSyntax:
                    return(VariableDeclaration.Print(variableDeclarationSyntax));

                case VariableDeclaratorSyntax variableDeclaratorSyntax:
                    return(VariableDeclarator.Print(variableDeclaratorSyntax));

                case VarPatternSyntax varPatternSyntax:
                    return(VarPattern.Print(varPatternSyntax));

                case WhenClauseSyntax whenClauseSyntax:
                    return(WhenClause.Print(whenClauseSyntax));

                case WhereClauseSyntax whereClauseSyntax:
                    return(WhereClause.Print(whereClauseSyntax));

                case WhileStatementSyntax whileStatementSyntax:
                    return(WhileStatement.Print(whileStatementSyntax));

                case WithExpressionSyntax withExpressionSyntax:
                    return(WithExpression.Print(withExpressionSyntax));

                case YieldStatementSyntax yieldStatementSyntax:
                    return(YieldStatement.Print(yieldStatementSyntax));

                default:
                    throw new Exception("Can't handle " + syntaxNode.GetType().Name);
                }
            }

            finally
            {
                depth--;
            }
        }
示例#14
0
        // For the first assignment to a local variable in a block before a control statement is hit,
        // if the local variable is not mentioned previously, we turn this assignment into a local declaration.
        private void AddDeclarationsWithInitialValues(IEnumerable <ILocalDefinition> localVariables, BasicBlock block)
        {
            List <ILocalDefinition> topLevelLocals = new List <ILocalDefinition>(localVariables);
            List <ILocalDefinition> localsMet      = new List <ILocalDefinition>();

            for (int i = 0; i < block.Statements.Count; i++)
            {
                if (topLevelLocals.Count == 0)
                {
                    break;
                }
                IExpressionStatement expressionStatement = block.Statements[i] as IExpressionStatement;
                if (expressionStatement != null)
                {
                    IAssignment assignment = expressionStatement.Expression as IAssignment;
                    if (assignment != null)
                    {
                        ILocalDefinition localDef = assignment.Target.Definition as ILocalDefinition;
                        if (localDef != null && topLevelLocals.Contains(localDef) && !localsMet.Contains(localDef) && !this.declaredLocals.ContainsKey(localDef))
                        {
                            LocalDeclarationStatement localDecl = new LocalDeclarationStatement()
                            {
                                LocalVariable = localDef, InitialValue = assignment.Source, Locations = new List <ILocation>(expressionStatement.Locations),
                            };
                            this.declaredLocals.Add(localDef, true);
                            block.Statements[i] = localDecl;
                            topLevelLocals.Remove(localDef);
                            localsMet.Add(localDef);
                        }
                    }
                }
                LocalFinder finder = new LocalFinder();
                finder.Traverse(block.Statements[i]);
                foreach (ILocalDefinition local in finder.FoundLocals)
                {
                    if (!localsMet.Contains(local))
                    {
                        localsMet.Add(local);
                    }
                }
                //Once we see a statement that can transfer control somewhere else, we
                //no longer know that any subsequent assignment dominates all references
                //and hence cannot postpone adding the declaration until we can unify it with the assignment.
                IGotoStatement gotoStatement = block.Statements[i] as IGotoStatement;
                if (gotoStatement != null)
                {
                    break;
                }
                IConditionalStatement conditionalStatement = block.Statements[i] as IConditionalStatement;
                if (conditionalStatement != null)
                {
                    break;
                }
                ISwitchStatement switchStatement = block.Statements[i] as ISwitchStatement;
                if (switchStatement != null)
                {
                    break;
                }
                IForEachStatement foreachStatement = block.Statements[i] as IForEachStatement;
                if (foreachStatement != null)
                {
                    break;
                }
                IForStatement forStatement = block.Statements[i] as IForStatement;
                if (forStatement != null)
                {
                    break;
                }
                ITryCatchFinallyStatement tryStatement = block.Statements[i] as ITryCatchFinallyStatement;
                if (tryStatement != null)
                {
                    break;
                }
            }
        }
示例#15
0
        public override void RewriteChildren(MethodDefinition methodDefinition)
        {
            var methodContract = contractProvider.GetMethodContractFor(methodDefinition);

            if (methodContract == null)
            {
                return;
            }
            var sourceMethodBody = methodDefinition.Body as ISourceMethodBody;

            if (sourceMethodBody == null)
            {
                return;
            }

            var newStatements = new List <IStatement>();

            var existingStatements = new List <IStatement>(sourceMethodBody.Block.Statements);

            existingStatements = Rewrite(existingStatements);

            // keep the call to the base constructor at the top
            if (methodDefinition.IsConstructor && existingStatements.Count > 0)
            {
                newStatements.Add(existingStatements[0]);
                existingStatements.RemoveAt(0);
            }


            /* if the query returns a value, instead of copying the postconditions at the end of each
             * single return in the code, we assign the value at that point to a local variable and jump
             * to the beginning of the postcondition block.
             */

            // add a new local variable to store the value at return
            LocalDeclarationStatement retLocal = null;

            if (TypeHelper.GetTypeName(methodDefinition.Type) != TypeHelper.GetTypeName(host.PlatformType.SystemVoid))
            {
                retLocal = new LocalDeclarationStatement
                {
                    LocalVariable = new LocalDefinition
                    {
                        Name = host.NameTable.GetNameFor("retLocal"),
                        Type = methodDefinition.Type
                    },
                    InitialValue = new CompileTimeConstant {
                        Type = methodDefinition.Type, Value = null
                    }
                };
                newStatements.Add(retLocal);
            }

            // add the preconditions as assumes
            foreach (var precondition in methodContract.Preconditions)
            {
                var methodCall = new MethodCall
                {
                    Arguments =
                        new List <IExpression>
                    {
                        Rewrite(precondition.Condition),
                        precondition.Description ?? new CompileTimeConstant {
                            Type = host.PlatformType.SystemString, Value = "Precondition"
                        }
                    },
                    IsStaticCall = true,
                    MethodToCall = AssumeReference,
                    Type         = systemVoid,
                    Locations    = new List <ILocation>(precondition.Locations)
                };
                var es = new ExpressionStatement
                {
                    Expression = methodCall
                };
                newStatements.Add(es);
            }

            // Add the invariant as a precondition as well
            var typeContract = contractProvider.GetTypeContractFor(methodDefinition.ContainingTypeDefinition);

            if (typeContract != null)
            {
                foreach (var inv in typeContract.Invariants)
                {
                    var methodCall = new MethodCall
                    {
                        Arguments =
                            new List <IExpression>
                        {
                            Rewrite(inv.Condition),
                            new CompileTimeConstant {
                                Value = "Type invariant", Type = host.PlatformType.SystemString
                            }
                        },
                        IsStaticCall = true,
                        MethodToCall = AssumeReference,
                        Type         = systemVoid,
                        Locations    = new List <ILocation>(inv.Locations)
                    };
                    var es = new ExpressionStatement
                    {
                        Expression = methodCall
                    };
                    newStatements.Add(es);
                }
            }

            // the dummy statement is going to indicate the beginning of the postcondition block
            var dummyPostconditionStatement = new LabeledStatement
            {
                Label     = host.NameTable.GetNameFor("dummyPostconditionStatement"),
                Statement = new EmptyStatement()
            };

            var retRewriter = new ReturnRewriter(host, dummyPostconditionStatement, retLocal);

            //replace (nested) ReturnStatements with the GoTo to a single return at the end
            newStatements.AddRange(existingStatements.Select(stmt => retRewriter.Rewrite(stmt)));

            // now, that all the existing statements were added it is time for the postcondition block
            newStatements.Add(dummyPostconditionStatement);

            // Add assume statements for each postcondition that predicates ONLY about parameters (ie. not about the instance)
            var contractDependencyAnalyzer = new CciContractDependenciesAnalyzer(contractProvider);

            foreach (var postcondition in methodContract.Postconditions)
            {
                if (contractDependencyAnalyzer.PredicatesAboutInstance(postcondition) ||
                    !contractDependencyAnalyzer.PredicatesAboutParameter(postcondition))
                {
                    continue;
                }

                var methodCall = new MethodCall
                {
                    Arguments =
                        new List <IExpression>
                    {
                        Rewrite(postcondition.Condition),
                        new CompileTimeConstant {
                            Type = host.PlatformType.SystemString, Value = "Conditions over parameters are assumed satisfiable"
                        }
                    },
                    IsStaticCall = true,
                    MethodToCall = AssumeReference,
                    Type         = systemVoid,
                    Locations    = new List <ILocation>(postcondition.Locations)
                };
                var es = new ExpressionStatement
                {
                    Expression = methodCall
                };
                newStatements.Add(es);
            }

            // the postcondition block. Add each postcondition as an assert
            foreach (var postcondition in methodContract.Postconditions)
            {
                var methodCall = new MethodCall
                {
                    Arguments =
                        new List <IExpression>
                    {
                        Rewrite(postcondition.Condition),
                        postcondition.Description ?? new CompileTimeConstant {
                            Type = host.PlatformType.SystemString, Value = "Postcondition"
                        }
                    },
                    IsStaticCall = true,
                    MethodToCall = AssertReference,
                    Type         = systemVoid,
                    Locations    = new List <ILocation>(postcondition.Locations)
                };
                var es = new ExpressionStatement
                {
                    Expression = methodCall
                };
                newStatements.Add(es);
            }

            // add the invariant as a postcondition as well
            if (typeContract != null)
            {
                foreach (var inv in typeContract.Invariants)
                {
                    var methodCall = new MethodCall
                    {
                        Arguments =
                            new List <IExpression>
                        {
                            Rewrite(inv.Condition),
                            new CompileTimeConstant {
                                Value = "Type invariant", Type = host.PlatformType.SystemString
                            }
                        },
                        IsStaticCall = true,
                        MethodToCall = AssertReference,
                        Type         = systemVoid,
                        Locations    = new List <ILocation>(inv.Locations)
                    };
                    var es = new ExpressionStatement
                    {
                        Expression = methodCall
                    };
                    newStatements.Add(es);
                }
            }

            IReturnStatement returnStatement;

            if (TypeHelper.GetTypeName(methodDefinition.Type) != TypeHelper.GetTypeName(host.PlatformType.SystemVoid))
            {
                // If the method is not void, the return statement have to include the local variable
                returnStatement = new ReturnStatement
                {
                    Expression = new BoundExpression {
                        Definition = retLocal.LocalVariable, Instance = null, Type = retLocal.LocalVariable.Type
                    }
                };
            }
            else
            {
                returnStatement = new ReturnStatement();
            }
            newStatements.Add(returnStatement);

            var newSourceMethodBody = new SourceMethodBody(host, sourceLocationProvider)
            {
                Block = new BlockStatement
                {
                    Statements = newStatements
                },
                IsNormalized     = false,
                LocalsAreZeroed  = sourceMethodBody.LocalsAreZeroed,
                MethodDefinition = methodDefinition
            };

            methodDefinition.Body = newSourceMethodBody;
        }
示例#16
0
        public override void ExtendDeclaration(IDeclarationModel declaration, CompilationModel model)
        {
            // this only applies to methods
            var methodDecl = declaration as MethodDeclaration;

            if (methodDecl == null || methodDecl.Container == null)
            {
                return;
            }

            if (!methodDecl.Definition.Symbol.IsExtensionMethod)
            {
                throw new CompilationException("The ScriptMixin attribute can only be applied to extension methods.", declaration);
            }

            // remove the function from the container
            methodDecl.Container.RemoveMember(methodDecl);

            // get the extension target info
            var extTarget = methodDecl.Parameters[0];
            var extType   = extTarget.Definition.Type;

            // rewrite first param as a local declaration to this context
            var thisDecl = new LocalDeclarationStatement {
                VariableDeclaration = new VariableDeclaration()
            };

            thisDecl.VariableDeclaration.Variables.Add(new VariableDeclarator
            {
                Definition = new LocalDefinition
                {
                    Name = extTarget.Name,
                    Type = extType
                },
                EqualsValueExpression = new LiteralExpression {
                    Text = "this"
                }
            });

            // add the declaration to the method body
            methodDecl.Body.Statements.Insert(0, thisDecl);

            // create a lambda using the method body.
            var lambdaExpression = new LambdaExpression();

            lambdaExpression.Body = methodDecl.Body;

            for (int i = 1; i < methodDecl.Parameters.Count; i++)
            {
                lambdaExpression.Parameters.Add(methodDecl.Parameters[i]);
            }

            // create a global statement to set the prototype value
            var target = extType.GetFullName() + ".prototype." + methodDecl.Definition.Name;

            model.GlobalStatements.Add(new ExpressionStatement
            {
                Expression = new BinaryExpression
                {
                    LeftExpression = new LiteralExpression {
                        Text = target
                    },
                    RightExpression = lambdaExpression,
                    Operator        = "="
                }
            });
        }
示例#17
0
        public override IStatement Rewrite(IForEachStatement forEachStatement)
        {
            ILocalDefinition foreachLocal;
            var key = forEachStatement.Collection.Type.InternedKey;

            ITypeReference   enumeratorType;
            IMethodReference getEnumerator;
            IMethodReference getCurrent;

            var gtir = forEachStatement.Collection.Type as IGenericTypeInstanceReference;

            if (gtir != null)
            {
                var            typeArguments         = gtir.GenericArguments;
                ITypeReference genericEnumeratorType = new Immutable.GenericTypeInstanceReference(this.host.PlatformType.SystemCollectionsGenericIEnumerator, typeArguments, this.host.InternFactory);
                ITypeReference genericEnumerableType = new Immutable.GenericTypeInstanceReference(this.host.PlatformType.SystemCollectionsGenericIEnumerable, typeArguments, this.host.InternFactory);
                enumeratorType = genericEnumeratorType;
                getEnumerator  = new SpecializedMethodReference()
                {
                    CallingConvention = CallingConvention.HasThis,
                    ContainingType    = genericEnumerableType,
                    InternFactory     = this.host.InternFactory,
                    Name                 = this.host.NameTable.GetNameFor("GetEnumerator"),
                    Parameters           = new List <IParameterTypeInformation>(),
                    Type                 = genericEnumeratorType,
                    UnspecializedVersion = new MethodReference()
                    {
                        CallingConvention = CallingConvention.HasThis,
                        ContainingType    = this.host.PlatformType.SystemCollectionsGenericIEnumerable,
                        InternFactory     = this.host.InternFactory,
                        Name       = this.host.NameTable.GetNameFor("GetEnumerator"),
                        Parameters = new List <IParameterTypeInformation>(),
                        Type       = this.host.PlatformType.SystemCollectionsGenericIEnumerator,
                    },
                };
                var getEnumerator2 = (IMethodReference)
                                     IteratorHelper.First(genericEnumerableType.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("GetEnumerator"), false));
                getEnumerator = getEnumerator2;
                getCurrent    = (IMethodReference)IteratorHelper.First(genericEnumeratorType.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("get_Current"), false));
            }
            else
            {
                enumeratorType = this.host.PlatformType.SystemCollectionsIEnumerator;
                getEnumerator  = new MethodReference()
                {
                    CallingConvention = CallingConvention.HasThis,
                    ContainingType    = enumeratorType,
                    InternFactory     = this.host.InternFactory,
                    Name       = this.host.NameTable.GetNameFor("GetEnumerator"),
                    Parameters = new List <IParameterTypeInformation>(),
                    Type       = this.host.PlatformType.SystemCollectionsIEnumerable,
                };
                getCurrent = new MethodReference()
                {
                    CallingConvention = CallingConvention.HasThis,
                    ContainingType    = enumeratorType,
                    InternFactory     = this.host.InternFactory,
                    Name       = this.host.NameTable.GetNameFor("get_Current"),
                    Parameters = new List <IParameterTypeInformation>(),
                    Type       = this.host.PlatformType.SystemObject,
                };
            }

            var initializer = new MethodCall()
            {
                Arguments     = new List <IExpression>(),
                IsStaticCall  = false,
                IsVirtualCall = true,
                MethodToCall  = getEnumerator,
                ThisArgument  = forEachStatement.Collection,
                Type          = enumeratorType,
            };
            IStatement initialization;

            if (!this.foreachLocals.TryGetValue(key, out foreachLocal))
            {
                foreachLocal = new LocalDefinition()
                {
                    Type = enumeratorType, Name = this.host.NameTable.GetNameFor("CS$5$" + this.foreachLocals.Count)
                };
                this.foreachLocals.Add(key, foreachLocal);
                initialization = new LocalDeclarationStatement()
                {
                    InitialValue  = initializer,
                    LocalVariable = foreachLocal,
                };
            }
            else
            {
                initialization = new ExpressionStatement()
                {
                    Expression = new Assignment()
                    {
                        Source = initializer,
                        Target = new TargetExpression()
                        {
                            Definition = foreachLocal,
                            Instance   = null,
                            Type       = foreachLocal.Type,
                        },
                        Type = foreachLocal.Type,
                    },
                };
            }

            var newStmts = new List <IStatement>();

            newStmts.Add(new ExpressionStatement()
            {
                Expression = new Assignment()
                {
                    Source = new MethodCall()
                    {
                        Arguments     = new List <IExpression>(),
                        IsStaticCall  = false,
                        IsVirtualCall = true,
                        MethodToCall  = getCurrent,
                        ThisArgument  = new BoundExpression()
                        {
                            Definition = foreachLocal,
                            Instance   = null,
                        },
                        Type = forEachStatement.Variable.Type,
                    },
                    Target = new TargetExpression()
                    {
                        Definition = forEachStatement.Variable,
                        Instance   = null,
                    },
                    Type = forEachStatement.Variable.Type,
                },
            });
            newStmts.Add(forEachStatement.Body);
            var newBody = new BlockStatement()
            {
                Statements = newStmts,
            };
            var result = new BlockStatement()
            {
                Statements = new List <IStatement>()
                {
                    initialization,
                    new TryCatchFinallyStatement()
                    {
                        TryBody = new BlockStatement()
                        {
                            Statements = new List <IStatement>()
                            {
                                new WhileDoStatement()
                                {
                                    Body      = newBody,
                                    Condition = new MethodCall()
                                    {
                                        Arguments     = new List <IExpression>(),
                                        IsStaticCall  = false,
                                        IsVirtualCall = true,
                                        MethodToCall  = moveNext,
                                        ThisArgument  = new BoundExpression()
                                        {
                                            Definition = foreachLocal,
                                            Instance   = null,
                                        },
                                        Type = this.host.PlatformType.SystemBoolean,
                                    },
                                },
                            },
                        },
                        FinallyBody = new BlockStatement()
                        {
                            Statements = new List <IStatement>()
                            {
                                new ConditionalStatement()
                                {
                                    Condition = new Equality()
                                    {
                                        LeftOperand = new BoundExpression()
                                        {
                                            Definition = foreachLocal, Instance = null, Type = foreachLocal.Type,
                                        },
                                        RightOperand = new CompileTimeConstant()
                                        {
                                            Type = foreachLocal.Type, Value = null,
                                        },
                                        Type = this.host.PlatformType.SystemBoolean,
                                    },
                                    FalseBranch = new EmptyStatement(),
                                    TrueBranch  = new ExpressionStatement()
                                    {
                                        Expression = new MethodCall()
                                        {
                                            Arguments     = new List <IExpression>(),
                                            IsStaticCall  = false,
                                            IsVirtualCall = true,
                                            MethodToCall  = this.disposeMethod,
                                            ThisArgument  = new BoundExpression()
                                            {
                                                Definition = foreachLocal,
                                                Instance   = null,
                                            },
                                            Type = this.host.PlatformType.SystemVoid,
                                        },
                                    },
                                },
                            },
                        },
                    },
                },
            };

            return(result);
        }