public override void VisitIndexerDeclaration(IndexerDeclarationSyntax node) { var ci = m_ClassInfoStack.Peek(); var 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; } } StringBuilder currentBuilder = ci.CurrentCodeBuilder; if (declSym.IsStatic) { ci.CurrentCodeBuilder = ci.StaticFunctionCodeBuilder; } else { ci.CurrentCodeBuilder = ci.InstanceFunctionCodeBuilder; } foreach (var accessor in node.AccessorList.Accessors) { var sym = m_Model.GetDeclaredSymbol(accessor); if (null != sym) { var mi = new MethodInfo(); mi.Init(sym, accessor); m_MethodInfoStack.Push(mi); string manglingName = NameMangling(sym); string keyword = accessor.Keyword.Text; CodeBuilder.AppendFormat("{0}{1} = function(this, {2})", GetIndentString(), manglingName, string.Join(", ", mi.ParamNames.ToArray())); CodeBuilder.AppendLine(); ++m_Indent; bool isStatic = declSym.IsStatic; string luaModule = ClassInfo.GetAttributeArgument <string>(sym, "Cs2Lua.TranslateToAttribute", 0); string luaFuncName = ClassInfo.GetAttributeArgument <string>(sym, "Cs2Lua.TranslateToAttribute", 1); if (!string.IsNullOrEmpty(luaModule) || !string.IsNullOrEmpty(luaFuncName)) { if (!string.IsNullOrEmpty(luaModule)) { SymbolTable.Instance.AddRequire(ci.Key, luaModule); } if (sym.ReturnsVoid && mi.ReturnParamNames.Count <= 0) { CodeBuilder.AppendFormat("{0}{1}({2}", GetIndentString(), luaFuncName, isStatic ? string.Empty : "this"); } else { CodeBuilder.AppendFormat("{0}return {1}({2}", GetIndentString(), luaFuncName, isStatic ? string.Empty : "this"); } if (mi.ParamNames.Count > 0) { if (!isStatic) { CodeBuilder.Append(", "); } CodeBuilder.Append(string.Join(", ", mi.ParamNames.ToArray())); } CodeBuilder.AppendLine(");"); } else if (null != accessor.Body) { if (mi.ValueParams.Count > 0) { OutputWrapValueParams(CodeBuilder, mi); } if (!string.IsNullOrEmpty(mi.OriginalParamsName)) { if (keyword == "get") { 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(); } else { CodeBuilder.AppendFormat("{0}local {1} = {{...}};", GetIndentString(), mi.OriginalParamsName); CodeBuilder.AppendLine(); CodeBuilder.AppendFormat("{0}local value = table.remove({1});", GetIndentString(), mi.OriginalParamsName); CodeBuilder.AppendLine(); if (mi.ParamsIsValueType) { CodeBuilder.AppendFormat("{0}{1} = wrapvaluetypearray({2});", GetIndentString(), mi.OriginalParamsName, mi.OriginalParamsName); } else if (mi.ParamsIsExternValueType) { CodeBuilder.AppendFormat("{0}{1} = wrapexternvaluetypearray({2});", GetIndentString(), mi.OriginalParamsName, mi.OriginalParamsName); } else { CodeBuilder.AppendFormat("{0}{1} = wraparray({2});", GetIndentString(), mi.OriginalParamsName, mi.OriginalParamsName); } CodeBuilder.AppendLine(); } } VisitBlock(accessor.Body); } --m_Indent; CodeBuilder.AppendFormat("{0}end,", GetIndentString()); CodeBuilder.AppendLine(); m_MethodInfoStack.Pop(); } } ci.CurrentCodeBuilder = currentBuilder; }
public override void VisitPropertyDeclaration(PropertyDeclarationSyntax node) { var ci = m_ClassInfoStack.Peek(); IPropertySymbol 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; } } bool noimpl = true; foreach (var accessor in node.AccessorList.Accessors) { var sym = m_Model.GetDeclaredSymbol(accessor); if (null != accessor.Body) { noimpl = false; break; } } if (noimpl) { //退化为field StringBuilder curBuilder = ci.CurrentCodeBuilder; if (declSym.IsStatic) { ci.CurrentCodeBuilder = ci.StaticFieldCodeBuilder; } else { ci.CurrentCodeBuilder = ci.InstanceFieldCodeBuilder; } ++m_Indent; CodeBuilder.AppendFormat("{0}{1} = ", GetIndentString(), SymbolTable.GetPropertyName(declSym)); if (null != node.Initializer) { IConversionExpression opd = null; var oper = m_Model.GetOperation(node.Initializer) as ISymbolInitializer; if (null != oper) { opd = oper.Value as IConversionExpression; } OutputExpressionSyntax(node.Initializer.Value, opd); CodeBuilder.Append(","); } else { CodeBuilder.Append("__cs2lua_nil_field_value,"); } CodeBuilder.AppendLine(); --m_Indent; ci.CurrentCodeBuilder = curBuilder; } else { StringBuilder curBuilder = ci.CurrentCodeBuilder; if (declSym.IsStatic) { ci.CurrentCodeBuilder = ci.StaticFunctionCodeBuilder; } else { ci.CurrentCodeBuilder = ci.InstanceFunctionCodeBuilder; } foreach (var accessor in node.AccessorList.Accessors) { var sym = m_Model.GetDeclaredSymbol(accessor); if (null != sym) { var mi = new MethodInfo(); mi.Init(sym, accessor); m_MethodInfoStack.Push(mi); string manglingName = NameMangling(sym); string keyword = accessor.Keyword.Text; string paramStr = string.Join(", ", mi.ParamNames.ToArray()); if (!declSym.IsStatic) { if (string.IsNullOrEmpty(paramStr)) { paramStr = "this"; } else { paramStr = "this, " + paramStr; } } CodeBuilder.AppendFormat("{0}{1} = {2}function({3})", GetIndentString(), manglingName, mi.ExistYield ? "wrapenumerable(" : string.Empty, paramStr); CodeBuilder.AppendLine(); ++m_Indent; bool isStatic = declSym.IsStatic; string luaModule = ClassInfo.GetAttributeArgument <string>(sym, "Cs2Lua.TranslateToAttribute", 0); string luaFuncName = ClassInfo.GetAttributeArgument <string>(sym, "Cs2Lua.TranslateToAttribute", 1); if (!string.IsNullOrEmpty(luaModule) || !string.IsNullOrEmpty(luaFuncName)) { if (!string.IsNullOrEmpty(luaModule)) { SymbolTable.Instance.AddRequire(ci.Key, luaModule); } if (sym.ReturnsVoid && mi.ReturnParamNames.Count <= 0) { CodeBuilder.AppendFormat("{0}{1}({2}", GetIndentString(), luaFuncName, isStatic ? string.Empty : "this"); } else { CodeBuilder.AppendFormat("{0}return {1}({2}", GetIndentString(), luaFuncName, isStatic ? string.Empty : "this"); } if (mi.ParamNames.Count > 0) { if (!isStatic) { CodeBuilder.Append(", "); } CodeBuilder.Append(string.Join(", ", mi.ParamNames.ToArray())); } CodeBuilder.AppendLine(");"); } else if (null != accessor.Body) { if (mi.ValueParams.Count > 0) { OutputWrapValueParams(CodeBuilder, mi); } VisitBlock(accessor.Body); } --m_Indent; CodeBuilder.AppendFormat("{0}end{1},", GetIndentString(), mi.ExistYield ? ")" : string.Empty); CodeBuilder.AppendLine(); m_MethodInfoStack.Pop(); } } ci.CurrentCodeBuilder = curBuilder; CodeBuilder.AppendFormat("{0}{1} = {{", GetIndentString(), SymbolTable.GetPropertyName(declSym)); CodeBuilder.AppendLine(); ++m_Indent; foreach (var accessor in node.AccessorList.Accessors) { var sym = m_Model.GetDeclaredSymbol(accessor); if (null != sym) { string manglingName = NameMangling(sym); string keyword = accessor.Keyword.Text; CodeBuilder.AppendFormat("{0}{1} = {2}.{3},", GetIndentString(), keyword, declSym.IsStatic ? "static_methods" : "instance_methods", manglingName); CodeBuilder.AppendLine(); } } --m_Indent; CodeBuilder.AppendFormat("{0}", GetIndentString()); CodeBuilder.AppendLine("},"); } }
public override void VisitEventDeclaration(EventDeclarationSyntax node) { var ci = m_ClassInfoStack.Peek(); IEventSymbol 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; } } StringBuilder curBuilder = ci.CurrentCodeBuilder; if (declSym.IsStatic) { ci.CurrentCodeBuilder = ci.StaticFunctionCodeBuilder; } else { ci.CurrentCodeBuilder = ci.InstanceFunctionCodeBuilder; } foreach (var accessor in node.AccessorList.Accessors) { var sym = m_Model.GetDeclaredSymbol(accessor); if (null != sym) { var mi = new MethodInfo(); mi.Init(sym, accessor); m_MethodInfoStack.Push(mi); string manglingName = NameMangling(sym); string keyword = accessor.Keyword.Text; string paramStr = string.Join(", ", mi.ParamNames.ToArray()); if (!declSym.IsStatic) { if (string.IsNullOrEmpty(paramStr)) { paramStr = "this"; } else { paramStr = "this, " + paramStr; } } CodeBuilder.AppendFormat("{0}{1} = function({2})", GetIndentString(), manglingName, paramStr); CodeBuilder.AppendLine(); ++m_Indent; bool isStatic = declSym.IsStatic; string luaModule = ClassInfo.GetAttributeArgument <string>(sym, "Cs2Lua.TranslateToAttribute", 0); string luaFuncName = ClassInfo.GetAttributeArgument <string>(sym, "Cs2Lua.TranslateToAttribute", 1); if (!string.IsNullOrEmpty(luaModule) || !string.IsNullOrEmpty(luaFuncName)) { if (!string.IsNullOrEmpty(luaModule)) { SymbolTable.Instance.AddRequire(ci.Key, luaModule); } if (sym.ReturnsVoid && mi.ReturnParamNames.Count <= 0) { CodeBuilder.AppendFormat("{0}{1}({2}", GetIndentString(), luaFuncName, isStatic ? string.Empty : "this"); } else { CodeBuilder.AppendFormat("{0}return {1}({2}", GetIndentString(), luaFuncName, isStatic ? string.Empty : "this"); } if (mi.ParamNames.Count > 0) { if (!isStatic) { CodeBuilder.Append(", "); } CodeBuilder.Append(string.Join(", ", mi.ParamNames.ToArray())); } CodeBuilder.AppendLine(");"); } else if (null != accessor.Body) { if (mi.ValueParams.Count > 0) { OutputWrapValueParams(CodeBuilder, mi); } VisitBlock(accessor.Body); } --m_Indent; CodeBuilder.AppendFormat("{0}end,", GetIndentString()); CodeBuilder.AppendLine(); m_MethodInfoStack.Pop(); } } ci.CurrentCodeBuilder = curBuilder; CodeBuilder.AppendFormat("{0}{1} = {{", GetIndentString(), SymbolTable.GetEventName(declSym)); CodeBuilder.AppendLine(); ++m_Indent; foreach (var accessor in node.AccessorList.Accessors) { var sym = m_Model.GetDeclaredSymbol(accessor); if (null != sym) { string manglingName = NameMangling(sym); string keyword = accessor.Keyword.Text; CodeBuilder.AppendFormat("{0}{1} = {2}.{3},", GetIndentString(), keyword, declSym.IsStatic ? "static_methods" : "instance_methods", manglingName); CodeBuilder.AppendLine(); } } --m_Indent; CodeBuilder.AppendFormat("{0}", GetIndentString()); CodeBuilder.AppendLine("},"); }
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(); }