Ast.Expression Convert(Ast.Expression expr, TypeSig actualType, TypeSig reqType) { if (actualType == null || reqType == null || TypeAnalysis.IsSameType(actualType, reqType)) { return expr; } else if (actualType is ByRefSig && reqType is PtrSig && expr is DirectionExpression) { return Convert( new UnaryOperatorExpression(UnaryOperatorType.AddressOf, ((DirectionExpression)expr).Expression.Detach()), new PtrSig(((ByRefSig)actualType).Next), reqType); } else if (actualType is PtrSig && reqType is ByRefSig) { expr = Convert(expr, actualType, new PtrSig(((ByRefSig)reqType).Next)); return new DirectionExpression { FieldDirection = FieldDirection.Ref, Expression = new UnaryOperatorExpression(UnaryOperatorType.Dereference, expr) }; } else if (actualType is PtrSig && reqType is PtrSig) { if (actualType.FullName != reqType.FullName) return expr.CastTo(AstBuilder.ConvertType(reqType)); else return expr; } else { bool actualIsIntegerOrEnum = TypeAnalysis.IsIntegerOrEnum(actualType); bool requiredIsIntegerOrEnum = TypeAnalysis.IsIntegerOrEnum(reqType); if (reqType.GetElementType() == ElementType.Boolean) { if (actualType.GetElementType() == ElementType.Boolean) return expr; if (actualIsIntegerOrEnum) { return new BinaryOperatorExpression(expr, BinaryOperatorType.InEquality, AstBuilder.MakePrimitive(0, actualType.ToTypeDefOrRef())); } else { return new BinaryOperatorExpression(expr, BinaryOperatorType.InEquality, new NullReferenceExpression()); } } if (actualType.GetElementType() == ElementType.Boolean && requiredIsIntegerOrEnum) { return new ConditionalExpression { Condition = expr, TrueExpression = AstBuilder.MakePrimitive(1, reqType.ToTypeDefOrRef()), FalseExpression = AstBuilder.MakePrimitive(0, reqType.ToTypeDefOrRef()) }; } if (expr is PrimitiveExpression && !requiredIsIntegerOrEnum && TypeAnalysis.IsEnum(actualType)) { return expr.CastTo(AstBuilder.ConvertType(actualType)); } bool actualIsPrimitiveType = actualIsIntegerOrEnum || actualType.GetElementType() == ElementType.R4 || actualType.GetElementType() == ElementType.R8; bool requiredIsPrimitiveType = requiredIsIntegerOrEnum || reqType.GetElementType() == ElementType.R4 || reqType.GetElementType() == ElementType.R8; if (actualIsPrimitiveType && requiredIsPrimitiveType) { return expr.CastTo(AstBuilder.ConvertType(reqType)); } return expr; } }
Ast.Expression Convert(Ast.Expression expr, Cecil.TypeReference actualType, Cecil.TypeReference reqType) { if (actualType == null || reqType == null || TypeAnalysis.IsSameType(actualType, reqType)) { return expr; } else if (actualType is ByReferenceType && reqType is PointerType && expr is DirectionExpression) { return Convert( new UnaryOperatorExpression(UnaryOperatorType.AddressOf, ((DirectionExpression)expr).Expression.Detach()), new PointerType(((ByReferenceType)actualType).ElementType), reqType); } else if (actualType is PointerType && reqType is ByReferenceType) { expr = Convert(expr, actualType, new PointerType(((ByReferenceType)reqType).ElementType)); return new DirectionExpression { FieldDirection = FieldDirection.Ref, Expression = new UnaryOperatorExpression(UnaryOperatorType.Dereference, expr) }; } else if (actualType is PointerType && reqType is PointerType) { if (actualType.FullName != reqType.FullName) return expr.CastTo(AstBuilder.ConvertType(reqType)); else return expr; } else { bool actualIsIntegerOrEnum = TypeAnalysis.IsIntegerOrEnum(actualType); bool requiredIsIntegerOrEnum = TypeAnalysis.IsIntegerOrEnum(reqType); if (TypeAnalysis.IsBoolean(reqType)) { if (TypeAnalysis.IsBoolean(actualType)) return expr; if (actualIsIntegerOrEnum) { return new BinaryOperatorExpression(expr, BinaryOperatorType.InEquality, AstBuilder.MakePrimitive(0, actualType)); } else { return new BinaryOperatorExpression(expr, BinaryOperatorType.InEquality, new NullReferenceExpression()); } } if (TypeAnalysis.IsBoolean(actualType) && requiredIsIntegerOrEnum) { return new ConditionalExpression { Condition = expr, TrueExpression = AstBuilder.MakePrimitive(1, reqType), FalseExpression = AstBuilder.MakePrimitive(0, reqType) }; } if (expr is PrimitiveExpression && !requiredIsIntegerOrEnum && TypeAnalysis.IsEnum(actualType)) { return expr.CastTo(AstBuilder.ConvertType(actualType)); } bool actualIsPrimitiveType = actualIsIntegerOrEnum || actualType.MetadataType == MetadataType.Single || actualType.MetadataType == MetadataType.Double; bool requiredIsPrimitiveType = requiredIsIntegerOrEnum || reqType.MetadataType == MetadataType.Single || reqType.MetadataType == MetadataType.Double; if (actualIsPrimitiveType && requiredIsPrimitiveType) { return expr.CastTo(AstBuilder.ConvertType(reqType)); } return expr; } }
Ast.Expression Convert(Ast.Expression expr, Cecil.TypeReference actualType, Cecil.TypeReference reqType) { if (reqType == null || actualType == reqType) { return expr; } else { bool actualIsIntegerOrEnum = TypeAnalysis.IsIntegerOrEnum(actualType); bool requiredIsIntegerOrEnum = TypeAnalysis.IsIntegerOrEnum(reqType); if (TypeAnalysis.IsBoolean(reqType)) { if (TypeAnalysis.IsBoolean(actualType)) return expr; if (actualIsIntegerOrEnum) { return new BinaryOperatorExpression(expr, BinaryOperatorType.InEquality, AstBuilder.MakePrimitive(0, actualType)); } else { return new BinaryOperatorExpression(expr, BinaryOperatorType.InEquality, new NullReferenceExpression()); } } if (TypeAnalysis.IsBoolean(actualType) && requiredIsIntegerOrEnum) { return new ConditionalExpression { Condition = expr, TrueExpression = AstBuilder.MakePrimitive(1, reqType), FalseExpression = AstBuilder.MakePrimitive(0, reqType) }; } if (expr is PrimitiveExpression && !requiredIsIntegerOrEnum && TypeAnalysis.IsEnum(actualType)) { return expr.CastTo(AstBuilder.ConvertType(actualType)); } if (actualIsIntegerOrEnum && requiredIsIntegerOrEnum) { return expr.CastTo(AstBuilder.ConvertType(reqType)); } return expr; } }