+ protected virtual void CheckIDiposableConversion (BlockContext bc, LocalVariable li, Expression initializer)
+ {
+ var type = li.Type;
+
+ if (type != TypeManager.idisposable_type && !type.ImplementsInterface (TypeManager.idisposable_type, false)) {
+ if (TypeManager.IsNullableType (type)) {
+ // it's handled in CreateDisposeCall
+ return;
+ }
+
+ bc.Report.SymbolRelatedToPreviousError (type);
+ var loc = type_expr == null ? initializer.Location : type_expr.Location;
+ bc.Report.Error (1674, loc, "`{0}': type used in a using statement must be implicitly convertible to `System.IDisposable'",
+ type.GetSignatureForError ());
+
+ return;
+ }
+ }
+
+ protected virtual Statement CreateDisposeCall (BlockContext bc, LocalVariable lv)
+ {
+ var lvr = lv.CreateReferenceExpression (bc, lv.Location);
+ var type = lv.Type;
+ var loc = lv.Location;
+
+ if (TypeManager.void_dispose_void == null) {
+ TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
+ TypeManager.idisposable_type, "Dispose", loc, TypeSpec.EmptyTypes);
+ }
+
+ var dispose_mg = MethodGroupExpr.CreatePredefined (TypeManager.void_dispose_void, TypeManager.idisposable_type, loc);
+ dispose_mg.InstanceExpression = TypeManager.IsNullableType (type) ?
+ new Cast (new TypeExpression (TypeManager.idisposable_type, loc), lvr, loc).Resolve (bc) :
+ lvr;
+
+ Statement dispose = new StatementExpression (new Invocation (dispose_mg, null));
+
+ // Add conditional call when disposing possible null variable
+ if (!type.IsStruct || TypeManager.IsNullableType (type))
+ dispose = new If (new Binary (Binary.Operator.Inequality, lvr, new NullLiteral (loc), loc), dispose, loc);
+
+ return dispose;
+ }
+