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(); }