private static void WriteMethodInvoke(LanguageWriter w, IMethodInvokeExpression exp)
 {
     WriteExpression(w, exp.Method, PREC_MEM_ACCESS > GetExpressionPrecedence(exp.Method));
     w.Write("(");
     w.WriteExpressionCollection(exp.Arguments);
     w.Write(")");
 }
 private static void WriteArrayIndexerExpression(LanguageWriter w, IArrayIndexerExpression exp)
 {
     w.WriteExpression(exp.Target);
     w.Write("[");
     w.WriteExpressionCollection(exp.Indices);
     w.Write("]");
 }
        private static void WriteArrayCreate(LanguageWriter w, IArrayCreateExpression exp)
        {
            w.WriteKeyword("gcnew");
            w.Write(" ");
            w.WriteKeyword("array");
            w.Write("<");

            new TypeRef(exp.Type).WriteNameWithRef(w);
            if (exp.Dimensions != null && exp.Dimensions.Count > 1)
            {
                w.Write(", ");
                w.WriteAsLiteral(exp.Dimensions.Count);
            }
            w.Write(">");

            // 要素数の指定
            if (exp.Dimensions != null)
            {
                w.Write("(");
                w.WriteExpressionCollection(exp.Dimensions);
                w.Write(")");
            }

            // {a, b, ... 要素の指定}
            IBlockExpression initializer = exp.Initializer;

            if (initializer != null)
            {
                WriteBlock(w, initializer);
            }
        }
        private void WriteVariableDecl(LanguageWriter w, bool nohandle)
        {
            if (nohandle)
            {
                IObjectCreateExpression exp_create = (IObjectCreateExpression)this.exp;

                // 変数型
                IOptionalModifier modopt = this.var_type as IOptionalModifier;
                if (modopt != null && modopt.Modifier.Namespace == "System.Runtime.CompilerServices" && modopt.Modifier.Name == "IsConst")
                {
                    this.var_type = modopt.ElementType;
                }
                new TypeRef(this.var_type).WriteName(w);

                // 変数名
                w.Write(" ");
                w.WriteDeclaration(this.var_name);

                // 初期化子
                if (exp_create.Arguments.Count == 0)
                {
                    w.WriteComment(" /* 既定のコンストラクタ */");
                }
                else
                {
                    w.Write("(");
                    w.WriteExpressionCollection(exp_create.Arguments);
                    w.Write(")");
                }
            }
            else
            {
                // = で代入の場合: ハンドル表記でないと、コンストラクタ呼び出しになってしまう

                // 変数型
                new TypeRef(this.var_type).WriteNameWithRef(w);

                // 変数名
                w.Write(" ");
                w.WriteDeclaration(this.var_name);

                // 代入する値
                w.Write("=");
                ExpressionWriter.WriteExpression(w, this.exp, false);
            }

            w.Write(";");
        }
        private static void WriteObjectCreate(LanguageWriter w, IObjectCreateExpression exp)
        {
            if (exp.Constructor == null)
            {
                // 構造体のデフォルトコンストラクタ (StatementAnalyze でフィルタリングされている筈だけれども)
                new TypeRef(exp.Type).WriteName(w);
#if FALSE
                w.Write("(");
#warning 構造体デフォルトコンストラクタ 対応漏れがあるかもしれないので保留
                w.WriteComment("/* C++/CLI では本来は T value; 等と書く筈です。*/");
                w.Write(") ");
#else
                w.Write("()");
#endif
            }
            else
            {
                ITypeReference declaringType = exp.Constructor.DeclaringType as ITypeReference;
                TypeRef        decl_type     = new TypeRef(exp.Constructor.DeclaringType);
                if (decl_type.IsRefType)
                {
                    w.WriteKeyword("gcnew");
                    w.Write(" ");
                }
                decl_type.WriteName(w);

                w.Write("(");
                w.WriteExpressionCollection(exp.Arguments);
                w.Write(")");
            }

            if (exp.Initializer != null)
            {
                WriteBlock(w, exp.Initializer);
            }
        }
        private void WriteCustomAttribute(ICustomAttribute attr)
        {
            IMethodReference meth_ref = attr.Constructor;
            TypeRef          decltype = new TypeRef(meth_ref.DeclaringType);
            string           name     = decltype.Name;

            // 参照付きで名前を指定
            writer.WriteReference(
                name.EndsWith("Attribute")?name.Substring(0, name.Length - 9):name,
                string.Format("/* 属性 コンストラクタ */\r\n{0}::{1}({2});",
                              decltype.FullName,
                              decltype.Name,
                              LanguageWriter.GetDesc(meth_ref.Parameters)
                              ),
                meth_ref
                );

            if (attr.Arguments.Count != 0)
            {
                writer.Write("(");
                writer.WriteExpressionCollection(attr.Arguments);
                writer.Write(")");
            }
        }
 private static void WriteBlock(LanguageWriter w, IBlockExpression exp)
 {
     w.Write("{");
     w.WriteExpressionCollection(((IBlockExpression)exp).Expressions);
     w.Write("}");
 }
        public static void WriteExpression(LanguageWriter w, IExpression exp, bool paren)
        {
            if (paren)
            {
                w.Write("(");
            }
            switch (GetExpressionType(exp))
            {
            case ExpressionType.AddressDereference:
                WriteAddressDereference(w, (IAddressDereferenceExpression)exp);
                break;

            case ExpressionType.AddressOf:
                w.Write("&");
                WriteExpression(w, ((IAddressOfExpression)exp).Expression, false);
                break;

            case ExpressionType.AddressOut:                                     // 引数 out 渡し
                WriteExpression(w, ((IAddressOutExpression)exp).Expression, false);
                break;

            case ExpressionType.AddressReference:                       // 引数 ref 渡し
                WriteExpression(w, ((IAddressReferenceExpression)exp).Expression, false);
                break;

            case ExpressionType.ArgumentList:
                w.WriteKeyword("__arglist");
                break;

            case ExpressionType.ArgumentReference:
                w.WriteParameterReference(((IArgumentReferenceExpression)exp).Parameter);
                break;

            case ExpressionType.ArrayCreate:
                WriteArrayCreate(w, (IArrayCreateExpression)exp);
                break;

            case ExpressionType.ArrayIndexer:
                WriteArrayIndexerExpression(w, (IArrayIndexerExpression)exp);
                break;

            case ExpressionType.Assign:
                WriteAssign(w, (IAssignExpression)exp);
                break;

            case ExpressionType.BaseReference:
                w.baseType.WriteName(w);
                break;

            case ExpressionType.Binary:
                WriteBinary(w, (IBinaryExpression)exp);
                break;

            case ExpressionType.Block:
                WriteBlock(w, (IBlockExpression)exp);
                break;

            case ExpressionType.CanCast:
                WriteCanCast(w, (ICanCastExpression)exp);
                break;

            case ExpressionType.Cast:
                WriteCast(w, (ICastExpression)exp);
                break;

            case ExpressionType.Condition:
                WriteCondition(w, (IConditionExpression)exp);
                break;

            case ExpressionType.DelegateCreate:
                WriteDelegateCreate(w, (IDelegateCreateExpression)exp);
                break;

            case ExpressionType.Literal:
                w.WriteAsLiteral(((ILiteralExpression)exp).Value);
                break;

            case ExpressionType.MethodInvoke:
                WriteMethodInvoke(w, (IMethodInvokeExpression)exp);
                break;

            case ExpressionType.ObjectCreate:
                WriteObjectCreate(w, (IObjectCreateExpression)exp);
                break;

            case ExpressionType.SizeOf:
                w.WriteKeyword("sizeof");
                w.Write("(");
                new TypeRef(((ISizeOfExpression)exp).Type).WriteName(w);
                w.Write(")");
                break;

            case ExpressionType.Snippet:
                w.WriteAsLiteral(((ISnippetExpression)exp).Value);
                break;

            case ExpressionType.ThisReference:
                w.WriteKeyword("this");
                break;

            case ExpressionType.TryCast:
                WriteTryCast(w, (ITryCastExpression)exp);
                break;

            case ExpressionType.TypeOf:
                new TypeRef(((ITypeOfExpression)exp).Type).WriteName(w);
                w.Write("::");
                w.WriteKeyword("typeid");
                break;

            case ExpressionType.TypeReference:
                WriteTypeReference(w, (ITypeReferenceExpression)exp);
                break;

            case ExpressionType.Unary:
                WriteUnary(w, (IUnaryExpression)exp);
                break;

            case ExpressionType.VariableDeclaration:
                WriteVariableDeclaration(w, ((IVariableDeclarationExpression)exp).Variable);
                break;

            case ExpressionType.VariableReference:
                w.WriteVariableReference(((IVariableReferenceExpression)exp).Variable);
                break;

            case ExpressionType.MemberInitializer:                     // 属性の初期化の際のメンバ指定
                WriteMemberInitializer(w, (IMemberInitializerExpression)exp);
                break;

            //---------------------------------------------------
            // メンバアクセス
            //---------------------------------------------------
            case ExpressionType.EventReference:
                WriteEventReference(w, (IEventReferenceExpression)exp);
                break;

            case ExpressionType.FieldReference:
                IFieldReferenceExpression exp_fld = (IFieldReferenceExpression)exp;
                WriteMemberAccess(w, exp_fld.Target);
                w.WriteFieldReference(exp_fld.Field);
                break;

            case ExpressionType.PropertyReference:
                WritePropertyReference(w, (IPropertyReferenceExpression)exp);
                break;

            case ExpressionType.PropertyIndexer:
                IPropertyIndexerExpression exp_pind = (IPropertyIndexerExpression)exp;
                WritePropertyReference(w, exp_pind.Target);
                w.Write("[");
                w.WriteExpressionCollection(exp_pind.Indices);
                w.Write("]");
                break;

            case ExpressionType.MethodReference:
                IMethodReferenceExpression exp_meth = (IMethodReferenceExpression)exp;
                WriteMemberAccess(w, exp_meth.Target);
                w.WriteMethodReference(exp_meth.Method);
                break;

            //---------------------------------------------------
            //	代替
            //---------------------------------------------------
            case ExpressionType.StackAlloc:
                WriteStackAllocate(w, (IStackAllocateExpression)exp);
                break;

            case ExpressionType.AnonymousMethod:
                WriteAnonymousMethod(w, (IAnonymousMethodExpression)exp);
                break;

            //---------------------------------------------------
            //	以下未対応
            //---------------------------------------------------
            case ExpressionType.NullCoalescing:
                WriteBinaryNullCoalescing(w, (INullCoalescingExpression)exp);
                break;

            case ExpressionType.DelegateInvoke:
            case ExpressionType.FieldOf:
            case ExpressionType.GenericDefault:
            case ExpressionType.Lambda:
            case ExpressionType.MethodOf:
            case ExpressionType.Query:
                goto default;

            case ExpressionType.TypedReferenceCreate:
            case ExpressionType.TypeOfTypedReference:
            case ExpressionType.ValueOfTypedReference:
                //throw new System.NotImplementedException("未だ実装していません\r\n");
                goto default;

            case ExpressionType.Unknown:
            default:
                ThrowUnknownExpression(exp);
                break;
            }
            if (paren)
            {
                w.Write(")");
            }
        }
        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();
            }
            //*/
        }