internal override Node Bind(Binder b) { b.OpenScope(); if (Expr != null) { b.Bind(ref Expr); Expr.RequireGetAccess(); } else { b.Bind(ref Decl); } b.Bind(ref Stmt); b.CloseScope(); var u = Decl != null ? Decl.VarDecls[0].Var : b.AddLocal(Expr.Datatype); var udecl = Decl ?? DeclStmt.Bound(VarDecl.Bound(u, Expr, b.Options.Binding)); Expr du = AsTypeExpr.Bound(IdExpr.Bound(u), IdExpr.Bound(Compilation.Get(WellKnownTypes.System_IDisposable))); b.Cache(ref du); var cond = BinaryExpr.Bound(du, Expr.Token, LiteralExpr.Bound(Constant.Null), BinaryOperatorKind.NotEqual, b.Options.Binding); var exit = IfStmt.Bound(cond, ExprStmt.Bound(MethodCallExpr.Bound(b, null, Compilation.Get(WellKnownMembers.System_IDisposable_Dispose), du, ArgList.Empty)), null); return(StmtBlock.Bound(udecl, TryStmt.Bound(b, Stmt, exit))); }
internal override Node Bind(Binder b) { b.OpenScope(); b.Bind(ref Key); Key.RequireGetAccess(); if (Key.Datatype.IsValueType) { throw Error(ErrorCode.RequireReferenceType); } b.Bind(ref Stmt); b.CloseScope(); var k = b.AddLocal(Compilation.Get(NativeType.Object)); b.Convert(ref Key, Compilation.Get(NativeType.Object)); var kdecl = DeclStmt.Bound(VarDecl.Bound(k, Key, b.Options.Binding)); var l = b.AddLocal(Compilation.Get(NativeType.Boolean)); var ldecl = DeclStmt.Bound(VarDecl.Bound(l, LiteralExpr.Bound(Constant.Create(false)), b.Options.Binding)); var enter = ExprStmt.Bound(MethodCallExpr.Bound(b, null, Compilation.Get(WellKnownMembers.System_Threading_Monitor_Enter), null, ArgList.Bound(IdExpr.Bound(k), IdExpr.Bound(l)))); var exit = IfStmt.Bound(IdExpr.Bound(l), ExprStmt.Bound(MethodCallExpr.Bound(b, null, Compilation.Get(WellKnownMembers.System_Threading_Monitor_Exit), null, ArgList.Bound(IdExpr.Bound(k)))), null); return(StmtBlock.Bound(kdecl, ldecl, TryStmt.Bound(b, StmtBlock.Bound(enter, Stmt), exit))); }