예제 #1
0
        public override void VisitCastExpression(CastExpressionSyntax node)
        {
            var ci   = m_ClassInfoStack.Peek();
            var oper = m_Model.GetOperation(node) as IConversionExpression;

            if (null != oper && oper.UsesOperatorMethod)
            {
                IMethodSymbol  msym    = oper.OperatorMethod;
                InvocationInfo ii      = new InvocationInfo();
                var            arglist = new List <ExpressionSyntax>()
                {
                    node.Expression
                };
                ii.Init(msym, arglist, m_Model);
                AddReferenceAndTryDeriveGenericTypeInstance(ci, oper.Type);

                OutputOperatorInvoke(ii, node);
            }
            else
            {
                CodeBuilder.Append("typecast(");
                VisitExpressionSyntax(node.Expression);

                var typeInfo = m_Model.GetTypeInfo(node.Type);
                var type     = typeInfo.Type;
                CodeBuilder.Append(", ");
                OutputType(type, node, ci, "cast");
                CodeBuilder.Append(")");
            }
        }
예제 #2
0
        public override void VisitPostfixUnaryExpression(PostfixUnaryExpressionSyntax node)
        {
            var oper = m_Model.GetOperation(node) as IHasOperatorMethodExpression;

            if (null != oper && oper.UsesOperatorMethod)
            {
                IMethodSymbol  msym    = oper.OperatorMethod;
                InvocationInfo ii      = new InvocationInfo();
                var            arglist = new List <ExpressionSyntax>()
                {
                    node.Operand
                };
                ii.Init(msym, arglist, m_Model);
                OutputOperatorInvoke(ii, node);
            }
            else
            {
                string op = node.OperatorToken.Text;
                if (op == "++" || op == "--")
                {
                    VisitExpressionSyntax(node.Operand);
                    m_PostfixUnaryExpressions.Enqueue(node);
                }
                else
                {
                    CodeBuilder.Append("(");
                    CodeBuilder.Append(op);
                    CodeBuilder.Append(" ");
                    VisitExpressionSyntax(node.Operand);
                    CodeBuilder.Append(")");
                }
            }
        }
예제 #3
0
        public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
        {
            var oper = m_Model.GetOperation(node) as IHasOperatorMethodExpression;

            if (null != oper && oper.UsesOperatorMethod)
            {
                IMethodSymbol  msym    = oper.OperatorMethod;
                InvocationInfo ii      = new InvocationInfo();
                var            arglist = new List <ExpressionSyntax>()
                {
                    node.Operand
                };
                ii.Init(msym, arglist, m_Model);
                OutputOperatorInvoke(ii, node);
            }
            else
            {
                string op = node.OperatorToken.Text;
                if (op == "++" || op == "--")
                {
                    CodeBuilder.Append("(function() ");
                    VisitExpressionSyntax(node.Operand);
                    CodeBuilder.Append(" = ");
                    VisitExpressionSyntax(node.Operand);
                    CodeBuilder.Append(" ");
                    CodeBuilder.Append(op == "++" ? "+" : "-");
                    CodeBuilder.Append(" 1; return ");
                    VisitExpressionSyntax(node.Operand);
                    CodeBuilder.Append("; end)()");
                }
                else
                {
                    ProcessUnaryOperator(node, ref op);
                    string functor;
                    if (s_UnaryFunctor.TryGetValue(op, out functor))
                    {
                        CodeBuilder.AppendFormat("{0}(", functor);
                        VisitExpressionSyntax(node.Operand);
                    }
                    else
                    {
                        CodeBuilder.Append("(");
                        CodeBuilder.Append(op);
                        CodeBuilder.Append(" ");
                        VisitExpressionSyntax(node.Operand);
                    }
                    CodeBuilder.Append(")");
                }
            }
        }
예제 #4
0
파일: CsToLua.cs 프로젝트: 70yx/Cs2Lua
 internal void OutputExpressionSyntax(ExpressionSyntax node, IConversionExpression opd)
 {
     if (null != opd && opd.UsesOperatorMethod && !(node is CastExpressionSyntax))
     {
         IMethodSymbol  msym    = opd.OperatorMethod;
         InvocationInfo ii      = new InvocationInfo();
         var            arglist = new List <ExpressionSyntax>()
         {
             node
         };
         ii.Init(msym, arglist, m_Model);
         OutputOperatorInvoke(ii, node);
     }
     else
     {
         VisitExpressionSyntax(node);
     }
 }
예제 #5
0
        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 !");
                    }
                }
            }
        }
예제 #6
0
        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(")");
        }
예제 #7
0
        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(")");
                }
            }
        }