private static int DoConversion(ConversionBlock block, Expression expression, Conversion conversion, IType expectedType, int level, ResolveResult rr, bool ignoreConversionResolveResult = false) { if (ConversionBlock.expressionIgnoreUserDefine.Contains(expression) && conversion.IsUserDefined) { expectedType = conversion.Method.Parameters.First().Type; } if (block.Emitter.IsAssignment) { return(level); } if (expression is ParenthesizedExpression && ((ParenthesizedExpression)expression).Expression is CastExpression) { return(level); } if (conversion.IsUserDefined && expression.Parent is CastExpression && ((CastExpression)expression.Parent).Expression == expression) { var parentConversion = block.Emitter.Resolver.Resolver.GetConversion((CastExpression)expression.Parent); if (!parentConversion.IsUserDefined || parentConversion.Method.Equals(conversion.Method)) { return(level); } } if (rr is ConstantResolveResult && expression is CastExpression && !conversion.IsUserDefined) { return(level); } var convrr = rr as ConversionResolveResult; if (convrr != null && convrr.Input is ConstantResolveResult && !convrr.Conversion.IsUserDefined) { return(level); } string afterUserDefined = ""; if (convrr != null && !conversion.IsUserDefined && !ignoreConversionResolveResult) { if (expectedType != convrr.Type) { if (expression.Parent is CastExpression && ((CastExpression)expression.Parent).Expression == expression) { var parentExpectedType = block.Emitter.Resolver.Resolver.GetExpectedType((CastExpression)expression.Parent); var parentrr = block.Emitter.Resolver.ResolveNode(expression.Parent, block.Emitter) as ConversionResolveResult; if (parentrr != null && parentrr.Type != expectedType || parentrr == null && expectedType != parentExpectedType) { level = ConversionBlock.DoConversion(block, expression, conversion, expectedType, level, rr, true); afterUserDefined = block.AfterOutput; block.AfterOutput = ""; } } else { level = ConversionBlock.DoConversion(block, expression, conversion, expectedType, level, rr, true); afterUserDefined = block.AfterOutput; block.AfterOutput = ""; } } conversion = convrr.Conversion; rr = convrr.Input; expectedType = convrr.Type; } var isNumLifted = conversion != null && conversion.IsImplicit && conversion.IsLifted && conversion.IsNumericConversion && !(expression is BinaryOperatorExpression); bool skipUserConversion = conversion == null || (!conversion.IsUserDefined && (Helpers.IsDecimalType(expectedType, block.Emitter.Resolver) || Helpers.Is64Type(expectedType, block.Emitter.Resolver) || conversion.IsIdentityConversion || isNumLifted)); if (!skipUserConversion && conversion.IsUserDefined && (expression is BinaryOperatorExpression || expression is UnaryOperatorExpression || expression.Parent is AssignmentExpression)) { level = ConversionBlock.CheckUserDefinedConversion(block, expression, conversion, level, rr, expectedType); if (conversion.IsUserDefined && block.DisableEmitConversionExpression) { return(level); } afterUserDefined = block.AfterOutput + afterUserDefined; block.AfterOutput = ""; } if (!(conversion.IsExplicit && conversion.IsNumericConversion)) { if (ConversionBlock.CheckDecimalConversion(block, expression, rr, expectedType, conversion, ignoreConversionResolveResult)) { block.AfterOutput += ")"; } } if (Helpers.IsDecimalType(expectedType, block.Emitter.Resolver) && !conversion.IsUserDefined) { var s = block.AfterOutput; block.AfterOutput = ""; if (!((expression.Parent is CastExpression) && !(expression is CastExpression))) { ConversionBlock.CheckNumericConversion(block, expression, rr, expectedType, conversion); } block.AfterOutput = block.AfterOutput + s + afterUserDefined; return(level); } if (!(conversion.IsExplicit && conversion.IsNumericConversion)) { if (ConversionBlock.CheckLongConversion(block, expression, rr, expectedType, conversion, ignoreConversionResolveResult)) { block.AfterOutput += ")"; } } if (Helpers.Is64Type(expectedType, block.Emitter.Resolver) && !conversion.IsUserDefined) { var s = block.AfterOutput; block.AfterOutput = ""; if (!((expression.Parent is CastExpression) && !(expression is CastExpression))) { ConversionBlock.CheckNumericConversion(block, expression, rr, expectedType, conversion); } block.AfterOutput = block.AfterOutput + s + afterUserDefined; return(level); } if (!((expression.Parent is CastExpression) && !(expression is CastExpression))) { ConversionBlock.CheckNumericConversion(block, expression, rr, expectedType, conversion); } if (conversion.IsIdentityConversion) { block.AfterOutput = block.AfterOutput + afterUserDefined; return(level); } if (isNumLifted && !conversion.IsUserDefined) { block.AfterOutput = block.AfterOutput + afterUserDefined; return(level); } bool isLifted = conversion.IsLifted && !isNumLifted && !(block is CastBlock) && !Helpers.IsDecimalType(expectedType, block.Emitter.Resolver) && !Helpers.Is64Type(expectedType, block.Emitter.Resolver) && !NullableType.IsNullable(expectedType); if (isLifted) { block.Write(JS.Types.SYSTEM_NULLABLE + ".getValue("); block.AfterOutput += ")"; } if (conversion.IsUserDefined && !(expression is BinaryOperatorExpression || expression is UnaryOperatorExpression || expression.Parent is AssignmentExpression)) { level = ConversionBlock.CheckUserDefinedConversion(block, expression, conversion, level, rr, expectedType); } block.AfterOutput = block.AfterOutput + afterUserDefined; return(level); }