public override void OnExpressionInterpolationExpression(ExpressionInterpolationExpression node)
{
Type stringBuilderType = typeof(StringBuilder);
ConstructorInfo constructor = stringBuilderType.GetConstructor(Type.EmptyTypes);
ConstructorInfo constructorString = stringBuilderType.GetConstructor(new Type[] { typeof(string) });
MethodInfo appendObject = Methods.InstanceFunctionOf<StringBuilder, object, StringBuilder>(sb => sb.Append);
MethodInfo appendString = Methods.InstanceFunctionOf<StringBuilder, string, StringBuilder>(sb => sb.Append);
Expression arg0 = node.Expressions[0];
IType argType = arg0.ExpressionType;
/* if arg0 is a string, let's call StringBuilder constructor
* directly with the string */
if ( ( typeof(StringLiteralExpression) == arg0.GetType()
&& ((StringLiteralExpression) arg0).Value.Length > 0 )
|| ( typeof(StringLiteralExpression) != arg0.GetType()
&& TypeSystemServices.StringType == argType ) )
{
Visit(arg0);
PopType();
_il.Emit(OpCodes.Newobj, constructorString);
}
else
{
_il.Emit(OpCodes.Newobj, constructor);
arg0 = null; /* arg0 is not a string so we want it to be appended below */
}
string formatString;
foreach (Expression arg in node.Expressions)
{
/* we do not need to append literal string.Empty
* or arg0 if it has been handled by ctor */
if ( ( typeof(StringLiteralExpression) == arg.GetType()
&& ((StringLiteralExpression) arg).Value.Length == 0 )
|| arg == arg0 )
{
continue;
}
formatString = arg["formatString"] as string; //annotation
if (!string.IsNullOrEmpty(formatString))
_il.Emit(OpCodes.Ldstr, string.Format("{{0:{0}}}", formatString));
Visit(arg);
argType = PopType();
if (!string.IsNullOrEmpty(formatString))
{
EmitCastIfNeeded(TypeSystemServices.ObjectType, argType);
Call(StringFormat);
}
if (TypeSystemServices.StringType == argType || !string.IsNullOrEmpty(formatString))
{
Call(appendString);
}
else
{
EmitCastIfNeeded(TypeSystemServices.ObjectType, argType);
Call(appendObject);
}
}
Call(stringBuilderType.GetMethod("ToString", Type.EmptyTypes));
PushType(TypeSystemServices.StringType);
}