Beispiel #1
0
        protected virtual void EmitCastExpression(Expression expression, AstType type, string method)
        {
            bool castToEnum   = this.Emitter.BridgeTypes.ToType(type).Kind == TypeKind.Enum;
            var  expressionrr = this.Emitter.Resolver.ResolveNode(expression, this.Emitter);
            bool enumCast     = expressionrr.Type.Kind == TypeKind.Enum;

            if (method != Bridge.Translator.Emitter.IS && (Helpers.IsIgnoreCast(type, this.Emitter) || castToEnum || enumCast))
            {
                expression.AcceptVisitor(this.Emitter);
                return;
            }

            if (method == Bridge.Translator.Emitter.IS && castToEnum)
            {
                this.Write("Bridge.hasValue(");
                expression.AcceptVisitor(this.Emitter);
                this.Write(")");
                return;
            }

            var typerr = this.Emitter.Resolver.ResolveNode(type, this.Emitter);

            if (expressionrr.Type.Equals(typerr.Type))
            {
                if (method == Bridge.Translator.Emitter.IS)
                {
                    this.WriteScript(true);
                }
                else
                {
                    expression.AcceptVisitor(this.Emitter);
                }

                return;
            }

            bool   isInlineCast;
            string castCode         = this.GetCastCode(expression, type, out isInlineCast);
            bool   isNullable       = NullableType.IsNullable(expressionrr.Type);
            bool   isResultNullable = NullableType.IsNullable(typerr.Type);

            if (isInlineCast)
            {
                if (isNullable)
                {
                    isNullable = !NullableType.GetUnderlyingType(expressionrr.Type).Equals(typerr.Type);
                }

                this.EmitInlineCast(expression, type, castCode, isNullable, isResultNullable);
                return;
            }

            if (method == Bridge.Translator.Emitter.CAST)
            {
                if (Helpers.IsIntegerType(typerr.Type, this.Emitter.Resolver))
                {
                    if (expressionrr.Type != null && Helpers.IsFloatType(expressionrr.Type, this.Emitter.Resolver))
                    {
                        this.Write("System.trunc(");
                        if (isNullable && !isResultNullable)
                        {
                            this.Write("System.Nullable.getValue(");
                        }
                        expression.AcceptVisitor(this.Emitter);
                        if (isNullable && !isResultNullable)
                        {
                            this.WriteCloseParentheses();
                        }
                        this.Write(")");

                        return;
                    }
                }

                if (ConversionBlock.IsUserDefinedConversion(this, this.CastExpression.Expression))
                {
                    expression.AcceptVisitor(this.Emitter);

                    return;
                }
            }

            var  simpleType = type as SimpleType;
            bool hasValue   = false;

            if (simpleType != null && simpleType.Identifier == "dynamic")
            {
                if (method == Bridge.Translator.Emitter.CAST || method == Bridge.Translator.Emitter.AS)
                {
                    expression.AcceptVisitor(this.Emitter);
                    return;
                }
                else if (method == Bridge.Translator.Emitter.IS)
                {
                    hasValue = true;
                    method   = "hasValue";
                }
            }

            this.Write(Bridge.Translator.Emitter.ROOT);
            this.WriteDot();
            this.Write(method);
            this.WriteOpenParentheses();
            if (isNullable && !isResultNullable)
            {
                this.Write("System.Nullable.getValue(");
            }
            expression.AcceptVisitor(this.Emitter);
            if (isNullable && !isResultNullable)
            {
                this.WriteCloseParentheses();
            }

            if (!hasValue)
            {
                this.WriteComma();

                if (castCode != null)
                {
                    this.Write(castCode);
                }
                else
                {
                    this.EmitCastType(type);
                }
            }

            if (isResultNullable && method != Bridge.Translator.Emitter.IS)
            {
                this.WriteComma();
                this.WriteScript(true);
            }

            this.WriteCloseParentheses();
        }