}
static EmptyExpression MyEmptyExpr;
- static public Expression ImplicitReferenceConversion (EmitContext ec, Expression expr, Type target_type)
+ static public Expression WideningReferenceConversion (EmitContext ec, Expression expr, Type target_type)
{
Type expr_type = expr.Type;
return new EmptyCast (expr, target_type);
}
- // This code is kind of mirrored inside ImplicitStandardConversionExists
+ // This code is kind of mirrored inside WideningStandardConversionExists
// with the small distinction that we only probe there
//
// Always ensure that the code here and there is in sync
Type target_element_type = TypeManager.GetElementType (target_type);
if (!expr_element_type.IsValueType && !target_element_type.IsValueType)
- if (ImplicitStandardConversionExists (ConstantEC, MyEmptyExpr,
+ if (WideningStandardConversionExists (ConstantEC, MyEmptyExpr,
target_element_type))
return new EmptyCast (expr, target_type);
}
// Tests whether an implicit reference conversion exists between expr_type
// and target_type
//
- public static bool ImplicitReferenceConversionExists (EmitContext ec, Expression expr, Type target_type)
+ public static bool WideningReferenceConversionExists (EmitContext ec, Expression expr, Type target_type)
{
Type expr_type = expr.Type;
return true;
// Please remember that all code below actually comes
- // from ImplicitReferenceConversion so make sure code remains in sync
+ // from WideningReferenceConversion so make sure code remains in sync
// from any class-type S to any interface-type T.
if (target_type.IsInterface) {
Type target_element_type = TypeManager.GetElementType (target_type);
if (!expr_element_type.IsValueType && !target_element_type.IsValueType)
- if (ImplicitStandardConversionExists (ConstantEC, MyEmptyExpr,
+ if (WideningStandardConversionExists (ConstantEC, MyEmptyExpr,
target_element_type))
return true;
}
/// expr is the expression to convert, returns a new expression of type
/// target_type or null if an implicit conversion is not possible.
/// </summary>
- static public Expression ImplicitNumericConversion (EmitContext ec, Expression expr,
+ static public Expression WideningNumericConversion (EmitContext ec, Expression expr,
Type target_type, Location loc)
{
Type expr_type = expr.Type;
if (expr is IntConstant){
Expression e;
- e = TryImplicitIntConversion (target_type, (IntConstant) expr);
+ e = TryWideningIntConversion (target_type, (IntConstant) expr);
if (e != null)
return e;
/// <summary>
- /// Same as ImplicitStandardConversionExists except that it also looks at
+ /// Same as WideningStandardConversionExists except that it also looks at
/// implicit user defined conversions - needed for overload resolution
/// </summary>
- public static bool ImplicitConversionExists (EmitContext ec, Expression expr, Type target_type)
+ public static bool WideningConversionExists (EmitContext ec, Expression expr, Type target_type)
{
if ((expr is NullLiteral) && target_type.IsGenericParameter)
return TypeParameter_to_Null (target_type);
- if (ImplicitStandardConversionExists (ec, expr, target_type))
+ if (WideningStandardConversionExists (ec, expr, target_type))
return true;
- Expression dummy = ImplicitUserConversion (ec, expr, target_type, Location.Null);
+ //
+ // VB.NET has no notion of User defined conversions
+ //
- if (dummy != null)
- return true;
+// Expression dummy = ImplicitUserConversion (ec, expr, target_type, Location.Null);
+
+// if (dummy != null)
+// return true;
return false;
}
- public static bool ImplicitUserConversionExists (EmitContext ec, Type source, Type target)
- {
- Expression dummy = ImplicitUserConversion (
- ec, new EmptyExpression (source), target, Location.Null);
- return dummy != null;
- }
+ //
+ // VB.NET has no notion of User defined conversions
+ //
+
+// public static bool ImplicitUserConversionExists (EmitContext ec, Type source, Type target)
+// {
+// Expression dummy = ImplicitUserConversion (
+// ec, new EmptyExpression (source), target, Location.Null);
+// return dummy != null;
+// }
/// <summary>
/// Determines if a standard implicit conversion exists from
///
/// ec should point to a real EmitContext if expr.Type is TypeManager.anonymous_method_type.
/// </summary>
- public static bool ImplicitStandardConversionExists (EmitContext ec, Expression expr, Type target_type)
+ public static bool WideningStandardConversionExists (EmitContext ec, Expression expr, Type target_type)
{
Type expr_type = expr.Type;
}
}
- if (ImplicitReferenceConversionExists (ec, expr, target_type))
+ if (WideningReferenceConversionExists (ec, expr, target_type))
return true;
//
//
// If `expr_type' implements `target_type' (which is an iface)
- // see TryImplicitIntConversion
+ // see TryWideningIntConversion
//
if (target_type.IsInterface && target_type.IsAssignableFrom (expr_type))
return true;
continue;
}
- if (ImplicitStandardConversionExists (ec, priv_fmet_param, best))
+ if (WideningStandardConversionExists (ec, priv_fmet_param, best))
best = t;
}
continue;
}
- if (ImplicitStandardConversionExists (ec, priv_fmee_ret, t))
+ if (WideningStandardConversionExists (ec, priv_fmee_ret, t))
best = t;
}
// or encompassed by S to a type encompassing or encompassed by T
//
priv_fms_expr.SetType (param_type);
- if (ImplicitStandardConversionExists (ec, priv_fms_expr, source_type))
+ if (WideningStandardConversionExists (ec, priv_fms_expr, source_type))
src_types_set.Add (param_type);
else {
- if (ImplicitStandardConversionExists (ec, source, param_type))
+ if (WideningStandardConversionExists (ec, source, param_type))
src_types_set.Add (param_type);
}
} else {
//
// Only if S is encompassed by param_type
//
- if (ImplicitStandardConversionExists (ec, source, param_type))
+ if (WideningStandardConversionExists (ec, source, param_type))
src_types_set.Add (param_type);
}
}
ArrayList candidate_set = new ArrayList ();
foreach (Type param_type in src_types_set){
- if (ImplicitStandardConversionExists (ec, source, param_type))
+ if (WideningStandardConversionExists (ec, source, param_type))
candidate_set.Add (param_type);
}
// or encompassed by S to a type encompassing or encompassed by T
//
priv_fms_expr.SetType (ret_type);
- if (ImplicitStandardConversionExists (ec, priv_fms_expr, target))
+ if (WideningStandardConversionExists (ec, priv_fms_expr, target))
tgt_types_set.Add (ret_type);
else {
priv_fms_expr.SetType (target);
- if (ImplicitStandardConversionExists (ec, priv_fms_expr, ret_type))
+ if (WideningStandardConversionExists (ec, priv_fms_expr, ret_type))
tgt_types_set.Add (ret_type);
}
} else {
// Only if T is encompassed by param_type
//
priv_fms_expr.SetType (ret_type);
- if (ImplicitStandardConversionExists (ec, priv_fms_expr, target))
+ if (WideningStandardConversionExists (ec, priv_fms_expr, target))
tgt_types_set.Add (ret_type);
}
}
foreach (Type ret_type in tgt_types_set){
priv_fmt_expr.SetType (ret_type);
- if (ImplicitStandardConversionExists (ec, priv_fmt_expr, target))
+ if (WideningStandardConversionExists (ec, priv_fmt_expr, target))
candidate_set.Add (ret_type);
}
/// <summary>
/// User-defined Implicit conversions
/// </summary>
- static public Expression ImplicitUserConversion (EmitContext ec, Expression source,
- Type target, Location loc)
- {
- return UserDefinedConversion (ec, source, target, loc, false);
- }
+
+ //
+ // VB.NET has no notion of User defined conversions
+ //
+
+// static public Expression ImplicitUserConversion (EmitContext ec, Expression source,
+// Type target, Location loc)
+// {
+// return UserDefinedConversion (ec, source, target, loc, false);
+// }
/// <summary>
/// User-defined Explicit conversions
/// </summary>
- static public Expression ExplicitUserConversion (EmitContext ec, Expression source,
- Type target, Location loc)
- {
- return UserDefinedConversion (ec, source, target, loc, true);
- }
+
+ //
+ // VB.NET has no notion of User defined conversions
+ //
+
+// static public Expression ExplicitUserConversion (EmitContext ec, Expression source,
+// Type target, Location loc)
+// {
+// return UserDefinedConversion (ec, source, target, loc, true);
+// }
static DoubleHash explicit_conv = new DoubleHash (100);
static DoubleHash implicit_conv = new DoubleHash (100);
/// <summary>
/// User-defined conversions
/// </summary>
+
+ //
+ // VB.NET has no notion of User defined conversions. This method is not used.
+ //
static public Expression UserDefinedConversion (EmitContext ec, Expression source,
Type target, Location loc,
bool look_for_explicit)
// by target.
//
if (look_for_explicit)
- source = ExplicitConversionStandard (ec, source, most_specific_source, loc);
+ source = WideningAndNarrowingConversionStandard (ec, source, most_specific_source, loc);
else
- source = ImplicitConversionStandard (ec, source, most_specific_source, loc);
+ source = WideningConversionStandard (ec, source, most_specific_source, loc);
if (source == null)
return null;
e = new UserCast ((MethodInfo) method, source, loc);
if (e.Type != target){
if (!look_for_explicit)
- e = ImplicitConversionStandard (ec, e, target, loc);
+ e = WideningConversionStandard (ec, e, target, loc);
else
- e = ExplicitConversionStandard (ec, e, target, loc);
+ e = WideningAndNarrowingConversionStandard (ec, e, target, loc);
}
return e;
/// `target_type'. It returns a new expression that can be used
/// in a context that expects a `target_type'.
/// </summary>
- static public Expression ImplicitConversion (EmitContext ec, Expression expr,
+ static public Expression WideningConversion (EmitContext ec, Expression expr,
Type target_type, Location loc)
{
Expression e;
if (target_type == null)
throw new Exception ("Target type is null");
- e = ImplicitConversionStandard (ec, expr, target_type, loc);
+ e = WideningConversionStandard (ec, expr, target_type, loc);
if (e != null)
return e;
- e = ImplicitUserConversion (ec, expr, target_type, loc);
- if (e != null)
- return e;
+ //
+ // VB.NET has no notion of User defined conversions
+ //
+
+// e = ImplicitUserConversion (ec, expr, target_type, loc);
+// if (e != null)
+// return e;
return null;
}
/// that can be used in a context that expects a
/// `target_type'.
///
- /// This is different from `ImplicitConversion' in that the
+ /// This is different from `WideningConversion' in that the
/// user defined implicit conversions are excluded.
/// </summary>
- static public Expression ImplicitConversionStandard (EmitContext ec, Expression expr,
+ static public Expression WideningConversionStandard (EmitContext ec, Expression expr,
Type target_type, Location loc)
{
Type expr_type = expr.Type;
if (expr_type.Equals (target_type) && !TypeManager.IsNullType (expr_type))
return expr;
- e = ImplicitNumericConversion (ec, expr, target_type, loc);
+ e = WideningNumericConversion (ec, expr, target_type, loc);
if (e != null)
return e;
- e = ImplicitReferenceConversion (ec, expr, target_type);
+ e = WideningReferenceConversion (ec, expr, target_type);
if (e != null)
return e;
/// into a different data type using casts (See Implicit Constant
/// Expression Conversions)
/// </summary>
- static public Expression TryImplicitIntConversion (Type target_type, IntConstant ic)
+ static public Expression TryWideningIntConversion (Type target_type, IntConstant ic)
{
int value = ic.Value;
return null;
}
- static public void Error_CannotImplicitConversion (Location loc, Type source, Type target)
+ static public void Error_CannotWideningConversion (Location loc, Type source, Type target)
{
if (source.Name == target.Name){
Report.ExtraInformation (loc,
/// <summary>
/// Attempts to implicitly convert `source' into `target_type', using
- /// ImplicitConversion. If there is no implicit conversion, then
+ /// WideningConversion. If there is no implicit conversion, then
/// an error is signaled
/// </summary>
- static public Expression ImplicitConversionRequired (EmitContext ec, Expression source,
+ static public Expression WideningConversionRequired (EmitContext ec, Expression source,
Type target_type, Location loc)
{
Expression e;
int errors = Report.Errors;
- e = ImplicitConversion (ec, source, target_type, loc);
+ e = WideningConversion (ec, source, target_type, loc);
if (Report.Errors > errors)
return null;
if (e != null)
return null;
}
- Error_CannotImplicitConversion (loc, source.Type, target_type);
+ Error_CannotWideningConversion (loc, source.Type, target_type);
return null;
}
/// <summary>
/// Performs the explicit numeric conversions
/// </summary>
- static Expression ExplicitNumericConversion (EmitContext ec, Expression expr, Type target_type, Location loc)
+ static Expression NarrowingNumericConversion (EmitContext ec, Expression expr, Type target_type, Location loc)
{
Type expr_type = expr.Type;
if (TypeManager.IsEnumType (real_target_type))
real_target_type = TypeManager.EnumToUnderlying (real_target_type);
- if (ImplicitStandardConversionExists (ec, expr, real_target_type)){
- Expression ce = ImplicitConversionStandard (ec, expr, real_target_type, loc);
+ if (WideningStandardConversionExists (ec, expr, real_target_type)){
+ Expression ce = WideningConversionStandard (ec, expr, real_target_type, loc);
if (real_target_type != target_type)
return new EmptyCast (ce, target_type);
return null;
}
+ /// <summary>
+ /// VB.NET specific: Convert to and from boolean
+ /// </summary>
+
+ static public Expression BooleanConversions (EmitContext ec, Expression expr,
+ Type target_type, Location loc)
+ {
+ Type expr_type = expr.Type;
+ Type real_target_type = target_type;
+
+ if (expr_type == TypeManager.bool_type) {
+
+ //
+ // From boolean to byte, short, int,
+ // long, float, double, decimal
+ //
+
+ if (real_target_type == TypeManager.byte_type)
+ return new BooleanToNumericCast (expr, target_type, OpCodes.Conv_U1);
+ if (real_target_type == TypeManager.short_type)
+ return new BooleanToNumericCast (expr, target_type, OpCodes.Conv_I2);
+ if (real_target_type == TypeManager.int32_type)
+ return new BooleanToNumericCast (expr, target_type, OpCodes.Conv_I4);
+ if (real_target_type == TypeManager.int64_type)
+ return new BooleanToNumericCast (expr, target_type, OpCodes.Conv_I8);
+ if (real_target_type == TypeManager.float_type)
+ return new BooleanToNumericCast (expr, target_type, OpCodes.Conv_R4);
+ if (real_target_type == TypeManager.double_type)
+ return new BooleanToNumericCast (expr, target_type, OpCodes.Conv_R8);
+ if (real_target_type == TypeManager.decimal_type) {
+ return new ImplicitInvocation("DecimalType", "FromBoolean", loc, expr);
+ }
+ } if (real_target_type == TypeManager.bool_type) {
+
+ //
+ // From byte, short, int, long, float,
+ // double, decimal to boolean
+ //
+
+ if (expr_type == TypeManager.byte_type ||
+ expr_type == TypeManager.short_type ||
+ expr_type == TypeManager.int32_type ||
+ expr_type == TypeManager.int64_type ||
+ expr_type == TypeManager.float_type ||
+ expr_type == TypeManager.double_type)
+ return new NumericToBooleanCast (expr, expr_type);
+ if (expr_type == TypeManager.decimal_type) {
+ return new ImplicitInvocation("System", "Convert", "ToBoolean", loc, expr);
+ }
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// VB.NET specific: Widening conversions to string
+ /// </summary>
+
+ static public Expression WideningStringConversions (EmitContext ec, Expression expr,
+ Type target_type, Location loc)
+ {
+ Expression ret_expr = DoWideningStringConversions (ec, expr, target_type, loc);
+
+ if (ret_expr != null)
+ ret_expr = ret_expr.Resolve (ec);
+
+ return ret_expr;
+ }
+
+ static public Expression DoWideningStringConversions (EmitContext ec, Expression expr,
+ Type target_type, Location loc)
+
+ {
+ Type expr_type = expr.Type;
+ Type real_target_type = target_type;
+
+ if (real_target_type == TypeManager.string_type) {
+ //
+ // From char to string
+ //
+ if (expr_type == TypeManager.char_type)
+ return new ImplicitInvocation ("StringType", "FromChar", loc, expr);
+ }
+
+ if(expr_type.IsArray && (expr_type.GetElementType() == TypeManager.char_type)) {
+ //
+ // From char array to string
+ //
+ return new ImplicitNew ("System", "String", loc, expr);
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// VB.NET specific: Narrowing conversions involving strings
+ /// </summary>
+
+ static public Expression NarrowingStringConversions (EmitContext ec, Expression expr,
+ Type target_type, Location loc)
+ {
+ Expression ret_expr = DoNarrowingStringConversions (ec, expr, target_type, loc);
+
+ if (ret_expr != null)
+ ret_expr = ret_expr.Resolve (ec);
+
+ return ret_expr;
+ }
+
+ static public Expression DoNarrowingStringConversions (EmitContext ec, Expression expr,
+ Type target_type, Location loc)
+ {
+ Type expr_type = expr.Type;
+ Type real_target_type = target_type;
+
+ // FIXME: Need to take care of Constants
+
+ if (expr_type == TypeManager.string_type) {
+
+ //
+ // From string to chararray, bool,
+ // byte, short, char, int, long,
+ // float, double, decimal and date
+ //
+
+ if (real_target_type.IsArray && (real_target_type.GetElementType() == TypeManager.char_type))
+ return new ImplicitInvocation("CharArrayType", "FromString", loc, expr);
+ if (real_target_type == TypeManager.bool_type)
+ return new ImplicitInvocation("BooleanType", "FromString", loc, expr);
+ if (real_target_type == TypeManager.byte_type)
+ return new ImplicitInvocation("ByteType", "FromString", loc, expr);
+ if (real_target_type == TypeManager.short_type)
+ return new ImplicitInvocation("ShortType", "FromString", loc, expr);
+ if (real_target_type == TypeManager.char_type)
+ return new ImplicitInvocation("CharType", "FromString", loc, expr);
+ if (real_target_type == TypeManager.int32_type)
+ return new ImplicitInvocation("IntegerType", "FromString", loc, expr);
+ if (real_target_type == TypeManager.int64_type)
+ return new ImplicitInvocation("LongType", "FromString", loc, expr);
+ if (real_target_type == TypeManager.float_type)
+ return new ImplicitInvocation("SingleType", "FromString", loc, expr);
+ if (real_target_type == TypeManager.double_type)
+ return new ImplicitInvocation("DoubleType", "FromString", loc, expr);
+ if (real_target_type == TypeManager.decimal_type)
+ return new ImplicitInvocation("DecimalType", "FromString", loc, expr);
+ if (real_target_type == TypeManager.date_type)
+ return new ImplicitInvocation("DateType", "FromString", loc, expr);
+ } if (real_target_type == TypeManager.string_type) {
+
+ //
+ // From bool, byte, short, char, int,
+ // long, float, double, decimal and
+ // date to string
+ //
+
+ if (expr_type == TypeManager.bool_type)
+ return new ImplicitInvocation("StringType", "FromBoolean", loc, expr);
+ if (expr_type == TypeManager.byte_type)
+ return new ImplicitInvocation("StringType", "FromByte", loc, expr);
+ if (expr_type == TypeManager.short_type)
+ return new ImplicitInvocation("StringType", "FromShort", loc, expr);
+ if (expr_type == TypeManager.int32_type)
+ return new ImplicitInvocation("StringType", "FromInteger", loc, expr);
+ if (expr_type == TypeManager.int64_type)
+ return new ImplicitInvocation("StringType", "FromLong", loc, expr);
+ if (expr_type == TypeManager.float_type)
+ return new ImplicitInvocation("StringType", "FromSingle", loc, expr);
+ if (expr_type == TypeManager.double_type)
+ return new ImplicitInvocation("StringType", "FromDouble", loc, expr);
+ if (expr_type == TypeManager.decimal_type)
+ return new ImplicitInvocation("StringType", "FromDecimal", loc, expr);
+ if (expr_type == TypeManager.date_type)
+ return new ImplicitInvocation("StringType", "FromDate", loc, expr);
+ }
+
+ return null;
+ }
+
/// <summary>
/// Returns whether an explicit reference conversion can be performed
/// from source_type to target_type
/// </summary>
- public static bool ExplicitReferenceConversionExists (Type source_type, Type target_type)
+ public static bool NarrowingReferenceConversionExists (Type source_type, Type target_type)
{
bool target_is_type_param = target_type.IsGenericParameter;
bool target_is_value_type = target_type.IsValueType;
Type target_element_type = TypeManager.GetElementType (target_type);
if (!source_element_type.IsValueType && !target_element_type.IsValueType)
- if (ExplicitReferenceConversionExists (source_element_type,
+ if (NarrowingReferenceConversionExists (source_element_type,
target_element_type))
return true;
}
/// <summary>
/// Implements Explicit Reference conversions
/// </summary>
- static Expression ExplicitReferenceConversion (Expression source, Type target_type)
+ static Expression NarrowingReferenceConversion (Expression source, Type target_type)
{
Type source_type = source.Type;
bool target_is_type_param = target_type.IsGenericParameter;
Type target_element_type = TypeManager.GetElementType (target_type);
if (!source_element_type.IsValueType && !target_element_type.IsValueType)
- if (ExplicitReferenceConversionExists (source_element_type,
+ if (NarrowingReferenceConversionExists (source_element_type,
target_element_type))
return new ClassCast (source, target_type);
}
/// Performs an explicit conversion of the expression `expr' whose
/// type is expr.Type to `target_type'.
/// </summary>
- static public Expression ExplicitConversion (EmitContext ec, Expression expr,
+ static public Expression WideningAndNarrowingConversion (EmitContext ec, Expression expr,
Type target_type, Location loc)
{
Type expr_type = expr.Type;
}
int errors = Report.Errors;
- Expression ne = ImplicitConversionStandard (ec, expr, target_type, loc);
+ Expression ne = WideningConversionStandard (ec, expr, target_type, loc);
if (Report.Errors > errors)
return null;
if (ne != null)
return ne;
- ne = ExplicitNumericConversion (ec, expr, target_type, loc);
+ ne = NarrowingNumericConversion (ec, expr, target_type, loc);
if (ne != null)
return ne;
return new UnboxCast (expr, target_type);
//
- // Skip the ExplicitReferenceConversion because we can not convert
+ // Skip the NarrowingReferenceConversion because we can not convert
// from Null to a ValueType, and ExplicitReference wont check against
// null literal explicitly
//
if (expr_type != TypeManager.null_type){
- ne = ExplicitReferenceConversion (expr, target_type);
+ ne = NarrowingReferenceConversion (expr, target_type);
if (ne != null)
return ne;
}
if (e != null){
Expression ci, ce;
- ci = ImplicitConversionStandard (ec, e, target_type, loc);
+ ci = WideningConversionStandard (ec, e, target_type, loc);
if (ci != null)
return ci;
- ce = ExplicitNumericConversion (ec, e, target_type, loc);
+ ce = NarrowingNumericConversion (ec, e, target_type, loc);
if (ce != null)
return ce;
//
}
}
- ne = ExplicitUserConversion (ec, expr, target_type, loc);
- if (ne != null)
- return ne;
+ //
+ // VB.NET has no notion of User defined conversions
+ //
+
+// ne = ExplicitUserConversion (ec, expr, target_type, loc);
+// if (ne != null)
+// return ne;
if (expr is NullLiteral){
Report.Error (37, loc, "Cannot convert null to value type `" +
}
/// <summary>
- /// Same as ExplicitConversion, only it doesn't include user defined conversions
+ /// Same as WideningAndNarrowingConversion, only it doesn't include user defined conversions
/// </summary>
- static public Expression ExplicitConversionStandard (EmitContext ec, Expression expr,
+ static public Expression WideningAndNarrowingConversionStandard (EmitContext ec, Expression expr,
Type target_type, Location l)
{
int errors = Report.Errors;
- Expression ne = ImplicitConversionStandard (ec, expr, target_type, l);
+ Expression ne = WideningConversionStandard (ec, expr, target_type, l);
if (Report.Errors > errors)
return null;
if (ne != null)
return ne;
- ne = ExplicitNumericConversion (ec, expr, target_type, l);
+ ne = NarrowingNumericConversion (ec, expr, target_type, l);
if (ne != null)
return ne;
- ne = ExplicitReferenceConversion (expr, target_type);
+ ne = NarrowingReferenceConversion (expr, target_type);
if (ne != null)
return ne;