Пример #1
0
        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);
        }
Пример #2
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);
        }