private static bool DetectLocalRefVariable(string var_disposable, IStatement next, IStatement next2, out LocalRefVariableStatement ret_lrv) { ret_lrv = new LocalRefVariableStatement(); //------------------------------------------------------- // 第二文 //------------------------------------------------------- // try{ // ... // null-declarations // var_name=var_disposable; // ... // }fault{ // var_name->Dispose(); // } ITryCatchFinallyStatement state_next = next as ITryCatchFinallyStatement; if (state_next == null || state_next.Try == null || state_next.Try.Statements.Count == 0 || state_next.Fault == null || state_next.Fault.Statements.Count != 1 ) { return(false); } // // null-declarations を飛ばす // int i_assign = 0; IStatementCollection try_states = state_next.Try.Statements; while (IsNullDeclaration(try_states[i_assign])) { if (++i_assign >= try_states.Count) { return(false); } } // // var_name=var_disposable の var_name を取得 // IAssignExpression exp_assign = GetAssignExpression(state_next.Try.Statements[i_assign]); if (exp_assign == null || var_disposable != GetVariableName(exp_assign.Expression)) { return(false); } ret_lrv.var_name = GetVariableName(exp_assign.Target); if (ret_lrv.var_name == null) { return(false); } // // fault 内の形式の確認 // { // **->**(); IMethodInvokeExpression exp_inv = GetInvokeExpression(state_next.Fault.Statements[0]); if (exp_inv == null || exp_inv.Arguments.Count != 0) { return(false); } // **->Dispose(); IMethodReferenceExpression method = exp_inv.Method as IMethodReferenceExpression; if (method == null || method.Method == null || method.Method.Name != "Dispose") { return(false); } // disposable->Dispose(); if (ret_lrv.var_name != GetVariableName(method.Target)) { return(false); } } //------------------------------------------------------- // 第三文 //------------------------------------------------------- // "Label:"? // var_name->Dispose(); // ILabeledStatement labeled = next2 as ILabeledStatement; if (labeled != null) { ret_lrv.labelname = labeled.Name; next2 = labeled.Statement; } { // **->**(); IMethodInvokeExpression exp_inv = GetInvokeExpression(next2); if (exp_inv == null || exp_inv.Arguments.Count != 0) { return(false); } // **->Dispose(); IMethodReferenceExpression method = exp_inv.Method as IMethodReferenceExpression; if (method == null || method.Method == null || method.Method.Name != "Dispose") { return(false); } // disposable->Dispose(); if (ret_lrv.var_name != GetVariableName(method.Target)) { return(false); } } ret_lrv.block = state_next.Try; ret_lrv.block.Statements.RemoveAt(i_assign); return(true); }
//=========================================================== // using の変換 //=========================================================== /// <summary> /// Using 文を他の構文に変換して、yields に変換後の Statement を書き込みます。 /// </summary> /// <param name="yields">変換後の Statement の書き込み先を指定します。</param> /// <param name="state">using 構文を表現する Statement を指定します。</param> /// <param name="last">state が Statements の中で最後の Statement か否かを指定します。</param> public static void TransformUsingStatement(Gen::List <IStatement> yields, IUsingStatement state, bool last) { // 変数の宣言の場合 IAssignExpression assig = state.Expression as IAssignExpression; if (assig != null) { do { IVariableDeclarationExpression var_decl_x = assig.Target as IVariableDeclarationExpression; if (var_decl_x == null) { continue; } IVariableDeclaration var_decl = var_decl_x.Variable as IVariableDeclaration; if (var_decl == null) { continue; } IObjectCreateExpression exp_create = assig.Expression as IObjectCreateExpression; if (exp_create != null) { LocalRefVariableStatement s_lr = new LocalRefVariableStatement(var_decl, assig.Expression, state.Body); s_lr.noblock = last; yields.Add(s_lr); } else { //yields.Add(new ExpressionStatement(assig)); //yields.Add(state.Body); //yields.Add(new DeleteStatement(new VariableReferenceExpression(var_decl))); //↑ 中で例外が起こったときのことを考えていない。 // 宣言部分と代入部分を分離 IStatement s_decl = new ExpressionStatement(var_decl_x); IStatement s_asgn = new ExpressionStatement( new AssignExpression( new VariableReferenceExpression(var_decl), assig.Expression ) ); IStatement s_delete = new DeleteStatement(new VariableReferenceExpression(var_decl)); // 宣言 yields.Add(s_decl); // try-finally BlockStatement try_block = new BlockStatement(); try_block.Statements.Add(s_asgn); try_block.Statements.AddRange(state.Body.Statements); BlockStatement finally_block = new BlockStatement(); finally_block.Statements.Add(s_delete); TryCatchFinallyStatement s_tcf = new TryCatchFinallyStatement(try_block); s_tcf.Finally = finally_block; yields.Add(s_tcf); } return; }while(false); throw new InterfaceNotImplementedException("×実装中×", typeof(IVariableDeclarationExpression), assig.Target); } // 変数の参照の場合 IVariableReferenceExpression varref = state.Expression as IVariableReferenceExpression; if (varref != null) { IStatement s_delete = new DeleteStatement(varref); // try-finally TryCatchFinallyStatement s_tcf = new TryCatchFinallyStatement(state.Body); BlockStatement finally_block = new BlockStatement(); finally_block.Statements.Add(s_delete); s_tcf.Finally = finally_block; yields.Add(s_tcf); return; } throw new InterfaceNotImplementedException( "Unexpected using-statement expression interface (expects IAssignExpression or IVariableReferenceExpression)", typeof(IAssignExpression), state.Expression); }
private static void WriteLocalRefVariable(LanguageWriter w, LocalRefVariableStatement state) { state.Write(w); return; if (!state.noblock) { w.PushScope(); //--------------------------------------------- w.Write("{"); w.WriteLine(); w.WriteIndent(); } if (!w.SuppressOutput) { //* #warning local-ref: 上層で無駄な宣言を取り除くべき if (w.scope.ContainsVariable(state.var_name)) { w.scope[state.var_name].local_scope = true; } else { w.scope.RegisterVariable(state.var_name, true); } //*/ } IObjectCreateExpression exp_create = state.exp as IObjectCreateExpression; bool nohandle = exp_create != null; // ハンドル表記でなくても良いかどうか if (nohandle) { // 変数型 IOptionalModifier modopt = state.var_type as IOptionalModifier; if (modopt != null && modopt.Modifier.Namespace == "System.Runtime.CompilerServices" && modopt.Modifier.Name == "IsConst") { state.var_type = modopt.ElementType; } new TypeRef(state.var_type).WriteName(w); // 変数名 w.Write(" "); w.WriteDeclaration(state.var_name); // 初期化子 if (exp_create.Arguments.Count == 0) { w.WriteComment(" /* 既定のコンストラクタ */"); } else { w.Write("("); w.WriteExpressionCollection(exp_create.Arguments); w.Write(")"); } } else { // = で代入の場合: ハンドル表記でないと、コンストラクタ呼び出しになってしまう // 変数型 new TypeRef(state.var_type).WriteNameWithRef(w); // 変数名 w.Write(" "); w.WriteDeclaration(state.var_name); // 代入する値 w.Write("="); ExpressionWriter.WriteExpression(w, state.exp, false); } w.Write(";"); // 後に続く内容 w.WriteLine(); WriteBlock(w, state.block); // ハンドル表記で宣言した場合はちゃんと delete if (!nohandle) { WriteStatement(w, new DeleteStatement(new VariableReferenceExpression(state.decl))); } w.WriteOutdent(); w.Write("}"); w.WriteLine(); if (state.labelname != null) { w.__WriteLabel(state.labelname); w.Write(";"); w.WriteLine(); } if (!state.noblock) { //--------------------------------------------- w.PopScope(); } //*/ }