Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        //===========================================================
        //		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);
        }
Ejemplo n.º 3
0
        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();
            }
            //*/
        }