/// <summary>
        /// create conversion code
        /// </summary>
        /// <param name="sourceType"></param>
        /// <param name="sourceCode"></param>
        /// <param name="targetType"></param>
        /// <returns>conversion code converting sourceCode to the targetType</returns>
        public static CodeExpression GetConversionCode(RaisDataType sourceType, CodeExpression sourceCode, RaisDataType targetType, CodeStatementCollection supprtStatements)
        {
            CodeExpression codeRet;

            if (sourceType.IsSameType(targetType))
            {
                return(sourceCode);
            }
            if (targetType.IsLibType || sourceType.IsLibType)
            {
                if (MathNode.GetTypeConversion != null)
                {
                    return(MathNode.GetTypeConversion(targetType.Type, sourceCode, sourceType.Type, supprtStatements));
                }
                return(CastOrConvert(sourceCode, sourceType.Type, targetType.Type, supprtStatements));
            }
            string srcType = sourceType.DevType.TypeString;
            string tgtType = targetType.DevType.TypeString;

            if (srcType.StartsWith(tgtType))
            {
                return(sourceCode);
            }
            if (tgtType.StartsWith(srcType))
            {
                return(new CodeCastExpression(tgtType, VPLUtil.GetCoreExpressionFromCast(sourceCode)));
            }
            TypeConverter converter = TypeDescriptor.GetConverter(targetType.Type);

            if (converter.CanConvertFrom(sourceType.Type))
            {
                MathNode.AddImportLocation(typeof(TypeConverter).Assembly.Location);
                string converterName = "conv" + targetType.Type.Name;
                if (!MathNodeVariable.VariableDeclared(supprtStatements, converterName))
                {
                    CodeVariableDeclarationStatement cs1 = new CodeVariableDeclarationStatement(
                        typeof(TypeConverter), converterName,
                        new CodeMethodInvokeExpression(
                            new CodeTypeReferenceExpression(typeof(TypeDescriptor)), "GetConverter",
                            new CodeExpression[] { new CodeSnippetExpression("typeof(" + tgtType + ")") }));
                    supprtStatements.Add(cs1);
                }
                //=================================================
                //
                codeRet = new CodeCastExpression(tgtType,
                                                 new CodeMethodInvokeExpression(
                                                     new CodeVariableReferenceExpression(converterName), "ConvertFrom",
                                                     new CodeExpression[] { sourceCode }));
                MathNode.Trace("\tcode 102: source type:{0}, target type:{1} result=converter.ConvertFrom(code);", sourceType, targetType);
            }
            else
            {
                codeRet = CastOrConvert(sourceCode, sourceType.Type, targetType.Type, supprtStatements);
            }
            return(codeRet);
        }
Ejemplo n.º 2
0
        public override System.CodeDom.CodeExpression ExportCode(IMethodCompile method)
        {
            MathNode.Trace("{0}.ExportCode: [{1}]", this.GetType().Name, this[0].TraceInfo);
            CodeMethodReferenceExpression mr = new CodeMethodReferenceExpression();

            mr.MethodName   = "Sqrt";
            mr.TargetObject = new CodeTypeReferenceExpression(typeof(Math));
            CodeExpression[] ps = new CodeExpression[1];
            ps[0] = this[0].ExportCode(method);
            if (!this[0].DataType.Type.Equals(typeof(double)))
            {
                ps[0] = new CodeCastExpression(typeof(double), VPLUtil.GetCoreExpressionFromCast(ps[0]));
            }
            return(new CodeMethodInvokeExpression(
                       mr,
                       ps));
        }
        /// <summary>
        /// implement IProgramEntity.ReturnCodeExpression
        /// if _castTo is null then this function returns the same as IMathExpression.ReturnCodeExpression
        /// </summary>
        /// <param name="portSelection"></param>
        /// <param name="method"></param>
        /// <returns></returns>
        public CodeExpression ReturnCodeExpression(object portSelection, IMethodCompile method)
        {
            CodeExpression ce = ReturnCodeExpression(method);

            if (_castTo != null)
            {
                IProgramPort p = portSelection as IProgramPort;
                if (p != null)
                {
                    ObjectRef prop = p.PortProperty;
                    if (prop != null)
                    {
                        StringCollection props = new StringCollection();
                        ce = new CodeCastExpression(_castTo.EntityType.TypeString, VPLUtil.GetCoreExpressionFromCast(ce));
                        while (true)
                        {
                            props.Add(prop.localName);
                            prop = prop.Owner;
                            if (prop == null)
                            {
                                break;
                            }
                            if (prop.IsSameType(_castTo.EntityType))
                            {
                                break;
                            }
                        }
                        for (int i = props.Count - 1; i >= 0; i--)
                        {
                            ce = new CodePropertyReferenceExpression(ce, props[i]);
                        }
                    }
                }
            }
            return(ce);
        }
        static CodeExpression CastOrConvert(CodeExpression code, Type sourceType, Type targetType, CodeStatementCollection csc)
        {
            if (sourceType.Equals(targetType))
            {
                MathNode.Trace("CastOrConvert 1: same type: {0}", targetType);
                return(code);
            }
            if (targetType.IsByRef)
            {
                MathNode.Trace("CastOrConvert 2: by ref type: {0}", targetType);
                return(code);
            }
            if (targetType.Equals(typeof(string)))
            {
                MathNode.Trace("CastOrConvert 3: to string from: {0}", sourceType);
                return(new CodeMethodInvokeExpression(code, "ToString", new CodeExpression[] { }));
            }
            TypeCode tcTarget = Type.GetTypeCode(targetType);
            TypeCode tcSource = Type.GetTypeCode(sourceType);

            if (IsNumeric(tcTarget))
            {
                if (IsNumeric(tcSource))
                {
                    return(new CodeCastExpression(targetType, VPLUtil.GetCoreExpressionFromCast(code)));
                }
                else
                {
                    if (tcSource == TypeCode.String)
                    {
                        return(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Convert)), GetConverToName(tcTarget), code));
                    }
                }
            }
            switch (tcTarget)
            {
            case TypeCode.Boolean:
                if (IsNumeric(tcSource) || tcSource == TypeCode.Char)
                {
                    return(new CodeBinaryOperatorExpression(code, CodeBinaryOperatorType.IdentityInequality, new CodeCastExpression(sourceType, new CodePrimitiveExpression(0))));
                }
                switch (tcSource)
                {
                case TypeCode.Boolean:
                    return(code);

                case TypeCode.DateTime:
                    return(new CodeBinaryOperatorExpression(code, CodeBinaryOperatorType.GreaterThan, new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(DateTime)), "MinValue")));

                case TypeCode.Object:
                    return(new CodeBinaryOperatorExpression(code, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)));
                }
                break;

            case TypeCode.String:
                return(new CodeMethodInvokeExpression(code, "ToString"));

            case TypeCode.Char:
                if (code is CodePrimitiveExpression)
                {
                    CodePrimitiveExpression cp = (CodePrimitiveExpression)code;
                    if (cp.Value == null)
                    {
                        return(new CodePrimitiveExpression('\0'));
                    }
                    if (ValueTypeUtil.IsNumber(cp.Value.GetType()))
                    {
                        short v = Convert.ToInt16(cp.Value);
                        return(new CodePrimitiveExpression((char)v));
                    }
                    string s = cp.Value.ToString();
                    if (string.IsNullOrEmpty(s))
                    {
                        return(new CodePrimitiveExpression('\0'));
                    }
                    else
                    {
                        return(new CodePrimitiveExpression(s[0]));
                    }
                }
                return(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Convert)), "ToChar", code));

            case TypeCode.DateTime:
                return(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Convert)), "ToDateTime", code));
            }
            if (sourceType.IsSubclassOf(targetType))
            {
                return(code);
            }
            if (targetType.IsSubclassOf(sourceType))
            {
                return(new CodeCastExpression(targetType, code));
            }
            return(CodeExpConvertTo(code, sourceType, targetType, csc));
        }
 public static void CreateAssignment(CodeExpression left, Type leftType, CodeExpression right, Type rightType, CodeStatementCollection statements, bool bThreadSafe)
 {
     if (leftType.IsAssignableFrom(rightType))
     {
         CodeAssignStatement cas = new CodeAssignStatement(left, right);
         if (!bThreadSafe)
         {
             statements.Add(new CodeSnippetStatement(CompilerUtil.InvokeStart));
         }
         statements.Add(cas);
         if (!bThreadSafe)
         {
             statements.Add(new CodeSnippetStatement(CompilerUtil.InvokeEnd));
         }
     }
     else
     {
         if (typeof(string).Equals(leftType) || typeof(PhpString).Equals(leftType))
         {
             if (rightType.IsValueType)
             {
                 CodeAssignStatement cas = new CodeAssignStatement(left,
                                                                   new CodeMethodInvokeExpression(right, "ToString"));
                 statements.Add(cas);
             }
             else
             {
                 //if it is null then return null else return var.ToString()
                 string vn = "l" + Guid.NewGuid().GetHashCode().ToString("x");
                 CodeVariableDeclarationStatement vds = new CodeVariableDeclarationStatement(rightType, vn, right);
                 statements.Add(vds);
                 CodeConditionStatement ccs = new CodeConditionStatement(
                     new CodeBinaryOperatorExpression(
                         new CodeVariableReferenceExpression(vn), CodeBinaryOperatorType.IdentityInequality,
                         new CodePrimitiveExpression(null)),
                     new CodeStatement[] { new CodeAssignStatement(left, new CodeMethodInvokeExpression(new CodeVariableReferenceExpression(vn), "ToString")) },
                     new CodeStatement[] { new CodeAssignStatement(left, new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(typeof(string)), "Empty")) });
                 statements.Add(ccs);
             }
         }
         else if (typeof(bool).Equals(leftType))
         {
             CodeAssignStatement cas = new CodeAssignStatement(left,
                                                               ConvertToBool(rightType, right));
             statements.Add(cas);
         }
         else
         {
             bool converted = false;
             if ((leftType.IsPrimitive || leftType.GetInterface("IConvertible") != null) &&
                 (rightType.IsPrimitive || rightType.GetInterface("IConvertible") != null))
             {
                 CodeExpression ex = VPLUtil.ConvertByType(leftType, right);
                 if (ex != null)
                 {
                     CodeAssignStatement cas = new CodeAssignStatement(left, ex);
                     statements.Add(cas);
                     converted = true;
                 }
             }
             if (!converted)
             {
                 TypeConverter converter = TypeDescriptor.GetConverter(leftType);
                 if (converter != null)
                 {
                     if (converter.CanConvertFrom(rightType))
                     {
                         string vn = "c" + Guid.NewGuid().GetHashCode().ToString("x");
                         CodeVariableDeclarationStatement vds = new CodeVariableDeclarationStatement(typeof(TypeConverter), vn,
                                                                                                     new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(TypeDescriptor)), "GetConverter", new CodeTypeOfExpression(leftType)));
                         statements.Add(vds);
                         CodeAssignStatement cas = new CodeAssignStatement(left,
                                                                           new CodeCastExpression(leftType,
                                                                                                  new CodeMethodInvokeExpression(
                                                                                                      new CodeVariableReferenceExpression(vn), "ConvertFrom", right)));
                         statements.Add(cas);
                         converted = true;
                     }
                 }
             }
             if (!converted)
             {
                 TypeConverter converter = TypeDescriptor.GetConverter(rightType);
                 if (converter != null)
                 {
                     if (converter.CanConvertTo(leftType))
                     {
                         string vn = "c" + Guid.NewGuid().GetHashCode().ToString("x");
                         CodeVariableDeclarationStatement vds = new CodeVariableDeclarationStatement(typeof(TypeConverter), vn,
                                                                                                     new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(TypeDescriptor)), "GetConverter", new CodeTypeOfExpression(rightType)));
                         statements.Add(vds);
                         CodeAssignStatement cas = new CodeAssignStatement(left,
                                                                           new CodeMethodInvokeExpression(
                                                                               new CodeVariableReferenceExpression(vn), "CanConvertTo", right, new CodeTypeOfExpression(leftType)));
                         statements.Add(cas);
                         converted = true;
                     }
                 }
             }
             if (!converted)
             {
                 CodeAssignStatement cas = new CodeAssignStatement(left,
                                                                   new CodeCastExpression(leftType, VPLUtil.GetCoreExpressionFromCast(right)));
                 statements.Add(cas);
             }
         }
     }
 }
 public static CodeCastExpression GetTypeConversion(string targetType, CodeExpression data)
 {
     return(new CodeCastExpression(targetType, VPLUtil.GetCoreExpressionFromCast(data)));
 }
        public static CodeExpression GetTypeConversion(DataTypePointer targetType, CodeExpression data, DataTypePointer dataType, CodeStatementCollection statements)
        {
            if (targetType.IsLibType && typeof(Type).Equals(targetType.BaseClassType))
            {
                if (data is CodeTypeOfExpression)
                {
                    return(data);
                }
            }
            if (targetType.IsAssignableFrom(dataType))
            {
                return(data);
            }
            if (typeof(string).Equals(targetType.BaseClassType))
            {
                if (typeof(JsString).Equals(dataType.BaseClassType))
                {
                    return(data);
                }
                if (typeof(PhpString).Equals(dataType.BaseClassType))
                {
                    return(data);
                }
                if (dataType.IsValueType)
                {
                    return(new CodeMethodInvokeExpression(data, "ToString"));
                }
                else
                {
                    string         vn = "l" + Guid.NewGuid().GetHashCode().ToString("x");
                    string         vs = "l" + Guid.NewGuid().GetHashCode().ToString("x");
                    CodeExpression val;
                    if (data is CodePropertyReferenceExpression || data is CodeFieldReferenceExpression || data is CodeVariableReferenceExpression)
                    {
                        val = data;
                    }
                    else
                    {
                        CodeVariableDeclarationStatement vds = new CodeVariableDeclarationStatement(dataType.GetCodeTypeReference(), vn, data);
                        statements.Add(vds);
                        val = new CodeVariableReferenceExpression(vn);
                    }
                    CodeVariableDeclarationStatement vds2 = new CodeVariableDeclarationStatement(typeof(string), vs);
                    statements.Add(vds2);
                    CodeVariableReferenceExpression re  = new CodeVariableReferenceExpression(vs);
                    CodeConditionStatement          ccs = new CodeConditionStatement(
                        new CodeBinaryOperatorExpression(
                            val, CodeBinaryOperatorType.IdentityInequality,
                            new CodePrimitiveExpression(null)),
                        new CodeStatement[] { new CodeAssignStatement(re, new CodeMethodInvokeExpression(val, "ToString")) },
                        new CodeStatement[] { new CodeAssignStatement(re, new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(typeof(string)), "Empty")) });
                    statements.Add(ccs);
                    return(re);
                }
            }
            if (typeof(bool).Equals(targetType.BaseClassType))
            {
                return(ConvertToBool(dataType.BaseClassType, data));
            }
            if ((targetType.BaseClassType.IsPrimitive || targetType.BaseClassType.GetInterface("IConvertible") != null) &&
                (dataType.BaseClassType.IsPrimitive || dataType.BaseClassType.GetInterface("IConvertible") != null))
            {
                CodeExpression ex = VPLUtil.ConvertByType(targetType.BaseClassType, data);
                if (ex != null)
                {
                    return(ex);
                }
            }
            if (targetType.BaseClassType.IsArray)
            {
                if (!dataType.BaseClassType.IsArray && !typeof(Array).Equals(dataType.BaseClassType))
                {
                    Type elementType;
                    if (targetType.BaseClassType.HasElementType)
                    {
                        elementType = targetType.BaseClassType.GetElementType();
                    }
                    else
                    {
                        elementType = typeof(object);
                    }
                    CodeArrayCreateExpression ae = new CodeArrayCreateExpression(elementType, new CodeExpression[] { GetTypeConversion(new DataTypePointer(elementType), data, dataType, statements) });
                    return(ae);
                }
            }
            TypeConverter converter = TypeDescriptor.GetConverter(targetType);

            if (converter != null)
            {
                if (converter.CanConvertFrom(dataType.BaseClassType))
                {
                    string vn = "c" + Guid.NewGuid().GetHashCode().ToString("x");
                    CodeVariableDeclarationStatement vds = new CodeVariableDeclarationStatement(typeof(TypeConverter), vn,
                                                                                                new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(TypeDescriptor)), "GetConverter", new CodeTypeOfExpression(targetType.GetCodeTypeReference())));
                    statements.Add(vds);
                    string vn2 = "c" + Guid.NewGuid().GetHashCode().ToString("x");
                    CodeVariableDeclarationStatement vds2 = new CodeVariableDeclarationStatement(typeof(TypeConverterNullable), vn2,
                                                                                                 new CodeObjectCreateExpression(typeof(TypeConverterNullable), new CodeVariableReferenceExpression(vn)));
                    statements.Add(vds2);
                    return(new CodeCastExpression(targetType.GetCodeTypeReference(),
                                                  new CodeMethodInvokeExpression(
                                                      new CodeVariableReferenceExpression(vn2), "ConvertFrom", data)));
                }
            }
            converter = TypeDescriptor.GetConverter(dataType);
            if (converter != null)
            {
                if (converter.CanConvertTo(targetType.BaseClassType))
                {
                    string vn = "c" + Guid.NewGuid().GetHashCode().ToString("x");
                    CodeVariableDeclarationStatement vds = new CodeVariableDeclarationStatement(typeof(TypeConverter), vn,
                                                                                                new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(TypeDescriptor)), "GetConverter", new CodeTypeOfExpression(dataType.GetCodeTypeReference())));
                    statements.Add(vds);
                    return(new CodeMethodInvokeExpression(
                               new CodeVariableReferenceExpression(vn), "CanConvertTo", data, new CodeTypeOfExpression(targetType.GetCodeTypeReference())));
                }
            }
            TypeCode tc = Type.GetTypeCode(targetType.BaseClassType);

            switch (tc)
            {
            case TypeCode.Boolean:
                return(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Convert)), "ToBoolean", VPLUtil.GetCoreExpressionFromCast(data)));

            case TypeCode.Byte:
                return(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Convert)), "ToByte", VPLUtil.GetCoreExpressionFromCast(data)));

            case TypeCode.Char:
                return(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Convert)), "ToChar", VPLUtil.GetCoreExpressionFromCast(data)));

            case TypeCode.DateTime:
                return(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Convert)), "ToDateTime", VPLUtil.GetCoreExpressionFromCast(data)));

            case TypeCode.Decimal:
                return(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Convert)), "ToDecimal", VPLUtil.GetCoreExpressionFromCast(data)));

            case TypeCode.Double:
                return(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Convert)), "ToDouble", VPLUtil.GetCoreExpressionFromCast(data)));

            case TypeCode.Int16:
                return(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Convert)), "ToInt16", VPLUtil.GetCoreExpressionFromCast(data)));

            case TypeCode.Int32:
                return(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Convert)), "ToInt32", VPLUtil.GetCoreExpressionFromCast(data)));

            case TypeCode.Int64:
                return(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Convert)), "ToInt64", VPLUtil.GetCoreExpressionFromCast(data)));

            case TypeCode.SByte:
                return(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Convert)), "ToSByte", VPLUtil.GetCoreExpressionFromCast(data)));

            case TypeCode.Single:
                return(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Convert)), "ToSingle", VPLUtil.GetCoreExpressionFromCast(data)));

            case TypeCode.String:
                return(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Convert)), "ToString", VPLUtil.GetCoreExpressionFromCast(data)));

            case TypeCode.UInt16:
                return(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Convert)), "ToUInt16", VPLUtil.GetCoreExpressionFromCast(data)));

            case TypeCode.UInt32:
                return(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Convert)), "ToUInt32", VPLUtil.GetCoreExpressionFromCast(data)));

            case TypeCode.UInt64:
                return(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Convert)), "ToUInt64", VPLUtil.GetCoreExpressionFromCast(data)));
            }
            ConstructorInfo cif = targetType.BaseClassType.GetConstructor(new Type[] { dataType.BaseClassType });

            if (cif != null)
            {
                return(new CodeObjectCreateExpression(targetType.BaseClassType, data));
            }
            return(new CodeCastExpression(targetType.GetCodeTypeReference(), VPLUtil.GetCoreExpressionFromCast(data)));
        }