public static Expression ImplicitTypeParameterConversion (Expression expr, TypeParameterSpec expr_type, TypeSpec target_type) { // // From T to a type parameter U, provided T depends on U // if (target_type.IsGenericParameter) { if (expr_type.TypeArguments != null && expr_type.HasDependencyOn (target_type)) { if (expr == null) return EmptyExpression.Null; if (expr_type.IsReferenceType && !((TypeParameterSpec) target_type).IsReferenceType) return new BoxedCast (expr, target_type); return new ClassCast (expr, target_type); } return null; } // // LAMESPEC: From T to dynamic type because it's like T to object // if (target_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { if (expr == null) return EmptyExpression.Null; if (expr_type.IsReferenceType) return new ClassCast (expr, target_type); return new BoxedCast (expr, target_type); } // // From T to its effective base class C // From T to any base class of C (it cannot contain dynamic or be of dynamic type) // From T to any interface implemented by C // var base_type = expr_type.GetEffectiveBase (); if (base_type == target_type || TypeSpec.IsBaseClass (base_type, target_type, false) || base_type.ImplementsInterface (target_type, true)) { if (expr == null) return EmptyExpression.Null; if (expr_type.IsReferenceType) return new ClassCast (expr, target_type); return new BoxedCast (expr, target_type); } if (target_type.IsInterface && expr_type.IsConvertibleToInterface (target_type)) { if (expr == null) return EmptyExpression.Null; if (expr_type.IsReferenceType) return new ClassCast (expr, target_type); return new BoxedCast (expr, target_type); } return null; }
public Class(TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs) : base(parent, name, attrs, MemberKind.Class) { var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE; this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report); spec = new TypeSpec (Kind, null, this, null, ModFlags); }
public Lifted(Expression expr, Unwrap unwrap, TypeSpec type) { this.expr = expr; this.unwrap = unwrap; this.loc = expr.Location; this.type = type; }
static bool IsValidEnumType (TypeSpec t) { return (t == TypeManager.int32_type || t == TypeManager.uint32_type || t == TypeManager.int64_type || t == TypeManager.byte_type || t == TypeManager.sbyte_type || t == TypeManager.short_type || t == TypeManager.ushort_type || t == TypeManager.uint64_type || t == TypeManager.char_type || TypeManager.IsEnumType (t)); }
// TODO: Replace IMemberContext with MemberCore public EmitContext (IMemberContext rc, ILGenerator ig, TypeSpec return_type) { this.MemberContext = rc; this.ig = ig; this.return_type = return_type; }
public static TypeSpec CreateDelegateType (ResolveContext rc, AParametersCollection parameters, TypeSpec returnType, Location loc) { Namespace type_ns = rc.Module.GlobalRootNamespace.GetNamespace ("System", true); if (type_ns == null) { return null; } if (returnType == rc.BuiltinTypes.Void) { var actArgs = parameters.Types; var actionSpec = type_ns.LookupType (rc.Module, "Action", actArgs.Length, LookupMode.Normal, loc).ResolveAsType(rc); if (actionSpec == null) { return null; } if (actArgs.Length == 0) return actionSpec; else return actionSpec.MakeGenericType(rc, actArgs); } else { TypeSpec[] funcArgs = new TypeSpec[parameters.Types.Length + 1]; parameters.Types.CopyTo(funcArgs, 0); funcArgs[parameters.Types.Length] = returnType; var funcSpec = type_ns.LookupType (rc.Module, "Func", funcArgs.Length, LookupMode.Normal, loc).ResolveAsType(rc); if (funcSpec == null) return null; return funcSpec.MakeGenericType(rc, funcArgs); } }
// // From a one-dimensional array-type S[] to System.Collections.IList<T> and base // interfaces of this interface, provided there is an implicit reference conversion // from S to T. // static bool ArrayToIList (ArrayContainer array, TypeSpec list, bool isExplicit) { if (array.Rank != 1 || !list.IsGeneric) return false; var open_version = list.GetDefinition (); if ((open_version != TypeManager.generic_ilist_type) && (open_version != TypeManager.generic_icollection_type) && (open_version != TypeManager.generic_ienumerable_type)) return false; var arg_type = list.TypeArguments[0]; if (array.Element == arg_type) return true; if (isExplicit) return ExplicitReferenceConversionExists (array.Element, arg_type); if (MyEmptyExpr == null) MyEmptyExpr = new EmptyExpression (array.Element); else MyEmptyExpr.SetType (array.Element); return ImplicitReferenceConversionExists (MyEmptyExpr, arg_type); }
/// <summary> /// Performs an explicit conversion of the expression `expr' whose /// type is expr.Type to `target_type'. /// </summary> public static Expression ExplicitConversion(ResolveContext ec, Expression expr, TypeSpec target_type, Location loc) { Expression e = ExplicitConversionCore (ec, expr, target_type, loc); if (e != null) { // // Don't eliminate explicit precission casts // if (e == expr) { if (target_type.BuiltinType == BuiltinTypeSpec.Type.Float) return new OpcodeCast (expr, target_type, OpCodes.Conv_R4); if (target_type.BuiltinType == BuiltinTypeSpec.Type.Double) return new OpcodeCast (expr, target_type, OpCodes.Conv_R8); } return e; } TypeSpec expr_type = expr.Type; if (target_type.IsNullableType) { TypeSpec target; if (expr_type.IsNullableType) { target = Nullable.NullableInfo.GetUnderlyingType (target_type); Expression unwrap = Nullable.Unwrap.Create (expr); e = ExplicitConversion (ec, unwrap, target, expr.Location); if (e == null) return null; return new Nullable.LiftedConversion (e, unwrap, target_type).Resolve (ec); } if (expr_type.BuiltinType == BuiltinTypeSpec.Type.Object) { return new UnboxCast (expr, target_type); } target = TypeManager.GetTypeArguments (target_type) [0]; e = ExplicitConversionCore (ec, expr, target, loc); if (e != null) return TypeSpec.IsReferenceType (expr.Type) ? new UnboxCast (expr, target_type) : Nullable.Wrap.Create (e, target_type); } else if (expr_type.IsNullableType) { e = ImplicitBoxingConversion (expr, Nullable.NullableInfo.GetUnderlyingType (expr_type), target_type); if (e != null) return e; e = Nullable.Unwrap.Create (expr, false); e = ExplicitConversionCore (ec, e, target_type, loc); if (e != null) return EmptyCast.Create (e, target_type); } e = ExplicitUserConversion (ec, expr, target_type, loc); if (e != null) return e; expr.Error_ValueCannotBeConverted (ec, target_type, true); return null; }
public BoolConstant(TypeSpec type, bool val, Location loc) : base(loc) { eclass = ExprClass.Value; this.type = type; Value = val; }
public Constant ImplicitConversionRequired (ResolveContext ec, TypeSpec type, Location loc) { Constant c = ConvertImplicitly (type); if (c == null) Error_ValueCannotBeConverted (ec, type, false); return c; }
public Class(NamespaceEntry ns, DeclSpace parent, MemberName name, Modifiers mod, Attributes attrs) : base(ns, parent, name, attrs, MemberKind.Class) { var accmods = (Parent == null || Parent.Parent == null) ? Modifiers.INTERNAL : Modifiers.PRIVATE; this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report); spec = new TypeSpec (Kind, null, this, null, ModFlags); }
protected CompilerGeneratedContainer (TypeContainer parent, MemberName name, Modifiers mod, MemberKind kind) : base (parent, name, null, kind) { Debug.Assert ((mod & Modifiers.AccessibilityMask) != 0); ModFlags = mod | Modifiers.COMPILER_GENERATED | Modifiers.SEALED; spec = new TypeSpec (Kind, null, this, null, ModFlags); }
public bool ResolveType(IMemberContext mc, TypeSpec defaultType) { if (TypeExpression != null) this.Type = TypeExpression.ResolveAsType (mc); else this.Type = defaultType; return this.Type != null; }
public TypeParameterInflator(TypeSpec type, TypeParameterSpec[] tparams, TypeSpec[] targs) { if (tparams.Length != targs.Length) throw new ArgumentException ("Invalid arguments"); this.tparams = tparams; this.targs = targs; this.type = type; }
// // Our constructor // public Iterator(ParametersBlock block, IMethodData method, TypeContainer host, TypeSpec iterator_type, bool is_enumerable) : base(block, TypeManager.bool_type, block.StartLocation) { this.OriginalMethod = method; this.OriginalIteratorType = iterator_type; this.IsEnumerable = is_enumerable; this.Host = host; this.type = method.ReturnType; }
/// <summary> /// Performs an explicit conversion of the expression `expr' whose /// type is expr.Type to `target_type'. /// </summary> public static Expression ExplicitConversion(ResolveContext ec, Expression expr, TypeSpec target_type, Location loc) { Expression e = ExplicitConversionCore (ec, expr, target_type, loc); if (e != null) { // // Don't eliminate explicit precission casts // if (e == expr) { if (target_type == TypeManager.float_type) return new OpcodeCast (expr, target_type, OpCodes.Conv_R4); if (target_type == TypeManager.double_type) return new OpcodeCast (expr, target_type, OpCodes.Conv_R8); } return e; } TypeSpec expr_type = expr.Type; if (TypeManager.IsNullableType (target_type)) { if (TypeManager.IsNullableType (expr_type)) { TypeSpec target = Nullable.NullableInfo.GetUnderlyingType (target_type); Expression unwrap = Nullable.Unwrap.Create (expr); e = ExplicitConversion (ec, unwrap, target, expr.Location); if (e == null) return null; return new Nullable.Lifted (e, unwrap, target_type).Resolve (ec); } else if (expr_type == TypeManager.object_type) { return new UnboxCast (expr, target_type); } else { TypeSpec target = TypeManager.GetTypeArguments (target_type) [0]; e = ExplicitConversionCore (ec, expr, target, loc); if (e != null) return Nullable.Wrap.Create (e, target_type); } } else if (TypeManager.IsNullableType (expr_type)) { bool use_class_cast; if (ImplicitBoxingConversionExists (Nullable.NullableInfo.GetUnderlyingType (expr_type), target_type, out use_class_cast)) return new BoxedCast (expr, target_type); e = Nullable.Unwrap.Create (expr, false); e = ExplicitConversionCore (ec, e, target_type, loc); if (e != null) return EmptyCast.Create (e, target_type); } e = ExplicitUserConversion (ec, expr, target_type, loc); if (e != null) return e; expr.Error_ValueCannotBeConverted (ec, loc, target_type, true); return null; }
public static void Error_InvalidConstantType(TypeSpec t, Location loc, Report Report) { if (t.IsGenericParameter) { Report.Error (1959, loc, "Type parameter `{0}' cannot be declared const", TypeManager.CSharpName (t)); } else { Report.Error (283, loc, "The type `{0}' cannot be declared const", TypeManager.CSharpName (t)); } }
public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl) { if (!expl && IsLiteral && BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (target) && BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (type)) { ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'", GetValueAsLiteral (), TypeManager.CSharpName (target)); } else { base.Error_ValueCannotBeConverted (ec, target, expl); } }
public BlockContext (IMemberContext mc, ExplicitBlock block, TypeSpec returnType) : base (mc) { if (returnType == null) throw new ArgumentNullException ("returnType"); this.return_type = returnType; // TODO: check for null value CurrentBlock = block; }
public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl) { if (!expl && IsLiteral && (TypeManager.IsPrimitiveType (target) || type == TypeManager.decimal_type) && (TypeManager.IsPrimitiveType (type) || type == TypeManager.decimal_type)) { ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'", AsString (), TypeManager.CSharpName (target)); } else { base.Error_ValueCannotBeConverted (ec, loc, target, expl); } }
static bool IList_To_Array(TypeSpec list, ArrayContainer array) { if (array.Rank != 1 || !list.IsGenericIterateInterface) return false; var arg_type = list.TypeArguments[0]; if (array.Element == arg_type) return true; return ImplicitReferenceConversionExists (array.Element, arg_type) || ExplicitReferenceConversionExists (array.Element, arg_type); }
public Delegate(TypeContainer parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, ParametersCompiled param_list, Attributes attrs) : base(parent, name, attrs, MemberKind.Delegate) { this.ReturnType = type; ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod_flags, IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE, name.Location, Report); parameters = param_list; spec = new TypeSpec (Kind, null, this, null, ModFlags | Modifiers.SEALED); }
public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl) { if (!expl && IsLiteral && type.BuiltinType != BuiltinTypeSpec.Type.Double && BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (target) && BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (type)) { ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'", GetValueAsLiteral (), target.GetSignatureForError ()); } else { base.Error_ValueCannotBeConverted (ec, target, expl); } }
public Class(NamespaceEntry ns, DeclSpace parent, MemberName name, Modifiers mod, Attributes attrs) : base(ns, parent, name, attrs, MemberKind.Class) { var accmods = (Parent == null || Parent.Parent == null) ? Modifiers.INTERNAL : Modifiers.PRIVATE; this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report); spec = new TypeSpec (Kind, null, this, null, ModFlags); if (IsStatic && RootContext.Version == LanguageVersion.ISO_1) { Report.FeatureIsNotAvailable (Location, "static classes"); } }
// // Our constructor // private Iterator(CompilerContext ctx, IMethodData method, TypeContainer host, TypeSpec iterator_type, bool is_enumerable) : base(new ToplevelBlock (ctx, method.Block, ParametersCompiled.EmptyReadOnlyParameters, method.Block.StartLocation), TypeManager.bool_type, method.Location) { this.OriginalMethod = method; this.OriginalIteratorType = iterator_type; this.IsEnumerable = is_enumerable; this.Host = host; this.type = method.ReturnType; IteratorHost = Block.ChangeToIterator (this, method.Block); }
public EmitContext (IMemberContext rc, ILGenerator ig, TypeSpec return_type) { this.member_context = rc; this.ig = ig; this.return_type = return_type; if (rc.Module.Compiler.Settings.Checked) flags |= Options.CheckedScope; #if STATIC ig.__CleverExceptionBlockAssistance (); #endif }
// // From a one-dimensional array-type S[] to System.Collections.IList<T> and base // interfaces of this interface, provided there is an implicit reference conversion // from S to T. // static bool ArrayToIList (ArrayContainer array, TypeSpec list, bool isExplicit) { if (array.Rank != 1 || !list.IsGenericIterateInterface) return false; var arg_type = list.TypeArguments[0]; if (array.Element == arg_type) return true; if (isExplicit) return ExplicitReferenceConversionExists (array.Element, arg_type); return ImplicitReferenceConversionExists (array.Element, arg_type); }
// // For better error reporting where compiler tries to guess missing using directive // public List<string> FindExtensionMethodNamespaces (IMemberContext ctx, TypeSpec extensionType, string name, int arity) { List<string> res = null; foreach (var ns in all_namespaces) { var methods = ns.Value.LookupExtensionMethod (ctx, extensionType, name, arity); if (methods != null) { if (res == null) res = new List<string> (); res.Add (ns.Key); } } return res; }
static bool ConvertPromotion (ResolveContext rc, ref Constant prim, ref Constant second, TypeSpec type) { Constant c = prim.ConvertImplicitly (type); if (c != null) { prim = c; return true; } if (type.BuiltinType == BuiltinTypeSpec.Type.UInt) { type = rc.BuiltinTypes.Long; prim = prim.ConvertImplicitly (type); second = second.ConvertImplicitly (type); return prim != null && second != null; } return false; }
static bool IsValidEnumType (TypeSpec t) { switch (t.BuiltinType) { case BuiltinTypeSpec.Type.Int: case BuiltinTypeSpec.Type.UInt: case BuiltinTypeSpec.Type.Long: case BuiltinTypeSpec.Type.Byte: case BuiltinTypeSpec.Type.SByte: case BuiltinTypeSpec.Type.Short: case BuiltinTypeSpec.Type.UShort: case BuiltinTypeSpec.Type.ULong: case BuiltinTypeSpec.Type.Char: return true; default: return t.IsEnum; } }