private void AddReferenceAndTryDeriveGenericTypeInstance(ClassInfo ci, ISymbol refSym) { ci.AddReference(refSym); TryDeriveGenericTypeInstance(refSym); }
internal void Init(IMethodSymbol sym, SyntaxNode node) { ParamNames.Clear(); ReturnParamNames.Clear(); OutParamNames.Clear(); OriginalParamsName = string.Empty; ExistYield = false; ExistTopLevelReturn = false; SemanticInfo = sym; if (sym.IsGenericMethod) { foreach (var param in sym.TypeParameters) { ParamNames.Add(param.Name); GenericMethodTypeParamNames.Add(param.Name); } } foreach (var param in sym.Parameters) { if (param.IsParams) { var arrTypeSym = param.Type as IArrayTypeSymbol; if (null != arrTypeSym && arrTypeSym.ElementType.TypeKind == TypeKind.Struct) { string ns = ClassInfo.GetNamespaces(arrTypeSym.ElementType); if (SymbolTable.Instance.IsCs2LuaSymbol(arrTypeSym.ElementType)) { ParamsIsValueType = true; } else if (ns != "System") { ParamsIsExternValueType = true; } } ParamNames.Add("..."); OriginalParamsName = param.Name; //遇到变参直接结束(变参set_Item会出现后面带一个value参数的情形,在函数实现里处理) break; } else if (param.RefKind == RefKind.Ref) { ParamNames.Add(param.Name); ReturnParamNames.Add(param.Name); } else if (param.RefKind == RefKind.Out) { //实参时out参数传入__cs2lua_out(适应slua与dotnet反射的调用规则,xlua忽略out参数) if (!SymbolTable.ForXlua) { ParamNames.Add(param.Name); } ReturnParamNames.Add(param.Name); OutParamNames.Add(param.Name); } else { if (param.Type.TypeKind == TypeKind.Struct) { string ns = ClassInfo.GetNamespaces(param.Type); if (SymbolTable.Instance.IsCs2LuaSymbol(param.Type)) { ValueParams.Add(ParamNames.Count); } else if (ns != "System") { ExternValueParams.Add(ParamNames.Count); } } ParamNames.Add(param.Name); } } if (!sym.ReturnsVoid) { var returnType = ClassInfo.GetFullName(sym.ReturnType); if (returnType.StartsWith(SymbolTable.PrefixExternClassName("System.Collections")) && (sym.ReturnType.Name == "IEnumerable" || sym.ReturnType.Name == "IEnumerator")) { var analysis = new YieldAnalysis(); analysis.Visit(node); ExistYield = analysis.YieldCount > 0; } } }
internal bool CheckExplicitInterfaceAccess(ISymbol sym, ref string nameOfIntf, ref string mname) { bool ret = false; if (sym.ContainingType.TypeKind == TypeKind.Interface) { string fn = ClassInfo.GetFullName(sym.ContainingType); ClassSymbolInfo csi; if (SymbolTable.Instance.ClassSymbols.TryGetValue(fn, out csi)) { switch (sym.Kind) { case SymbolKind.Method: IMethodSymbol msym = sym as IMethodSymbol; if (csi.ExplicitInterfaceImplementationMethods.Contains(msym)) { ret = true; if (null != nameOfIntf) { nameOfIntf = string.Format("\"{0}\"", fn.Replace(".", "_")); } if (null != mname) { mname = string.Format("\"{0}\"", NameMangling(msym)); } } break; case SymbolKind.Property: IPropertySymbol psym = sym as IPropertySymbol; if (csi.ExplicitInterfaceImplementationProperties.Contains(psym)) { ret = true; if (null != nameOfIntf) { nameOfIntf = string.Format("\"{0}\"", fn.Replace(".", "_")); } if (null != mname) { mname = string.Format("\"{0}\"", SymbolTable.GetPropertyName(psym)); } } break; case SymbolKind.Event: IEventSymbol esym = sym as IEventSymbol; if (csi.ExplicitInterfaceImplementationEvents.Contains(esym)) { ret = true; if (null != nameOfIntf) { nameOfIntf = string.Format("\"{0}\"", fn.Replace(".", "_")); } if (null != mname) { mname = string.Format("\"{0}\"", SymbolTable.GetEventName(esym)); } } break; } } } return(ret); }
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 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; } } if (null != node.ExpressionBody) { StringBuilder curBuilder = ci.CurrentCodeBuilder; if (declSym.IsStatic) { ci.CurrentCodeBuilder = ci.StaticFunctionCodeBuilder; } else { ci.CurrentCodeBuilder = ci.InstanceFunctionCodeBuilder; } var mi = new MethodInfo(); mi.Init(declSym.GetMethod, node.ExpressionBody); m_MethodInfoStack.Push(mi); string manglingName = NameMangling(declSym.GetMethod); CodeBuilder.AppendFormat("{0}{1} = function(this, {2})", GetIndentString(), manglingName, string.Join(",", mi.ParamNames.ToArray())); CodeBuilder.AppendLine(); ++m_Indent; CodeBuilder.AppendFormat("{0}return ", GetIndentString()); IConversionExpression opd = null; var oper = m_Model.GetOperation(node.ExpressionBody) as IBlockStatement; if (null != oper && oper.Statements.Length == 1) { var iret = oper.Statements[0] as IReturnStatement; if (null != iret) { opd = iret.ReturnedValue as IConversionExpression; } } OutputExpressionSyntax(node.ExpressionBody.Expression, opd); CodeBuilder.AppendLine(";"); --m_Indent; CodeBuilder.AppendFormat("{0}end,", GetIndentString()); CodeBuilder.AppendLine(); m_MethodInfoStack.Pop(); ci.CurrentCodeBuilder = curBuilder; } else { 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; } }
internal void Init(INamedTypeSymbol typeSym, CSharpCompilation compilation, SymbolTable symTable) { if (typeSym.TypeKind == TypeKind.Error) { Logger.Instance.ReportIllegalType(typeSym); return; } IsInterface = typeSym.TypeKind == TypeKind.Interface; foreach (var intf in typeSym.AllInterfaces) { string key = ClassInfo.GetFullName(intf); ClassSymbolInfo isi; if (!symTable.ClassSymbols.TryGetValue(key, out isi)) { isi = new ClassSymbolInfo(); symTable.ClassSymbols.Add(key, isi); isi.Init(intf, compilation, symTable); } } ClassKey = ClassInfo.GetFullName(typeSym); BaseClassKey = ClassInfo.GetFullName(typeSym.BaseType); if (BaseClassKey == SymbolTable.PrefixExternClassName("System.Object") || BaseClassKey == SymbolTable.PrefixExternClassName("System.ValueType")) { BaseClassKey = string.Empty; } ExistConstructor = false; ExistStaticConstructor = false; if (typeSym.GetAttributes().Length > 0) { ExistAttributes = true; } bool fieldUseExplicitTypeParams = false; bool staticUseExplicitTypeParams = false; TypeSymbol = typeSym; foreach (var sym in TypeSymbol.GetMembers()) { var fsym = sym as IFieldSymbol; if (null != fsym) { FieldSymbols.Add(fsym); if (fsym.GetAttributes().Length > 0) { ExistAttributes = true; } CheckFieldUseExplicitTypeParam(fsym, compilation, ref fieldUseExplicitTypeParams, ref staticUseExplicitTypeParams); } } foreach (var sym in TypeSymbol.GetMembers()) { var msym = sym as IMethodSymbol; if (null != msym) { if (msym.MethodKind == MethodKind.Constructor && !msym.IsImplicitlyDeclared) { ExistConstructor = true; } else if (msym.MethodKind == MethodKind.StaticConstructor && !msym.IsImplicitlyDeclared) { ExistStaticConstructor = true; } MethodSymbols.Add(msym); if (msym.GetAttributes().Length > 0) { ExistAttributes = true; } string name = msym.Name; if (name[0] == '.') { name = name.Substring(1); } string manglingName = SymbolTable.CalcMethodMangling(msym); if (!SymbolOverloadFlags.ContainsKey(name)) { SymbolOverloadFlags.Add(name, false); MethodNames.Add(name); } else { SymbolOverloadFlags[name] = true; MethodNames.Add(manglingName); } continue; } var psym = sym as IPropertySymbol; if (null != psym && !psym.IsIndexer) { PropertySymbols.Add(psym); if (psym.GetAttributes().Length > 0) { ExistAttributes = true; } continue; } var esym = sym as IEventSymbol; if (null != esym) { EventSymbols.Add(esym); if (esym.GetAttributes().Length > 0) { ExistAttributes = true; } continue; } } BuildInterfaceInfo(typeSym, compilation, symTable); }
public override void VisitConditionalAccessExpression(ConditionalAccessExpressionSyntax node) { CodeBuilder.Append("condaccess("); VisitExpressionSyntax(node.Expression); CodeBuilder.Append(", "); var elementBinding = node.WhenNotNull as ElementBindingExpressionSyntax; if (null != elementBinding) { var oper = m_Model.GetOperation(node.WhenNotNull); var symInfo = m_Model.GetSymbolInfo(node.WhenNotNull); var sym = symInfo.Symbol; var psym = sym as IPropertySymbol; if (null != sym && sym.IsStatic) { var ci = m_ClassInfoStack.Peek(); AddReferenceAndTryDeriveGenericTypeInstance(ci, sym); } if (null != psym && psym.IsIndexer) { CodeBuilder.Append("(function() return "); CodeBuilder.AppendFormat("get{0}{1}indexer(", psym.ContainingAssembly == m_SymbolTable.AssemblySymbol ? string.Empty : "extern", psym.IsStatic ? "static" : "instance"); if (psym.IsStatic) { string fullName = ClassInfo.GetFullName(psym.ContainingType); CodeBuilder.Append(fullName); } else { VisitExpressionSyntax(node.Expression); } CodeBuilder.Append(", "); if (!psym.IsStatic) { string fnOfIntf = "nil"; CheckExplicitInterfaceAccess(psym.GetMethod, ref fnOfIntf); CodeBuilder.AppendFormat("{0}, ", fnOfIntf); } string manglingName = NameMangling(psym.GetMethod); CodeBuilder.AppendFormat("\"{0}\", ", manglingName); InvocationInfo ii = new InvocationInfo(); List <ExpressionSyntax> args = new List <ExpressionSyntax> { node.WhenNotNull }; ii.Init(psym.GetMethod, args, m_Model); OutputArgumentList(ii.Args, ii.DefaultValueArgs, ii.GenericTypeArgs, ii.ArrayToParams, false, elementBinding); CodeBuilder.Append(")"); CodeBuilder.Append("; end)"); } else if (oper.Kind == OperationKind.ArrayElementReferenceExpression) { CodeBuilder.Append("(function() return "); VisitExpressionSyntax(node.Expression); CodeBuilder.Append("["); VisitExpressionSyntax(node.WhenNotNull); CodeBuilder.Append(" + 1]"); CodeBuilder.Append("; end)"); } else if (null != sym) { CodeBuilder.Append("(function() return "); CodeBuilder.AppendFormat("get{0}{1}element(", sym.ContainingAssembly == m_SymbolTable.AssemblySymbol ? string.Empty : "extern", sym.IsStatic ? "static" : "instance"); if (sym.IsStatic) { string fullName = ClassInfo.GetFullName(sym.ContainingType); CodeBuilder.Append(fullName); } else { VisitExpressionSyntax(node.Expression); } CodeBuilder.Append(", "); CodeBuilder.AppendFormat("\"{0}\", ", sym.Name); VisitExpressionSyntax(node.WhenNotNull); CodeBuilder.Append(")"); CodeBuilder.Append("; end)"); } else { ReportIllegalSymbol(node, symInfo); } } else { CodeBuilder.Append("(function() return "); VisitExpressionSyntax(node.Expression); VisitExpressionSyntax(node.WhenNotNull); CodeBuilder.Append("; end)"); } CodeBuilder.Append(")"); }
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)) { m_SymbolTable.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; } CodeBuilder.AppendFormat("{0}{1} = ", GetIndentString(), SymbolTable.GetPropertyName(declSym)); if (null != node.Initializer) { VisitExpressionSyntax(node.Initializer.Value); CodeBuilder.Append(","); } else { CodeBuilder.Append("true,"); } CodeBuilder.AppendLine(); 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; 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 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)) { m_SymbolTable.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; 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; }
internal bool IsCs2LuaSymbol(ITypeSymbol sym) { return(sym.ContainingAssembly == m_AssemblySymbol && !m_ExternTypes.ContainsKey(ClassInfo.SpecialGetFullTypeName(sym, true))); }
public override void VisitIdentifierName(IdentifierNameSyntax node) { string name = node.Identifier.Text; if (m_ClassInfoStack.Count > 0) { ClassInfo classInfo = m_ClassInfoStack.Peek(); SymbolInfo symbolInfo = m_Model.GetSymbolInfo(node); var sym = symbolInfo.Symbol; if (null != sym) { if (sym.Kind == SymbolKind.NamedType || sym.Kind == SymbolKind.Namespace) { string fullName = ClassInfo.GetFullName(sym); CodeBuilder.Append(fullName); if (sym.Kind == SymbolKind.NamedType) { var namedType = sym as INamedTypeSymbol; AddReferenceAndTryDeriveGenericTypeInstance(classInfo, namedType); } return; } else if (sym.Kind == SymbolKind.Field || sym.Kind == SymbolKind.Property || sym.Kind == SymbolKind.Event) { if (m_ObjectCreateStack.Count > 0) { ITypeSymbol symInfo = m_ObjectCreateStack.Peek(); if (null != symInfo) { var names = symInfo.GetMembers(name); if (names.Length > 0) { CodeBuilder.AppendFormat("newobj.{0}", name); return; } } } if (sym.ContainingType == classInfo.SemanticInfo || sym.ContainingType == classInfo.SemanticInfo.OriginalDefinition || classInfo.IsInherit(sym.ContainingType)) { if (sym.IsStatic) { CodeBuilder.AppendFormat("{0}.{1}", classInfo.Key, sym.Name); } else { CodeBuilder.AppendFormat("this.{0}", sym.Name); } return; } } else if (sym.Kind == SymbolKind.Method && sym.ContainingType == classInfo.SemanticInfo) { var msym = sym as IMethodSymbol; string manglingName = NameMangling(msym); var mi = new MethodInfo(); mi.Init(msym, node); if (node.Parent is InvocationExpressionSyntax) { if (sym.IsStatic) { CodeBuilder.AppendFormat("{0}.{1}", classInfo.Key, manglingName); } else { CodeBuilder.AppendFormat("this:{0}", manglingName); } } else { string className = ClassInfo.GetFullName(msym.ContainingType); string delegationKey = string.Format("{0}:{1}", className, manglingName); string varName = string.Format("__compiler_delegation_{0}", node.GetLocation().GetLineSpan().StartLinePosition.Line); CodeBuilder.AppendFormat("(function() local {0} = ", varName); CodeBuilder.Append("(function("); string paramsString = string.Join(", ", mi.ParamNames.ToArray()); CodeBuilder.Append(paramsString); if (sym.IsStatic) { CodeBuilder.AppendFormat(") {0}{1}.{2}({3}); end)", msym.ReturnsVoid ? string.Empty : "return ", classInfo.Key, manglingName, paramsString); } else { CodeBuilder.AppendFormat(") {0}this:{1}({2}); end)", msym.ReturnsVoid ? string.Empty : "return ", manglingName, paramsString); } CodeBuilder.AppendFormat("; setdelegationkey({0}, \"{1}\", ", varName, delegationKey); if (sym.IsStatic) { CodeBuilder.Append(classInfo.Key); CodeBuilder.Append(", "); CodeBuilder.Append(classInfo.Key); } else { CodeBuilder.Append("this, this"); } CodeBuilder.Append("."); CodeBuilder.Append(manglingName); CodeBuilder.AppendFormat("); return {0}; end)()", varName); } return; } } else { if (m_ObjectCreateStack.Count > 0) { ITypeSymbol symInfo = m_ObjectCreateStack.Peek(); if (null != symInfo) { var names = symInfo.GetMembers(name); if (names.Length > 0) { CodeBuilder.AppendFormat("newobj.{0}", name); return; } } } else { ReportIllegalSymbol(node, symbolInfo); } } } CodeBuilder.Append(name); }
internal bool IsIgnoredSymbol(ITypeSymbol sym) { return(m_IgnoredTypes.ContainsKey(ClassInfo.GetFullName(sym))); }
private void VisitTypeDeclarationSyntax(TypeDeclarationSyntax node) { INamedTypeSymbol declSym = m_Model.GetDeclaredSymbol(node); SymbolTable.Instance.AddGenericTypeDefine(ClassInfo.GetFullNameWithTypeParameters(declSym), node); }
public override void VisitObjectCreationExpression(ObjectCreationExpressionSyntax node) { var ci = m_ClassInfoStack.Peek(); var oper = m_Model.GetOperation(node); var objectCreate = oper as IObjectCreationExpression; if (null != objectCreate) { var typeSymInfo = objectCreate.Type; var sym = objectCreate.Constructor; m_ObjectCreateStack.Push(typeSymInfo); string fullTypeName = ClassInfo.GetFullName(typeSymInfo); //处理ref/out参数 InvocationInfo ii = new InvocationInfo(); ii.Init(sym, node.ArgumentList, m_Model); AddReferenceAndTryDeriveGenericTypeInstance(ci, sym); bool isCollection = IsImplementationOfSys(typeSymInfo, "ICollection"); bool isExternal = typeSymInfo.ContainingAssembly != m_SymbolTable.AssemblySymbol; string ctor = NameMangling(sym); string localName = string.Format("__compiler_newobject_{0}", node.GetLocation().GetLineSpan().StartLinePosition.Line); if (ii.ReturnArgs.Count > 0) { CodeBuilder.Append("(function() "); CodeBuilder.AppendFormat("local {0}; {1}", localName, localName); CodeBuilder.Append(", "); OutputExpressionList(ii.ReturnArgs); CodeBuilder.Append(" = "); } if (isCollection) { bool isDictionary = IsImplementationOfSys(typeSymInfo, "IDictionary"); bool isList = IsImplementationOfSys(typeSymInfo, "IList"); if (isDictionary) { //字典对象的处理 CodeBuilder.AppendFormat("new{0}dictionary({1}, ", isExternal ? "extern" : string.Empty, fullTypeName); if (isExternal) { CodeBuilder.AppendFormat("\"{0}\", ", fullTypeName); } } else if (isList) { //列表对象的处理 CodeBuilder.AppendFormat("new{0}list({1}, ", isExternal ? "extern" : string.Empty, fullTypeName); if (isExternal) { CodeBuilder.AppendFormat("\"{0}\", ", fullTypeName); } } else { //集合对象的处理 CodeBuilder.AppendFormat("new{0}collection({1}, ", isExternal ? "extern" : string.Empty, fullTypeName); if (isExternal) { CodeBuilder.AppendFormat("\"{0}\", ", fullTypeName); } } } else { CodeBuilder.AppendFormat("new{0}object({1}, ", isExternal ? "extern" : string.Empty, fullTypeName); if (isExternal) { CodeBuilder.AppendFormat("\"{0}\", ", fullTypeName); } } if (string.IsNullOrEmpty(ctor)) { CodeBuilder.Append("nil"); } else { CodeBuilder.AppendFormat("\"{0}\"", ctor); } if (isExternal) { ClassSymbolInfo csi; if (m_SymbolTable.ClassSymbols.TryGetValue(fullTypeName, out csi)) { if (csi.ExtensionClasses.Count > 0) { CodeBuilder.Append(", (function(obj)"); foreach (var pair in csi.ExtensionClasses) { string refname = pair.Key; CodeBuilder.AppendFormat(" {0}.__install_{1}(obj);", fullTypeName, refname.Replace(".", "_")); } CodeBuilder.Append(" end)"); } else { CodeBuilder.Append(", nil"); } } else { CodeBuilder.Append(", nil"); } } if (null != node.Initializer) { CodeBuilder.Append(", "); if (!isCollection) { CodeBuilder.Append("{"); } VisitInitializerExpression(node.Initializer); if (!isCollection) { CodeBuilder.Append("}"); } } else { CodeBuilder.Append(", {}"); } if (ii.Args.Count + ii.DefaultValueArgs.Count + ii.GenericTypeArgs.Count > 0) { CodeBuilder.Append(", "); } OutputArgumentList(ii.Args, ii.DefaultValueArgs, ii.GenericTypeArgs, ii.ArrayToParams, false, node); CodeBuilder.Append(")"); if (ii.ReturnArgs.Count > 0) { CodeBuilder.Append("; "); CodeBuilder.AppendFormat("return {0}; end)()", localName); } m_ObjectCreateStack.Pop(); } else { var methodBinding = oper as IMethodBindingExpression; if (null != methodBinding) { var typeSymInfo = methodBinding.Type; var msym = methodBinding.Method; if (null != msym) { string manglingName = NameMangling(msym); var mi = new MethodInfo(); mi.Init(msym, node); CodeBuilder.Append("(function("); string paramsString = string.Join(", ", mi.ParamNames.ToArray()); CodeBuilder.Append(paramsString); CodeBuilder.Append(") "); if (!msym.ReturnsVoid) { CodeBuilder.Append("return "); } if (msym.IsStatic) { AddReferenceAndTryDeriveGenericTypeInstance(ci, msym); string className = ClassInfo.GetFullName(msym.ContainingType); CodeBuilder.Append(className); CodeBuilder.Append("."); } else { CodeBuilder.Append("this:"); } CodeBuilder.Append(manglingName); CodeBuilder.AppendFormat("({0}) end)", paramsString); } else { VisitArgumentList(node.ArgumentList); } } else { var typeParamObjCreate = oper as ITypeParameterObjectCreationExpression; if (null != typeParamObjCreate) { CodeBuilder.Append("newtypeparamobject("); OutputType(typeParamObjCreate.Type, node, ci, "new"); CodeBuilder.Append(")"); } else { Log(node, "Unknown ObjectCreationExpressionSyntax !"); } } } }
private void OutputType(ITypeSymbol type, SyntaxNode node, ClassInfo ci, string errorTag) { if (null != type && type.TypeKind != TypeKind.Error) { if (type.TypeKind == TypeKind.TypeParameter) { var typeParam = type as ITypeParameterSymbol; if (typeParam.TypeParameterKind == TypeParameterKind.Type && !m_SkipGenericTypeDefine && null != m_GenericTypeInstance) { IMethodSymbol sym = FindClassMethodDeclaredSymbol(node); if (null != sym) { var t = SymbolTable.Instance.FindTypeArgument(type); if (t.TypeKind != TypeKind.TypeParameter) { CodeBuilder.Append(ClassInfo.GetFullName(t)); AddReferenceAndTryDeriveGenericTypeInstance(ci, t); } else { CodeBuilder.Append(t.Name); } } else { ISymbol varSym = FindVariableDeclaredSymbol(node); if (null != varSym) { var t = SymbolTable.Instance.FindTypeArgument(type); if (t.TypeKind != TypeKind.TypeParameter) { CodeBuilder.Append(ClassInfo.GetFullName(t)); AddReferenceAndTryDeriveGenericTypeInstance(ci, t); } else { CodeBuilder.Append(t.Name); } } else { Log(node, "Can't find declaration for type param !", type.Name); } } } else { CodeBuilder.Append(type.Name); } } else if (type.TypeKind == TypeKind.Array) { var arrType = type as IArrayTypeSymbol; CodeBuilder.Append(SymbolTable.PrefixExternClassName("System.Array")); } else { var fullName = ClassInfo.GetFullName(type); CodeBuilder.Append(fullName); var namedType = type as INamedTypeSymbol; if (null != namedType) { AddReferenceAndTryDeriveGenericTypeInstance(ci, namedType); } } } else if (null != type) { CodeBuilder.Append("nil"); ReportIllegalType(node, type); } else { CodeBuilder.Append("nil"); Log(node, "Unknown {0} Type !", errorTag); } }
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(); } if (SymbolTable.ForXlua && mi.OutParamNames.Count > 0) { CodeBuilder.AppendFormat("{0}local {1};", GetIndentString(), string.Join(", ", mi.OutParamNames.ToArray())); 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(); }
private void BuildInterfaceInfo(INamedTypeSymbol typeSym, CSharpCompilation compilation, SymbolTable symTable) { foreach (var intf in typeSym.AllInterfaces) { if (!InterfaceSymbols.Contains(intf)) { InterfaceSymbols.Add(intf); } foreach (var sym in intf.GetMembers()) { var msym = sym as IMethodSymbol; if (null != msym) { var implSym = typeSym.FindImplementationForInterfaceMember(sym) as IMethodSymbol; if (null != implSym) { string name = symTable.NameMangling(msym); name = ClassInfo.CalcNameWithFullTypeName(name, sym.ContainingType); string implName = symTable.NameMangling(implSym); if (!InterfaceMethodMap.ContainsKey(name)) { InterfaceMethodMap.Add(name, implName); } } } var psym = sym as IPropertySymbol; if (null != psym && !psym.IsIndexer) { var implSym = typeSym.FindImplementationForInterfaceMember(sym) as IPropertySymbol; if (null != implSym && !psym.IsIndexer) { string name = SymbolTable.GetPropertyName(psym); name = ClassInfo.CalcNameWithFullTypeName(name, sym.ContainingType); string implName = SymbolTable.GetPropertyName(implSym); if (!InterfaceMethodMap.ContainsKey(name)) { InterfaceMethodMap.Add(name, implName); } } } var esym = sym as IEventSymbol; if (null != esym) { var implSym = typeSym.FindImplementationForInterfaceMember(sym) as IEventSymbol; if (null != implSym) { string name = SymbolTable.GetEventName(esym); name = ClassInfo.CalcNameWithFullTypeName(name, sym.ContainingType); string implName = SymbolTable.GetEventName(implSym); if (!InterfaceMethodMap.ContainsKey(name)) { InterfaceMethodMap.Add(name, implName); } } } } } if (typeSym.TypeKind != TypeKind.Interface) { foreach (var sym in typeSym.GetMembers()) { var msym = sym as IMethodSymbol; if (null != msym && msym.ExplicitInterfaceImplementations.Length > 0) { foreach (var implSym in msym.ExplicitInterfaceImplementations) { string fn = ClassInfo.GetFullName(implSym.ContainingType); ClassSymbolInfo csi; if (symTable.ClassSymbols.TryGetValue(fn, out csi)) { if (!csi.ExplicitInterfaceImplementationMethods.Contains(implSym)) { csi.ExplicitInterfaceImplementationMethods.Add(implSym); } } } } var psym = sym as IPropertySymbol; if (null != psym && !psym.IsIndexer && psym.ExplicitInterfaceImplementations.Length > 0) { foreach (var implSym in psym.ExplicitInterfaceImplementations) { string fn = ClassInfo.GetFullName(implSym.ContainingType); ClassSymbolInfo csi; if (symTable.ClassSymbols.TryGetValue(fn, out csi)) { if (!csi.ExplicitInterfaceImplementationProperties.Contains(implSym)) { csi.ExplicitInterfaceImplementationProperties.Add(implSym); } } } } var esym = sym as IEventSymbol; if (null != esym && esym.ExplicitInterfaceImplementations.Length > 0) { foreach (var implSym in esym.ExplicitInterfaceImplementations) { string fn = ClassInfo.GetFullName(implSym.ContainingType); ClassSymbolInfo csi; if (symTable.ClassSymbols.TryGetValue(fn, out csi)) { if (!csi.ExplicitInterfaceImplementationEvents.Contains(implSym)) { csi.ExplicitInterfaceImplementationEvents.Add(implSym); } } } } } } }
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; if (null != node.ExpressionBody) { noimpl = false; } else { foreach (var accessor in node.AccessorList.Accessors) { var sym = m_Model.GetDeclaredSymbol(accessor); if (null != accessor.Body) { noimpl = false; break; } } } if (null != node.ExpressionBody) { StringBuilder curBuilder = ci.CurrentCodeBuilder; if (declSym.IsStatic) { ci.CurrentCodeBuilder = ci.StaticFunctionCodeBuilder; } else { ci.CurrentCodeBuilder = ci.InstanceFunctionCodeBuilder; } var mi = new MethodInfo(); mi.Init(declSym.GetMethod, node.ExpressionBody); m_MethodInfoStack.Push(mi); string manglingName = NameMangling(declSym.GetMethod); CodeBuilder.AppendFormat("{0}{1} = function({2})", GetIndentString(), manglingName, declSym.IsStatic ? string.Empty : "this"); CodeBuilder.AppendLine(); ++m_Indent; CodeBuilder.AppendFormat("{0}return ", GetIndentString()); IConversionExpression opd = null; var oper = m_Model.GetOperation(node.ExpressionBody) as IBlockStatement; if (null != oper && oper.Statements.Length == 1) { var iret = oper.Statements[0] as IReturnStatement; if (null != iret) { opd = iret.ReturnedValue as IConversionExpression; } } OutputExpressionSyntax(node.ExpressionBody.Expression, opd); CodeBuilder.AppendLine(";"); --m_Indent; CodeBuilder.AppendFormat("{0}end,", GetIndentString()); CodeBuilder.AppendLine(); m_MethodInfoStack.Pop(); ci.CurrentCodeBuilder = curBuilder; CodeBuilder.AppendFormat("{0}{1} = {{", GetIndentString(), SymbolTable.GetPropertyName(declSym)); CodeBuilder.AppendLine(); ++m_Indent; CodeBuilder.AppendFormat("{0}get = {1}.{2},", GetIndentString(), declSym.IsStatic ? "static_methods" : "instance_methods", manglingName); CodeBuilder.AppendLine(); --m_Indent; CodeBuilder.AppendFormat("{0}", GetIndentString()); CodeBuilder.AppendLine("},"); } else 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; } CodeBuilder.AppendFormat("{0}", declSym.Type.TypeKind == TypeKind.Delegate ? "delegationwrap(" : string.Empty); OutputExpressionSyntax(node.Initializer.Value, opd); CodeBuilder.AppendFormat("{0}", declSym.Type.TypeKind == TypeKind.Delegate ? ")" : string.Empty); CodeBuilder.Append(","); } else if (declSym.Type.TypeKind == TypeKind.Delegate) { CodeBuilder.Append("wrapdelegation{},"); } else { OutputFieldDefaultValue(declSym.Type); CodeBuilder.Append(","); } 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 VisitIdentifierName(IdentifierNameSyntax node) { string name = node.Identifier.Text; if (m_ClassInfoStack.Count > 0) { ClassInfo classInfo = m_ClassInfoStack.Peek(); SymbolInfo symbolInfo = m_Model.GetSymbolInfo(node); var sym = symbolInfo.Symbol; if (null != sym) { if (sym.Kind == SymbolKind.NamedType || sym.Kind == SymbolKind.Namespace) { string fullName = ClassInfo.GetFullName(sym); CodeBuilder.Append(fullName); if (sym.Kind == SymbolKind.NamedType) { var namedType = sym as INamedTypeSymbol; AddReferenceAndTryDeriveGenericTypeInstance(classInfo, namedType); } return; } else if (sym.Kind == SymbolKind.Field || sym.Kind == SymbolKind.Property || sym.Kind == SymbolKind.Event) { if (m_ObjectCreateStack.Count > 0) { ITypeSymbol symInfo = m_ObjectCreateStack.Peek(); if (null != symInfo) { var names = symInfo.GetMembers(name); if (names.Length > 0) { CodeBuilder.AppendFormat("{0}", name); return; } } } if (sym.ContainingType == classInfo.SemanticInfo || sym.ContainingType == classInfo.SemanticInfo.OriginalDefinition || classInfo.IsInherit(sym.ContainingType)) { if (sym.IsStatic) { CodeBuilder.AppendFormat("{0}.{1}", classInfo.Key, sym.Name); } else { CodeBuilder.AppendFormat("this.{0}", sym.Name); } return; } } else if (sym.Kind == SymbolKind.Method && sym.ContainingType == classInfo.SemanticInfo) { var msym = sym as IMethodSymbol; string manglingName = NameMangling(msym); var mi = new MethodInfo(); mi.Init(msym, node); if (node.Parent is InvocationExpressionSyntax) { if (sym.IsStatic) { CodeBuilder.AppendFormat("{0}.{1}", classInfo.Key, manglingName); } else { CodeBuilder.AppendFormat("this:{0}", manglingName); } } else { CodeBuilder.Append("(function("); string paramsString = string.Join(", ", mi.ParamNames.ToArray()); CodeBuilder.Append(paramsString); if (sym.IsStatic) { CodeBuilder.AppendFormat(") {0}.{1}({2}) end)", classInfo.Key, manglingName, paramsString); } else { CodeBuilder.AppendFormat(") this:{0}({1}) end)", manglingName, paramsString); } } return; } } else { if (m_ObjectCreateStack.Count > 0) { ITypeSymbol symInfo = m_ObjectCreateStack.Peek(); if (null != symInfo) { var names = symInfo.GetMembers(name); if (names.Length > 0) { CodeBuilder.AppendFormat("{0}", name); return; } } } else { ReportIllegalSymbol(node, symbolInfo); } } } CodeBuilder.Append(name); }
public override void VisitMemberAccessExpression(MemberAccessExpressionSyntax node) { SymbolInfo symInfo = m_Model.GetSymbolInfo(node); var sym = symInfo.Symbol; string className = string.Empty; if (null != sym && sym.IsStatic && null != sym.ContainingType) { className = ClassInfo.GetFullName(sym.ContainingType); } if (null != sym) { if (sym.IsStatic) { var ci = m_ClassInfoStack.Peek(); AddReferenceAndTryDeriveGenericTypeInstance(ci, sym); } } else { ReportIllegalSymbol(node, symInfo); } if (node.Parent is InvocationExpressionSyntax) { var msym = sym as IMethodSymbol; string manglingName = NameMangling(msym); if (string.IsNullOrEmpty(className)) { VisitExpressionSyntax(node.Expression); CodeBuilder.Append(":"); } else { CodeBuilder.Append(className); CodeBuilder.Append("."); } CodeBuilder.Append(manglingName); } else { var msym = sym as IMethodSymbol; if (null != msym) { string manglingName = NameMangling(msym); var mi = new MethodInfo(); mi.Init(msym, node); CodeBuilder.Append("(function("); string paramsString = string.Join(", ", mi.ParamNames.ToArray()); CodeBuilder.Append(paramsString); CodeBuilder.Append(") "); if (!msym.ReturnsVoid) { CodeBuilder.Append("return "); } if (string.IsNullOrEmpty(className)) { VisitExpressionSyntax(node.Expression); CodeBuilder.Append(":"); } else { CodeBuilder.Append(className); CodeBuilder.Append("."); } CodeBuilder.Append(manglingName); CodeBuilder.AppendFormat("({0}) end)", paramsString); } else { var psym = sym as IPropertySymbol; string fnOfIntf = string.Empty; string mname = string.Empty; bool propExplicitImplementInterface = false; bool propForBasicValueType = false; if (null != psym) { if (!psym.IsStatic) { propExplicitImplementInterface = CheckExplicitInterfaceAccess(psym, ref fnOfIntf, ref mname); propForBasicValueType = SymbolTable.IsBasicValueProperty(psym); } } if (propExplicitImplementInterface) { CodeBuilder.AppendFormat("getwithinterface("); VisitExpressionSyntax(node.Expression); CodeBuilder.AppendFormat(", \"{0}\", \"{1}\")", fnOfIntf, mname); } else if (propForBasicValueType) { string pname = psym.Name; CodeBuilder.AppendFormat("getforbasicvalue("); VisitExpressionSyntax(node.Expression); CodeBuilder.AppendFormat(", \"{0}\", \"{1}\")", className, pname); } else { if (string.IsNullOrEmpty(className)) { VisitExpressionSyntax(node.Expression); } else { CodeBuilder.Append(className); } CodeBuilder.Append(node.OperatorToken.Text); CodeBuilder.Append(node.Name.Identifier.Text); } } } }