public static int CheckConversion(ConversionBlock block, Expression expression) { try { var rr = block.Emitter.Resolver.ResolveNode(expression, block.Emitter); var conversion = block.Emitter.Resolver.Resolver.GetConversion(expression); var expectedType = block.Emitter.Resolver.Resolver.GetExpectedType(expression); int level = 0; if (block.Emitter.IsAssignment) { return(level); } /*if (expression is ParenthesizedExpression && expression.Parent is CastExpression) * { * return level; * }*/ if (conversion.IsUserDefined && expression.Parent is CastExpression && ((CastExpression)expression.Parent).Expression == expression) { 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); } if (convrr != null && !conversion.IsUserDefined) { conversion = convrr.Conversion; rr = convrr.Input; expectedType = convrr.Type; } if (!((expression.Parent is CastExpression) && !(expression is CastExpression))) { CheckNumericConversion(block, expression, rr, expectedType, conversion); } if (!(conversion.IsExplicit && conversion.IsNumericConversion)) { level = ConversionBlock.CheckDecimalConversion(block, expression, rr, expectedType, conversion) ? (level + 1) : level; } if (Helpers.IsDecimalType(expectedType, block.Emitter.Resolver) && !conversion.IsUserDefined) { return(level); } if (!(conversion.IsExplicit && conversion.IsNumericConversion)) { level = ConversionBlock.CheckLongConversion(block, expression, rr, expectedType, conversion) ? (level + 1) : level; } if (Helpers.Is64Type(expectedType, block.Emitter.Resolver) && !conversion.IsUserDefined) { return(level); } if (conversion == null) { return(level); } if (conversion.IsIdentityConversion) { return(level); } var isNumLifted = conversion.IsImplicit && conversion.IsLifted && conversion.IsNumericConversion && !(expression is BinaryOperatorExpression); if (isNumLifted && !conversion.IsUserDefined) { 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) { level++; block.Write("Bridge.Nullable.getValue("); } if (conversion.IsUserDefined) { var method = conversion.Method; string inline = block.Emitter.GetInline(method); if (conversion.IsExplicit && !string.IsNullOrWhiteSpace(inline)) { // Still returns true if Nullable.lift( was written. return(level); } if (!string.IsNullOrWhiteSpace(inline)) { if (expression is InvocationExpression) { new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, (InvocationExpression)expression), inline).Emit(); } else if (expression is ObjectCreateExpression) { new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, (ObjectCreateExpression)expression), inline).Emit(); } else if (expression is UnaryOperatorExpression) { var unaryExpression = (UnaryOperatorExpression)expression; var resolveOperator = block.Emitter.Resolver.ResolveNode(unaryExpression, block.Emitter); OperatorResolveResult orr = resolveOperator as OperatorResolveResult; new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, unaryExpression, orr, method), inline).Emit(); } else if (expression is BinaryOperatorExpression) { var binaryExpression = (BinaryOperatorExpression)expression; var resolveOperator = block.Emitter.Resolver.ResolveNode(binaryExpression, block.Emitter); OperatorResolveResult orr = resolveOperator as OperatorResolveResult; new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, binaryExpression, orr, method), inline).Emit(); } else { new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, expression), inline).Emit(); } block.DisableEmitConversionExpression = true; // Still returns true if Nullable.lift( was written. return(level); } else { if (method.DeclaringTypeDefinition != null && block.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition)) { // Still returns true if Nullable.lift( was written. return(level); } block.Write(BridgeTypes.ToJsName(method.DeclaringType, block.Emitter)); block.WriteDot(); block.Write(OverloadsCollection.Create(block.Emitter, method).GetOverloadName()); } if (isLifted) { block.WriteComma(); } else { block.WriteOpenParentheses(); level++; } var arg = method.Parameters[0]; if (Helpers.IsDecimalType(arg.Type, block.Emitter.Resolver, arg.IsParams) && !Helpers.IsDecimalType(rr.Type, block.Emitter.Resolver) && !expression.IsNull) { block.Write("Bridge.Decimal"); if (NullableType.IsNullable(arg.Type) && ConversionBlock.ShouldBeLifted(expression)) { block.Write(".lift"); } if (expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(level); } block.WriteOpenParentheses(); level++; } if (Helpers.Is64Type(arg.Type, block.Emitter.Resolver, arg.IsParams) && !Helpers.Is64Type(rr.Type, block.Emitter.Resolver) && !expression.IsNull) { var isUint = Helpers.IsULongType(arg.Type, block.Emitter.Resolver, arg.IsParams); block.Write("Bridge." + (isUint ? "ULong" : "Long")); if (NullableType.IsNullable(arg.Type) && ConversionBlock.ShouldBeLifted(expression)) { block.Write(".lift"); } if (expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(level); } block.WriteOpenParentheses(); level++; } return(level); } // Still returns true if Nullable.lift( was written. return(level); } catch { } return(0); }
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); }