protected internal override Statement VisitUsingInstruction(UsingInstruction inst) { var transformed = TransformToForeach(inst, out var resource); if (transformed != null) { return(transformed); } AstNode usingInit = resource; var var = inst.Variable; if (!inst.ResourceExpression.MatchLdNull() && !NullableType.GetUnderlyingType(var.Type).GetAllBaseTypes().Any(b => b.IsKnownType(KnownTypeCode.IDisposable))) { var.Kind = VariableKind.Local; var disposeType = exprBuilder.compilation.FindType(KnownTypeCode.IDisposable); var disposeVariable = currentFunction.RegisterVariable( VariableKind.Local, disposeType, AssignVariableNames.GenerateVariableName(currentFunction, disposeType) ); return(new BlockStatement { new ExpressionStatement(new AssignmentExpression(exprBuilder.ConvertVariable(var).Expression, resource.Detach())), new TryCatchStatement { TryBlock = ConvertAsBlock(inst.Body), FinallyBlock = new BlockStatement() { new ExpressionStatement(new AssignmentExpression(exprBuilder.ConvertVariable(disposeVariable).Expression, new AsExpression(exprBuilder.ConvertVariable(var).Expression, exprBuilder.ConvertType(disposeType)))), new IfElseStatement { Condition = new BinaryOperatorExpression(exprBuilder.ConvertVariable(disposeVariable), BinaryOperatorType.InEquality, new NullReferenceExpression()), TrueStatement = new ExpressionStatement(new InvocationExpression(new MemberReferenceExpression(exprBuilder.ConvertVariable(disposeVariable).Expression, "Dispose"))) } } }, }); } else { if (var.LoadCount > 0 || var.AddressCount > 0) { var type = settings.AnonymousTypes && var.Type.ContainsAnonymousType() ? new SimpleType("var") : exprBuilder.ConvertType(var.Type); var vds = new VariableDeclarationStatement(type, var.Name, resource); vds.Variables.Single().AddAnnotation(new ILVariableResolveResult(var, var.Type)); usingInit = vds; } return(new UsingStatement { ResourceAcquisition = usingInit, EmbeddedStatement = ConvertAsBlock(inst.Body) }); } }
internal void RegisterMove(ILInstruction predecessor) { FlagsBeingMoved |= predecessor.Flags; MoveActions.Add(delegate { var v = Function.RegisterVariable(VariableKind.StackSlot, predecessor.ResultType); predecessor.ReplaceWith(new LdLoc(v)); return(new StLoc(v, predecessor)); }); }
internal void RegisterMove(ILInstruction predecessor) { FlagsBeingMoved |= predecessor.Flags; MoveActions.Add(delegate { var type = context.TypeSystem.FindType(predecessor.ResultType.ToKnownTypeCode()); var v = Function.RegisterVariable(VariableKind.StackSlot, type); predecessor.ReplaceWith(new LdLoc(v)); return(new StLoc(v, predecessor)); }); }