コード例 #1
0
ファイル: CsToLua_Object.cs プロジェクト: hexiaoweiff8/Cs2Lua
        public override void VisitConstructorDeclaration(ConstructorDeclarationSyntax node)
        {
            bool          isExportConstructor = false;
            var           ci      = m_ClassInfoStack.Peek();
            IMethodSymbol declSym = m_Model.GetDeclaredSymbol(node);

            if (null != declSym)
            {
                string require = ClassInfo.GetAttributeArgument <string>(declSym, "Cs2Lua.RequireAttribute", 0);
                if (!string.IsNullOrEmpty(require))
                {
                    SymbolTable.Instance.AddRequire(ci.Key, require);
                }
                if (ClassInfo.HasAttribute(declSym, "Cs2Lua.IgnoreAttribute"))
                {
                    return;
                }
                if (declSym.IsAbstract)
                {
                    return;
                }
                isExportConstructor = ClassInfo.HasAttribute(declSym, "Cs2Lua.ExportAttribute");
            }

            bool            generateBasicCtor  = false;
            bool            generateBasicCctor = false;
            ClassSymbolInfo csi;

            if (SymbolTable.Instance.ClassSymbols.TryGetValue(ci.Key, out csi))
            {
                generateBasicCtor  = csi.GenerateBasicCtor;
                generateBasicCctor = csi.GenerateBasicCctor;
            }

            bool isStatic = declSym.IsStatic;
            var  mi       = new MethodInfo();

            mi.Init(declSym, node);
            m_MethodInfoStack.Push(mi);

            string manglingName = NameMangling(declSym);

            if (isStatic)
            {
                ci.ExistStaticConstructor = true;
            }
            else
            {
                ci.ExistConstructor = true;

                if (isExportConstructor)
                {
                    ci.ExportConstructor     = manglingName;
                    ci.ExportConstructorInfo = mi;
                }
                else if (string.IsNullOrEmpty(ci.ExportConstructor))
                {
                    //有构造但还没有明确指定的导出构造,则使用第一次遇到的构造
                    ci.ExportConstructor     = manglingName;
                    ci.ExportConstructorInfo = mi;
                }
            }

            bool myselfDefinedBaseClass = SymbolTable.Instance.IsCs2LuaSymbol(ci.SemanticInfo.BaseType);

            CodeBuilder.AppendFormat("{0}{1} = function({2}", GetIndentString(), manglingName, isStatic ? string.Empty : "this");
            if (mi.ParamNames.Count > 0)
            {
                if (!isStatic)
                {
                    CodeBuilder.Append(", ");
                }
                CodeBuilder.Append(string.Join(", ", mi.ParamNames.ToArray()));
            }
            CodeBuilder.Append(")");
            CodeBuilder.AppendLine();
            ++m_Indent;
            if (mi.ValueParams.Count > 0)
            {
                OutputWrapValueParams(CodeBuilder, mi);
            }
            if (!string.IsNullOrEmpty(mi.OriginalParamsName))
            {
                if (mi.ParamsIsValueType)
                {
                    CodeBuilder.AppendFormat("{0}local {1} = wrapvaluetypearray{{...}};", GetIndentString(), mi.OriginalParamsName);
                }
                else if (mi.ParamsIsExternValueType)
                {
                    CodeBuilder.AppendFormat("{0}local {1} = wrapexternvaluetypearray{{...}};", GetIndentString(), mi.OriginalParamsName);
                }
                else
                {
                    CodeBuilder.AppendFormat("{0}local {1} = wraparray{{...}};", GetIndentString(), mi.OriginalParamsName);
                }
                CodeBuilder.AppendLine();
            }
            //首先执行初始化列表
            var init = node.Initializer;

            if (null != init)
            {
                var    oper          = m_Model.GetOperation(init) as IInvocationExpression;
                string manglingName2 = NameMangling(oper.TargetMethod);
                if (init.ThisOrBaseKeyword.Text == "this")
                {
                    CodeBuilder.AppendFormat("{0}this:{1}(", GetIndentString(), manglingName2);
                }
                else if (init.ThisOrBaseKeyword.Text == "base")
                {
                    CodeBuilder.AppendFormat("{0}this.base.{1}(this", GetIndentString(), manglingName2);
                    if (init.ArgumentList.Arguments.Count > 0)
                    {
                        CodeBuilder.Append(", ");
                    }
                }
                VisitArgumentList(init.ArgumentList);
                CodeBuilder.AppendLine(");");
            }
            //再执行构造函数内容(字段初始化部分)
            if (isStatic)
            {
                if (!string.IsNullOrEmpty(ci.BaseKey) && myselfDefinedBaseClass)
                {
                    CodeBuilder.AppendFormat("{0}{1}.cctor();", GetIndentString(), ci.BaseKey);
                    CodeBuilder.AppendLine();
                }
                if (generateBasicCctor)
                {
                    CodeBuilder.AppendFormat("{0}{1}.__cctor();", GetIndentString(), ci.Key);
                    CodeBuilder.AppendLine();
                }
            }
            else
            {
                if (!string.IsNullOrEmpty(ci.BaseKey) && !ClassInfo.IsBaseInitializerCalled(node, m_Model) && myselfDefinedBaseClass)
                {
                    //如果当前构造没有调父类构造并且委托的其它构造也没有调父类构造,则调用默认构造。
                    CodeBuilder.AppendFormat("{0}this.base.ctor(this);", GetIndentString());
                    CodeBuilder.AppendLine();
                }
                if (generateBasicCtor)
                {
                    CodeBuilder.AppendFormat("{0}this:__ctor({1});", GetIndentString(), string.Join(", ", mi.GenericTypeTypeParamNames.ToArray()));
                    CodeBuilder.AppendLine();
                }
            }
            //再执行构造函数内容(构造函数部分)
            if (null != node.Body)
            {
                VisitBlock(node.Body);
            }
            if (!mi.ExistTopLevelReturn)
            {
                if (mi.ReturnParamNames.Count > 0)
                {
                    CodeBuilder.AppendFormat("{0}return this, {1};", GetIndentString(), string.Join(", ", mi.ReturnParamNames));
                    CodeBuilder.AppendLine();
                }
                else if (!isStatic)
                {
                    CodeBuilder.AppendFormat("{0}return this;", GetIndentString());
                    CodeBuilder.AppendLine();
                }
            }
            --m_Indent;
            CodeBuilder.AppendFormat("{0}end,", GetIndentString());
            CodeBuilder.AppendLine();
            m_MethodInfoStack.Pop();
        }