private void OutputOperatorInvoke(InvocationInfo ii, SyntaxNode node) { if (SymbolTable.Instance.IsCs2LuaSymbol(ii.MethodSymbol)) { CodeBuilder.AppendFormat("{0}.", ii.ClassKey); string manglingName = NameMangling(ii.MethodSymbol); CodeBuilder.Append(manglingName); CodeBuilder.Append("("); OutputArgumentList(ii.Args, ii.DefaultValueArgs, ii.GenericTypeArgs, ii.ArrayToParams, false, node, ii.ArgConversions.ToArray()); CodeBuilder.Append(")"); } else { string method = ii.MethodSymbol.Name; string luaOp = string.Empty; if (SymbolTable.ForSlua) { //slua导出时把重载操作符导出成lua实例方法了,然后利用lua实例上支持的操作符元方法在运行时绑定到重载实现 //这里把lua支持的操作符方法转成lua操作(可能比invokeexternoperator要快一些) if (method == "op_Addition") { luaOp = "+"; } else if (method == "op_Subtraction") { luaOp = "-"; } else if (method == "op_Multiply") { luaOp = "*"; } else if (method == "op_Division") { luaOp = "/"; } else if (method == "op_UnaryNegation") { luaOp = "-"; } else if (method == "op_UnaryPlus") { luaOp = "+"; } else if (method == "op_LessThan") { luaOp = "<"; } else if (method == "op_GreaterThan") { luaOp = ">"; } else if (method == "op_LessThanOrEqual") { luaOp = "<="; } else if (method == "op_GreaterThanOrEqual") { luaOp = ">= "; } } if (string.IsNullOrEmpty(luaOp)) { CodeBuilder.AppendFormat("invokeexternoperator({0}, ", ii.GenericClassKey); CodeBuilder.AppendFormat("\"{0}\"", method); CodeBuilder.Append(", "); OutputArgumentList(ii.Args, ii.DefaultValueArgs, ii.GenericTypeArgs, ii.ArrayToParams, false, node, ii.ArgConversions.ToArray()); CodeBuilder.Append(")"); } else { if (ii.Args.Count == 1) { if (luaOp == "-") { CodeBuilder.Append("("); CodeBuilder.Append(luaOp); CodeBuilder.Append(" "); OutputExpressionSyntax(ii.Args[0], ii.ArgConversions[0]); CodeBuilder.Append(")"); } } else if (ii.Args.Count == 2) { CodeBuilder.Append("("); OutputExpressionSyntax(ii.Args[0], ii.ArgConversions[0]); CodeBuilder.Append(" "); CodeBuilder.Append(luaOp); CodeBuilder.Append(" "); OutputExpressionSyntax(ii.Args[1], ii.ArgConversions[1]); CodeBuilder.Append(")"); } } } }
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 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 !"); } } } }
public override void VisitBinaryExpression(BinaryExpressionSyntax node) { var ci = m_ClassInfoStack.Peek(); var oper = m_Model.GetOperation(node) as IHasOperatorMethodExpression; if (null != oper && oper.UsesOperatorMethod) { IMethodSymbol msym = oper.OperatorMethod; var castOper = oper as IConversionExpression; if (null != castOper) { InvocationInfo ii = new InvocationInfo(); var arglist = new List <ExpressionSyntax>() { node.Left }; ii.Init(msym, arglist, m_Model); OutputOperatorInvoke(ii, node); } else { InvocationInfo ii = new InvocationInfo(); var arglist = new List <ExpressionSyntax>() { node.Left, node.Right }; ii.Init(msym, arglist, m_Model); OutputOperatorInvoke(ii, node); } } else { string op = node.OperatorToken.Text; ProcessBinaryOperator(node, ref op); string functor; if (s_BinaryFunctor.TryGetValue(op, out functor)) { CodeBuilder.AppendFormat("{0}(", functor); VisitExpressionSyntax(node.Left); CodeBuilder.Append(", "); if (op == "as" || op == "is") { var typeInfo = m_Model.GetTypeInfo(node.Right); var type = typeInfo.Type; OutputType(type, node, ci, op); } else if (op == "??") { var rightOper = m_Model.GetOperation(node.Right); bool rightIsConst = null != rightOper && rightOper.ConstantValue.HasValue; if (rightIsConst) { CodeBuilder.Append("true, "); VisitExpressionSyntax(node.Right); } else { CodeBuilder.Append("false, (function() return "); VisitExpressionSyntax(node.Right); CodeBuilder.Append("; end)"); } } else { VisitExpressionSyntax(node.Right); } CodeBuilder.Append(")"); } else if (op == "+") { ProcessAddOrStringConcat(node.Left, node.Right); } else if (op == "==" || op == "~=") { ProcessEqualOrNotEqual(op, node.Left, node.Right); } else { CodeBuilder.Append("("); VisitExpressionSyntax(node.Left); CodeBuilder.AppendFormat(" {0} ", op); VisitExpressionSyntax(node.Right); CodeBuilder.Append(")"); } } }