@@ -543,13 +543,27 @@ IEnumerable<Expression> VisitBlockBody(IList<Expression> exprs, bool shouldRetur
543543
544544 Expression VisitBlock ( BlockExpression node , bool shouldReturn )
545545 {
546+ var assignedVariables = new HashSet < ParameterExpression > ( node . Expressions
547+ . Where ( exp => exp . NodeType == ExpressionType . Assign )
548+ . Select ( exp => ( ( BinaryExpression ) exp ) . Left )
549+ . Where ( exp => exp . NodeType == ExpressionType . Parameter )
550+ . Select ( exp => ( ParameterExpression ) exp ) ) ;
551+
546552 var list = new List < ParameterExpression > ( ) ;
553+ var hasDeclaration = false ;
547554 foreach ( var variable in node . Variables )
548555 {
549- var arg = VisitNextLine ( Translate ( variable . Type ) + " " , variable , ";" ) ;
556+ Expression arg ;
557+ if ( assignedVariables . Contains ( variable ) )
558+ arg = VisitParameter ( variable , false ) ;
559+ else
560+ {
561+ arg = VisitNextLine ( Translate ( variable . Type ) + " " , variable , ";" ) ;
562+ hasDeclaration = true ;
563+ }
550564 list . Add ( ( ParameterExpression ) arg ) ;
551565 }
552- if ( node . Variables . Count > 0 )
566+ if ( hasDeclaration )
553567 WriteLine ( ) ;
554568
555569 var lines = VisitBlockBody ( node . Expressions , shouldReturn && node . Type != typeof ( void ) ) ;
@@ -664,7 +678,7 @@ protected override Expression VisitConstant(ConstantExpression node)
664678 if ( type . GetTypeInfo ( ) . IsPrimitive || type == typeof ( decimal ) )
665679 Write ( value . ToString ( ) ) ;
666680 else
667- Write ( "valueof(" , Translate ( type ) , ", \" " , value . ToString ( ) , " \" )") ;
681+ Write ( "valueof(" , Translate ( type ) , ")" ) ;
668682 }
669683
670684 if ( _document == null || CanEmitConstant ( value , node . Type ) )
@@ -811,7 +825,7 @@ protected override Expression VisitDynamic(DynamicExpression node)
811825 }
812826#endif
813827
814- IList < T > VisitArguments < T > ( string open , IList < T > args , Func < T , T > func , string end , bool wrap = false ) where T : class
828+ IList < T > VisitArguments < T > ( string open , IList < T > args , Func < T , T > func , string end , bool wrap = false , IList < string > prefix = null ) where T : class
815829 {
816830 Write ( open ) ;
817831 if ( wrap )
@@ -824,6 +838,8 @@ IList<T> VisitArguments<T>(string open, IList<T> args, Func<T, T> func, string e
824838 {
825839 if ( wrap )
826840 WriteLine ( ) ;
841+ if ( prefix != null )
842+ Write ( prefix [ i ] ) ;
827843 var arg = func ( args [ i ] ) ;
828844 changed |= arg != args [ i ] ;
829845 list . Add ( arg ) ;
@@ -1142,16 +1158,18 @@ protected override Expression VisitMethodCall(MethodCallExpression node)
11421158 if ( node . Method . DeclaringType != null )
11431159 Write ( "." ) ;
11441160 Write ( node . Method . Name ) ;
1161+ var prefix = node . Method . GetParameters ( )
1162+ . Select ( p => p . IsOut ? "out " : p . ParameterType . IsByRef ? "ref " : "" ) ;
11451163
11461164 if ( isExtension )
11471165 {
1148- var args = VisitArguments ( "(" , node . Arguments . Skip ( 1 ) . ToList ( ) , Visit , ")" ) ;
1166+ var args = VisitArguments ( "(" , node . Arguments . Skip ( 1 ) . ToList ( ) , Visit , ")" , prefix : prefix . Skip ( 1 ) . ToList ( ) ) ;
11491167 var newArgs = new [ ] { arg0 } . Concat ( args ) . ToList ( ) ;
11501168 return newArgs . SequenceEqual ( node . Arguments ) ? node : node . Update ( obj , newArgs ) ;
11511169 }
11521170 else
11531171 {
1154- var args = VisitArguments ( "(" , node . Arguments , Visit , ")" ) ;
1172+ var args = VisitArguments ( "(" , node . Arguments , Visit , ")" , prefix : prefix . ToList ( ) ) ;
11551173 return node . Update ( obj , args ) ;
11561174 }
11571175 }
@@ -1274,8 +1292,28 @@ protected override Expression VisitNewArray(NewArrayExpression node)
12741292
12751293 protected override Expression VisitParameter ( ParameterExpression node )
12761294 {
1295+ return VisitParameter ( node , true ) ;
1296+ }
1297+
1298+ HashSet < ParameterExpression > _pendingVariables ;
1299+ private Expression VisitParameter ( ParameterExpression node , bool write )
1300+ {
1301+ if ( _pendingVariables == null )
1302+ _pendingVariables = new HashSet < ParameterExpression > ( ) ;
1303+
12771304 var name = GetName ( node ) ;
1278- Write ( name ) ;
1305+ if ( write )
1306+ {
1307+ if ( _pendingVariables . Contains ( node ) )
1308+ {
1309+ Write ( Translate ( node . Type ) , " " , name ) ;
1310+ _pendingVariables . Remove ( node ) ;
1311+ }
1312+ else
1313+ Write ( name ) ;
1314+ }
1315+ else
1316+ _pendingVariables . Add ( node ) ;
12791317
12801318 if ( ! string . IsNullOrEmpty ( node . Name ) )
12811319 return node ;
@@ -1412,7 +1450,8 @@ protected override Expression VisitUnary(UnaryExpression node)
14121450 {
14131451 case ExpressionType . Convert :
14141452 case ExpressionType . ConvertChecked :
1415- Write ( "(" , Translate ( node . Type ) , ")" ) ;
1453+ if ( ! node . Type . IsAssignableFrom ( node . Operand . Type ) )
1454+ Write ( "(" , Translate ( node . Type ) , ")" ) ;
14161455 break ;
14171456
14181457 case ExpressionType . Throw :
0 commit comments