예제 #1
0
 private void AddReferenceAndTryDeriveGenericTypeInstance(ClassInfo ci, ISymbol refSym)
 {
     ci.AddReference(refSym);
     TryDeriveGenericTypeInstance(refSym);
 }
예제 #2
0
        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;
                }
            }
        }
예제 #3
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);
        }
예제 #4
0
        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("},");
        }
예제 #5
0
        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;
            }
        }
예제 #6
0
        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);
        }
예제 #7
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(")");
        }
예제 #8
0
        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("},");
            }
        }
예제 #9
0
        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;
        }
예제 #10
0
 internal bool IsCs2LuaSymbol(ITypeSymbol sym)
 {
     return(sym.ContainingAssembly == m_AssemblySymbol && !m_ExternTypes.ContainsKey(ClassInfo.SpecialGetFullTypeName(sym, true)));
 }
예제 #11
0
        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);
        }
예제 #12
0
 internal bool IsIgnoredSymbol(ITypeSymbol sym)
 {
     return(m_IgnoredTypes.ContainsKey(ClassInfo.GetFullName(sym)));
 }
예제 #13
0
        private void VisitTypeDeclarationSyntax(TypeDeclarationSyntax node)
        {
            INamedTypeSymbol declSym = m_Model.GetDeclaredSymbol(node);

            SymbolTable.Instance.AddGenericTypeDefine(ClassInfo.GetFullNameWithTypeParameters(declSym), node);
        }
예제 #14
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 !");
                    }
                }
            }
        }
예제 #15
0
        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);
            }
        }
예제 #16
0
        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();
        }
예제 #17
0
 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);
                         }
                     }
                 }
             }
         }
     }
 }
예제 #18
0
        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("},");
            }
        }
예제 #19
0
        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);
        }
예제 #20
0
        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);
                    }
                }
            }
        }