Ejemplo n.º 1
0
 private void BuildInterfaceInfo(INamedTypeSymbol typeSym, CSharpCompilation compilation, SymbolTable symTable)
 {
     foreach (var intf in typeSym.AllInterfaces)
     {
         if (!InterfaceSymbols.Contains(intf))
         {
             InterfaceSymbols.Add(intf);
         }
     }
     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.ContainsKey(implSym))
                         {
                             csi.ExplicitInterfaceImplementationMethods.Add(implSym, msym);
                         }
                     }
                 }
             }
             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.ContainsKey(implSym))
                         {
                             csi.ExplicitInterfaceImplementationProperties.Add(implSym, psym);
                         }
                     }
                 }
             }
             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.ContainsKey(implSym))
                         {
                             csi.ExplicitInterfaceImplementationEvents.Add(implSym, esym);
                         }
                     }
                 }
             }
         }
     }
 }
Ejemplo n.º 2
0
        public override void VisitVariableDeclarator(VariableDeclaratorSyntax node)
        {
            var ci       = m_ClassInfoStack.Peek();
            var localSym = m_Model.GetDeclaredSymbol(node) as ILocalSymbol;

            if (null != localSym && localSym.HasConstantValue)
            {
                if (null != node.Initializer)
                {
                    CodeBuilder.AppendFormat("{0}local({1}); {2}", GetIndentString(), node.Identifier.Text, node.Identifier.Text);
                }
                else
                {
                    CodeBuilder.AppendFormat("{0}local({1})", GetIndentString(), node.Identifier.Text);
                }
                CodeBuilder.Append(" = ");
                OutputConstValue(localSym.ConstantValue, localSym);
                CodeBuilder.AppendLine(";");
                return;
            }
            bool        dslToObject = false;
            ITypeSymbol type        = null;

            if (null != node.Initializer)
            {
                type = m_Model.GetTypeInfoEx(node.Initializer.Value).Type;
                if (null != localSym && null != localSym.Type && null != type)
                {
                    dslToObject = InvocationInfo.IsDslToObject(localSym.Type, type);
                }
            }
            VisitLocalVariableDeclarator(ci, node, dslToObject);
            if (null != node.Initializer)
            {
                var rightSymbolInfo = m_Model.GetSymbolInfoEx(node.Initializer.Value);
                var rightSym        = rightSymbolInfo.Symbol;
                if (null != type && type.IsValueType && !dslToObject && !SymbolTable.IsBasicType(type) && !CsDslTranslater.IsImplementationOfSys(type, "IEnumerator"))
                {
                    if (null != rightSym && (rightSym.Kind == SymbolKind.Method || rightSym.Kind == SymbolKind.Property || rightSym.Kind == SymbolKind.Field || rightSym.Kind == SymbolKind.Local) && SymbolTable.Instance.IsCs2DslSymbol(rightSym))
                    {
                        MarkNeedFuncInfo();
                        if (SymbolTable.Instance.IsCs2DslSymbol(type))
                        {
                            CodeBuilder.AppendFormat("{0}{1} = wrapstruct({2}, {3});", GetIndentString(), node.Identifier.Text, node.Identifier.Text, ClassInfo.GetFullName(type));
                            CodeBuilder.AppendLine();
                        }
                        else
                        {
                            string ns = ClassInfo.GetNamespaces(type);
                            if (ns != "System")
                            {
                                CodeBuilder.AppendFormat("{0}{1} = wrapexternstruct({2}, {3});", GetIndentString(), node.Identifier.Text, node.Identifier.Text, ClassInfo.GetFullName(type));
                                CodeBuilder.AppendLine();
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 3
0
        public override void VisitForEachStatement(ForEachStatementSyntax node)
        {
            MethodInfo mi = m_MethodInfoStack.Peek();

            mi.TryCatchUsingOrLoopSwitchStack.Push(false);

            ContinueInfo ci = new ContinueInfo();

            ci.Init(node.Statement);
            m_ContinueInfoStack.Push(ci);

            IConversionOperation opd = null;
            bool isList  = false;
            bool isArray = false;
            var  oper    = m_Model.GetOperationEx(node) as IForEachLoopOperation;

            if (null != oper)
            {
                opd = oper.Collection as IConversionOperation;
            }
            var expType = m_Model.GetTypeInfoEx(node.Expression).Type;

            if (null != expType)
            {
                isList  = IsImplementationOfSys(expType, "IList");
                isArray = expType.TypeKind == TypeKind.Array;
            }

            var srcPos = GetSourcePosForVar(node);

            if (isArray)
            {
                int rank    = 0;
                var arrType = expType as IArrayTypeSymbol;
                rank = arrType.Rank;
                bool   isCs2Dsl = SymbolTable.Instance.IsCs2DslSymbol(expType);
                string varIndex = string.Format("__foreach_ix_{0}", srcPos);
                string varExp   = string.Format("__foreach_exp_{0}", srcPos);
                CodeBuilder.AppendFormat("{0}foreacharray({1}, {2}, {3}, ", GetIndentString(), varIndex, varExp, node.Identifier.Text);
                OutputExpressionSyntax(node.Expression, opd);
                CodeBuilder.Append(", ");
                CodeBuilder.Append(rank);
                CodeBuilder.Append(", ");
                CodeBuilder.Append(isCs2Dsl ? "false" : "true");
                CodeBuilder.AppendLine("){");
            }
            else if (isList)
            {
                string           varIndex = string.Format("__foreach_ix_{0}", srcPos);
                string           varExp   = string.Format("__foreach_exp_{0}", srcPos);
                var              objType  = expType as INamedTypeSymbol;
                INamedTypeSymbol listType = null;
                var              fobj     = objType;
                IMethodSymbol    msym     = null;
                while (null != fobj)
                {
                    if (HasItemGetMethodDefined(fobj, ref msym))
                    {
                        listType = fobj;
                        break;
                    }
                    fobj = fobj.BaseType;
                }
                string elemTypeName = null;
                string elemTypeKind = null;
                if (null != msym)
                {
                    elemTypeName = ClassInfo.GetFullName(msym.ReturnType);
                    elemTypeKind = "TypeKind." + msym.ReturnType.TypeKind;
                }
                if (string.IsNullOrEmpty(elemTypeName))
                {
                    elemTypeName = "null";
                }
                if (string.IsNullOrEmpty(elemTypeKind))
                {
                    elemTypeKind = "null";
                }
                bool   isCs2Dsl     = SymbolTable.Instance.IsCs2DslSymbol(listType);
                string objTypeName  = ClassInfo.GetFullName(objType);
                string listTypeName = ClassInfo.GetFullName(listType);
                CodeBuilder.AppendFormat("{0}foreachlist({1}, {2}, {3}, ", GetIndentString(), varIndex, varExp, node.Identifier.Text);
                OutputExpressionSyntax(node.Expression, opd);
                CodeBuilder.Append(", ");
                CodeBuilder.Append(elemTypeName);
                CodeBuilder.Append(", ");
                CodeBuilder.Append(elemTypeKind);
                CodeBuilder.Append(", ");
                CodeBuilder.Append(objTypeName);
                CodeBuilder.Append(", ");
                CodeBuilder.Append(listTypeName);
                CodeBuilder.Append(", ");
                CodeBuilder.Append(isCs2Dsl ? "false" : "true");
                CodeBuilder.AppendLine("){");
            }
            else
            {
                MarkNeedFuncInfo();
                var objType = expType as INamedTypeSymbol;
                INamedTypeSymbol enumType = null;
                var fobj = objType;
                while (null != fobj)
                {
                    if (HasForeachDefined(fobj))
                    {
                        enumType = fobj;
                        break;
                    }
                    fobj = fobj.BaseType;
                }
                bool   isCs2Dsl     = SymbolTable.Instance.IsCs2DslSymbol(enumType);
                string objTypeName  = ClassInfo.GetFullName(objType);
                string enumTypeName = ClassInfo.GetFullName(enumType);
                string varIter      = string.Format("__foreach_{0}", srcPos);
                CodeBuilder.AppendFormat("{0}foreach({1}, {2}, ", GetIndentString(), varIter, node.Identifier.Text);
                OutputExpressionSyntax(node.Expression, opd);
                CodeBuilder.Append(", ");
                CodeBuilder.Append(objTypeName);
                CodeBuilder.Append(", ");
                CodeBuilder.Append(enumTypeName);
                CodeBuilder.Append(", ");
                CodeBuilder.Append(isCs2Dsl ? "false" : "true");
                CodeBuilder.AppendLine("){");
            }
            if (ci.HaveContinue)
            {
                if (ci.HaveBreak)
                {
                    CodeBuilder.AppendFormat("{0}local({1}); {1} = false;", GetIndentString(), ci.BreakFlagVarName);
                    CodeBuilder.AppendLine();
                }
                CodeBuilder.AppendFormat("{0}do{{", GetIndentString());
                CodeBuilder.AppendLine();
            }
            ++m_Indent;
            node.Statement.Accept(this);
            --m_Indent;
            if (ci.HaveContinue)
            {
                CodeBuilder.AppendFormat("{0}}}while(false);", GetIndentString());
                CodeBuilder.AppendLine();
                if (ci.HaveBreak)
                {
                    CodeBuilder.AppendFormat("{0}if({1}){{break;}};", GetIndentString(), ci.BreakFlagVarName);
                    CodeBuilder.AppendLine();
                }
            }
            CodeBuilder.AppendFormat("{0}}};", GetIndentString());
            CodeBuilder.AppendLine();
            m_ContinueInfoStack.Pop();
            mi.TryCatchUsingOrLoopSwitchStack.Pop();
        }
Ejemplo n.º 4
0
        internal void Init(IMethodSymbol sym, SyntaxNode node)
        {
            ParamNames.Clear();
            ReturnParamNames.Clear();
            OutParamNames.Clear();
            OriginalParamsName  = string.Empty;
            ExistYield          = false;
            ExistTopLevelReturn = false;

            ExistTryCatch = false;
            TryCatchLayer = 0;
            ReturnVarName = string.Empty;

            SemanticInfo = sym;
            SyntaxNode   = node;

            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.IsCs2DslSymbol(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)
                {
                    //ref参数与out参数在形参处理时机制相同,实参时out参数传入__cs2dsl_out(适应脚本引擎与dotnet反射的调用规则)
                    ParamNames.Add(string.Format("ref({0})", param.Name));
                    ReturnParamNames.Add(param.Name);
                }
                else if (param.RefKind == RefKind.Out)
                {
                    //ref参数与out参数在形参处理时机制相同,实参时out参数传入__cs2dsl_out(适应脚本引擎与dotnet反射的调用规则)
                    ParamNames.Add(string.Format("out({0})", 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.IsCs2DslSymbol(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;
                }
            }
        }
Ejemplo n.º 5
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)
                {
                    bool isExtern = !SymbolTable.Instance.IsCs2DslSymbol(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 (IsNewObjMember(name))
                        {
                            CodeBuilder.AppendFormat("{0}(SymbolKind.{1}, newobj, \"{2}\")", isExtern ? "getexterninstance" : "getinstance", sym.Kind.ToString(), name);
                            return;
                        }
                        if (sym.ContainingType == classInfo.SemanticInfo || sym.ContainingType == classInfo.SemanticInfo.OriginalDefinition || classInfo.IsInherit(sym.ContainingType))
                        {
                            if (sym.IsStatic)
                            {
                                CodeBuilder.AppendFormat("{0}(SymbolKind.{1}, {2}, \"{3}\")", isExtern ? "getexternstatic" : "getstatic", sym.Kind.ToString(), classInfo.Key, sym.Name);
                            }
                            else
                            {
                                CodeBuilder.AppendFormat("{0}(SymbolKind.{1}, this, \"{2}\")", isExtern ? "getexterninstance" : "getinstance", sym.Kind.ToString(), sym.Name);
                            }
                            return;
                        }
                    }
                    else if (sym.Kind == SymbolKind.Method && (sym.ContainingType == classInfo.SemanticInfo || sym.ContainingType == classInfo.SemanticInfo.OriginalDefinition || classInfo.IsInherit(sym.ContainingType)))
                    {
                        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}(SymbolKind.{1}, {2}, \"{3}\")", isExtern ? "getexternstatic" : "getstatic", sym.Kind.ToString(), classInfo.Key, manglingName);
                            }
                            else
                            {
                                CodeBuilder.AppendFormat("{0}(SymbolKind.{1}, this, \"{2}\")", isExtern ? "getexterninstance" : "getinstance", sym.Kind.ToString(), manglingName);
                            }
                        }
                        else
                        {
                            string className     = ClassInfo.GetFullName(msym.ContainingType);
                            string delegationKey = string.Format("{0}:{1}", className, manglingName);
                            string varName       = string.Format("__delegation_{0}", GetSourcePosForVar(node));

                            CodeBuilder.Append("(function(){ ");

                            string paramsString = string.Join(", ", mi.ParamNames.ToArray());
                            if (msym.IsStatic)
                            {
                                CodeBuilder.AppendFormat("builddelegation(\"{0}\", {1}, \"{2}\", {3}, {4}, {5}, {6});", paramsString, varName, delegationKey, className, manglingName, msym.ReturnsVoid ? "false" : "true", msym.IsStatic ? "true" : "false");
                            }
                            else
                            {
                                CodeBuilder.AppendFormat("builddelegation(\"{0}\", {1}, \"{2}\", {3}, {4}, {5}, {6});", paramsString, varName, delegationKey, "this", manglingName, msym.ReturnsVoid ? "false" : "true", msym.IsStatic ? "true" : "false");
                            }

                            CodeBuilder.Append(" })()");
                        }
                        return;
                    }
                }
                else
                {
                    SymbolKind kind;
                    if (IsNewObjMember(name, out kind))
                    {
                        CodeBuilder.AppendFormat("getinstance(SymbolKind.{0}, newobj, \"{1}\")", kind.ToString(), name);
                        return;
                    }
                    ReportIllegalSymbol(node, symbolInfo);
                }
            }
            CodeBuilder.Append(name);
        }
Ejemplo n.º 6
0
 internal bool IsIgnoredSymbol(ITypeSymbol sym)
 {
     return(m_IgnoredTypes.ContainsKey(ClassInfo.GetFullName(sym)));
 }
Ejemplo n.º 7
0
        internal string CalcFullNameAndTypeArguments(INamedTypeSymbol sym)
        {
            var name = ClassInfo.GetFullName(sym);

            return(CalcFullNameAndTypeArguments(name, sym));
        }
Ejemplo n.º 8
0
        internal static void CheckInvocation(IMethodSymbol sym, IMethodSymbol callerSym)
        {
            if (!SymbolTable.EnableTranslationCheck)
            {
                return;
            }
            if (ClassInfo.HasAttribute(sym, "Cs2Dsl.DontCheckAttribute"))
            {
                return;
            }
            if (null != callerSym && ClassInfo.HasAttribute(callerSym, "Cs2Dsl.DontCheckAttribute"))
            {
                return;
            }
            if (null != callerSym && ClassInfo.HasAttribute(callerSym.ContainingType, "Cs2Dsl.DontCheckAttribute"))
            {
                return;
            }

            if (!SymbolTable.Instance.IsCs2DslSymbol(sym))
            {
                var ckey = ClassInfo.GetFullName(sym.ContainingType);
                var id   = string.Format("{0}.{1}", ckey, sym.Name);
                if (!SymbolTable.Instance.CheckedInvocations.Contains(id))
                {
                    SymbolTable.Instance.CheckedInvocations.Add(id);

                    bool            isOverload = false;
                    ClassSymbolInfo info;
                    if (SymbolTable.Instance.ClassSymbols.TryGetValue(ckey, out info))
                    {
                        info.SymbolOverloadFlags.TryGetValue(sym.Name, out isOverload);
                    }

                    string callerInfo = string.Empty;
                    if (null != callerSym)
                    {
                        var callerClass  = ClassInfo.GetFullName(callerSym.ContainingType);
                        var callerMethod = SymbolTable.Instance.NameMangling(callerSym);
                        callerInfo = string.Format(" caller:{0}.{1}", callerClass, callerMethod);
                    }

                    if (sym.IsExtensionMethod && !SymbolTable.Instance.IsLegalExtension(sym.ContainingType))
                    {
                        //不支持的语法
                        Logger.Instance.Log("Translation Error", "unsupported extern extension method {0}.{1} !{2}", ckey, sym.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                    }
                    else
                    {
                        if (SymbolTable.Instance.IsIllegalMethod(sym))
                        {
                            Logger.Instance.Log("Translation Error", "unsupported extern method {0}.{1} !{2}", ckey, sym.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                        }
                    }

                    if (sym.ContainingType.TypeKind == TypeKind.Delegate || sym.ContainingType.IsGenericType && SymbolTable.Instance.IsLegalGenericType(sym.ContainingType, true) || sym.IsGenericMethod && SymbolTable.Instance.IsLegalGenericMethod(sym))
                    {
                        //如果是标记为合法的泛型类或委托类型的成员,则不用再进行类型检查
                    }
                    else
                    {
                        foreach (var param in sym.Parameters)
                        {
                            var type = param.Type as INamedTypeSymbol;
                            if (param.IsParams && isOverload)
                            {
                                Logger.Instance.Log("Translation Warning", "extern overloaded method {0}.{1} parameter {2} is params, please check export api code !{3}", ckey, sym.Name, param.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                                continue;
                            }
                            if (null != type && type.TypeKind != TypeKind.Delegate)
                            {
                                if (type.IsGenericType)
                                {
                                    if (!SymbolTable.Instance.IsLegalParameterGenericType(type))
                                    {
                                        Logger.Instance.Log("Translation Error", "extern method {0}.{1} parameter {2} is generic type, please replace with non generic type !{3}", ckey, sym.Name, param.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                                    }
                                }
                                else
                                {
                                    if (SymbolTable.Instance.IsIllegalType(type))
                                    {
                                        Logger.Instance.Log("Translation Error", "extern method {0}.{1} parameter {2} is unsupported type, please replace with non generic type !{3}", ckey, sym.Name, param.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                                    }
                                }
                            }
                        }
                        if (!sym.ReturnsVoid)
                        {
                            var type = sym.ReturnType as INamedTypeSymbol;
                            if (null != type && type.TypeKind != TypeKind.Delegate)
                            {
                                if (type.IsGenericType)
                                {
                                    if (!SymbolTable.Instance.IsLegalParameterGenericType(type))
                                    {
                                        Logger.Instance.Log("Translation Error", "extern method {0}.{1} return {2} is generic type, please replace with non generic type !{3}", ckey, sym.Name, type.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                                    }
                                }
                                else
                                {
                                    if (SymbolTable.Instance.IsIllegalType(type))
                                    {
                                        Logger.Instance.Log("Translation Error", "extern method {0}.{1} return {2} is unsupported type, please replace with non generic type !{3}", ckey, sym.Name, type.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 9
0
        internal static void CheckInvocation(SemanticModel model, IMethodSymbol sym, IList <ExpressionSyntax> args, IList <ArgDefaultValueInfo> defValArgs, IList <IConversionExpression> argConversions, SyntaxNode node, IMethodSymbol callerSym)
        {
            if (!SymbolTable.EnableTranslationCheck)
            {
                return;
            }
            if (ClassInfo.HasAttribute(sym, "Cs2Dsl.DontCheckAttribute"))
            {
                return;
            }
            if (null != callerSym && ClassInfo.HasAttribute(callerSym, "Cs2Dsl.DontCheckAttribute"))
            {
                return;
            }
            if (null != callerSym && ClassInfo.HasAttribute(callerSym.ContainingType, "Cs2Dsl.DontCheckAttribute"))
            {
                return;
            }

            if (!SymbolTable.Instance.IsCs2DslSymbol(sym))
            {
                var ckey = ClassInfo.GetFullName(sym.ContainingType);
                var oper = null != node?model.GetOperationEx(node) as IInvocationExpression : null;

                var realType = null != oper && null != oper.Instance ? oper.Instance.Type : null;

                bool            isOverload = false;
                ClassSymbolInfo info;
                if (SymbolTable.Instance.ClassSymbols.TryGetValue(ckey, out info))
                {
                    info.SymbolOverloadFlags.TryGetValue(sym.Name, out isOverload);
                }

                string callerInfo = string.Empty;
                if (null != callerSym)
                {
                    var callerClass  = ClassInfo.GetFullName(callerSym.ContainingType);
                    var callerMethod = SymbolTable.Instance.NameCs2DslMangling(callerSym);
                    callerInfo = string.Format(" caller:{0}.{1}", callerClass, callerMethod);
                }

                if (sym.IsExtensionMethod && !SymbolTable.Instance.IsLegalExtension(sym.ContainingType))
                {
                    //不支持的语法
                    Logger.Instance.Log(node, "unsupported extern extension method {0}.{1} !{2}", ckey, sym.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                }
                else
                {
                    if (SymbolTable.Instance.IsIllegalMethod(sym))
                    {
                        Logger.Instance.Log(node, "unsupported extern method {0}.{1} !{2}", ckey, sym.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                    }
                }

                if (sym.ContainingType.TypeKind == TypeKind.Delegate ||
                    (null == realType || realType == sym.ContainingType) && sym.ContainingType.IsGenericType && SymbolTable.Instance.IsLegalGenericType(sym.ContainingType, true) ||
                    sym.IsGenericMethod && SymbolTable.Instance.IsLegalGenericMethod(sym))
                {
                    //如果是标记为合法的泛型类或委托类型的成员,则不用再进行类型检查
                }
                else
                {
                    int ix = 0;
                    foreach (var param in sym.Parameters)
                    {
                        IOperation argOper = null;
                        if (ix < args.Count)
                        {
                            argOper = null != args[ix] ? model.GetOperationEx(args[ix]) : null;
                        }
                        else if (ix < args.Count + defValArgs.Count)
                        {
                            argOper = defValArgs[ix - args.Count].OperOrSym as IOperation;
                        }
                        IConversionExpression argConv = null;
                        if (ix < argConversions.Count)
                        {
                            argConv = argConversions[ix];
                        }
                        ++ix;
                        INamedTypeSymbol argType = null;
                        if (null != argOper && (null == argConv || !argConv.UsesOperatorMethod))
                        {
                            argType = argOper.Type as INamedTypeSymbol;
                        }
                        var paramType = param.Type as INamedTypeSymbol;
                        if (param.IsParams && isOverload)
                        {
                            Logger.Instance.Log(node, "extern overloaded method {0}.{1} parameter {2} is params, please check export api code !{3}", ckey, sym.Name, param.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                            continue;
                        }
                        if (null != paramType && paramType.TypeKind != TypeKind.Delegate)
                        {
                            bool isContainerIntf = paramType.Name == "IEnumerable" || paramType.Name == "ICollection" || paramType.Name == "IDictionary" || paramType.Name == "IList";
                            if (null != realType && SymbolTable.Instance.IsCs2DslSymbol(realType) && isContainerIntf &&
                                null != argType && (argType.IsGenericType || SymbolTable.Instance.IsCs2DslSymbol(argType)))
                            {
                                Logger.Instance.Log(node, "extern method {0}.{1} parameter {2} can't assign a script object to it !{3}", ckey, sym.Name, param.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                            }
                            else if (paramType.IsGenericType)
                            {
                                if (!SymbolTable.Instance.IsLegalParameterGenericType(paramType))
                                {
                                    Logger.Instance.Log(node, "extern method {0}.{1} parameter {2} is generic type, please replace with non generic type !{3}", ckey, sym.Name, param.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                                }
                            }
                            else
                            {
                                if (SymbolTable.Instance.IsIllegalType(paramType))
                                {
                                    Logger.Instance.Log(node, "extern method {0}.{1} parameter {2} is unsupported type, please replace with non generic type !{3}", ckey, sym.Name, param.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                                }
                            }
                        }
                    }
                    if (!sym.ReturnsVoid)
                    {
                        var type = sym.ReturnType as INamedTypeSymbol;
                        if (null != type && type.TypeKind != TypeKind.Delegate)
                        {
                            if (type.IsGenericType)
                            {
                                if (!SymbolTable.Instance.IsLegalParameterGenericType(type))
                                {
                                    Logger.Instance.Log(node, "extern method {0}.{1} return {2} is generic type, please replace with non generic type !{3}", ckey, sym.Name, type.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                                }
                            }
                            else
                            {
                                if (SymbolTable.Instance.IsIllegalType(type))
                                {
                                    Logger.Instance.Log(node, "extern method {0}.{1} return {2} is unsupported type, please replace with non generic type !{3}", ckey, sym.Name, type.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 10
0
        internal string CalcTryUsingFuncOptions(DataFlowAnalysis dataFlow, ControlFlowAnalysis ctrlFlow, List <string> inputs, List <string> outputs)
        {
            string returnType         = "System.Int32";
            string returnTypeKind     = "TypeKind.Struct";
            bool   returnTypeIsExtern = false;

            var sb = new StringBuilder();

            sb.AppendFormat("needfuncinfo({0}), rettype(return, {1}, {2}, 0, true)", NeedFuncInfo ? "true" : "false", returnType, returnTypeKind);
            if (ctrlFlow.ReturnStatements.Length > 0 && !string.IsNullOrEmpty(ReturnVarName))
            {
                returnType = ClassInfo.GetFullName(SemanticInfo.ReturnType);
                if (string.IsNullOrEmpty(returnType))
                {
                    returnType = "null";
                }
                returnTypeKind     = "TypeKind." + SemanticInfo.ReturnType.TypeKind.ToString();
                returnTypeIsExtern = !SymbolTable.Instance.IsCs2DslSymbol(SemanticInfo.ReturnType);
                sb.Append(", ");
                sb.AppendFormat("rettype({0}, {1}, {2}, 1, {3})", ReturnVarName, returnType, returnTypeKind, returnTypeIsExtern ? "true" : "false");
            }
            foreach (var v in dataFlow.DataFlowsOut)
            {
                sb.Append(", ");
                int refOrOut = 2;
                if (inputs.Contains(v.Name))
                {
                    refOrOut = 1;
                }
                var psym = v as IParameterSymbol;
                var lsym = v as ILocalSymbol;
                if (null != psym)
                {
                    var  type     = ClassInfo.GetFullName(psym.Type);
                    var  typeKind = psym.Type.TypeKind.ToString();
                    bool isExtern = !SymbolTable.Instance.IsCs2DslSymbol(psym.Type);
                    if (string.IsNullOrEmpty(type))
                    {
                        type = "null";
                    }
                    sb.AppendFormat("rettype({0}, {1}, {2}, {3}, {4})", v.Name, type, typeKind, refOrOut, isExtern ? "true" : "false");
                }
                else if (null != lsym)
                {
                    var  type     = ClassInfo.GetFullName(lsym.Type);
                    var  typeKind = lsym.Type.TypeKind.ToString();
                    bool isExtern = !SymbolTable.Instance.IsCs2DslSymbol(lsym.Type);
                    if (string.IsNullOrEmpty(type))
                    {
                        type = "null";
                    }
                    sb.AppendFormat("rettype({0}, {1}, {2}, {3}, {4})", v.Name, type, typeKind, refOrOut, isExtern ? "true" : "false");
                }
            }
            if (ctrlFlow.ReturnStatements.Length > 0 && !string.IsNullOrEmpty(ReturnVarName))
            {
                sb.Append(", ");
                sb.AppendFormat("paramtype({0}, {1}, {2}, 1, {3})", ReturnVarName, returnType, returnTypeKind, returnTypeIsExtern ? "true" : "false");
            }
            foreach (var v in dataFlow.DataFlowsIn)
            {
                if (v.Name == "this")
                {
                    continue;
                }
                sb.Append(", ");
                int refOrOut = 0;
                if (outputs.Contains(v.Name))
                {
                    refOrOut = 1;
                }
                var psym = v as IParameterSymbol;
                var lsym = v as ILocalSymbol;
                if (null != psym)
                {
                    var  type     = ClassInfo.GetFullName(psym.Type);
                    var  typeKind = psym.Type.TypeKind.ToString();
                    bool isExtern = !SymbolTable.Instance.IsCs2DslSymbol(psym.Type);
                    if (string.IsNullOrEmpty(type))
                    {
                        type = "null";
                    }
                    sb.AppendFormat("paramtype({0}, {1}, {2}, {3}, {4})", v.Name, type, typeKind, refOrOut, isExtern ? "true" : "false");
                }
                else if (null != lsym)
                {
                    var  type     = ClassInfo.GetFullName(lsym.Type);
                    var  typeKind = lsym.Type.TypeKind.ToString();
                    bool isExtern = !SymbolTable.Instance.IsCs2DslSymbol(lsym.Type);
                    if (string.IsNullOrEmpty(type))
                    {
                        type = "null";
                    }
                    sb.AppendFormat("paramtype({0}, {1}, {2}, {3}, {4})", v.Name, type, typeKind, refOrOut, isExtern ? "true" : "false");
                }
            }
            foreach (var v in dataFlow.DataFlowsOut)
            {
                sb.Append(", ");
                int refOrOut = 2;
                if (inputs.Contains(v.Name))
                {
                    refOrOut = 1;
                }
                var psym = v as IParameterSymbol;
                var lsym = v as ILocalSymbol;
                if (null != psym)
                {
                    var  type     = ClassInfo.GetFullName(psym.Type);
                    var  typeKind = psym.Type.TypeKind.ToString();
                    bool isExtern = !SymbolTable.Instance.IsCs2DslSymbol(psym.Type);
                    if (string.IsNullOrEmpty(type))
                    {
                        type = "null";
                    }
                    sb.AppendFormat("paramtype({0}, {1}, {2}, {3}, {4})", v.Name, type, typeKind, refOrOut, isExtern ? "true" : "false");
                }
                else if (null != lsym)
                {
                    var  type     = ClassInfo.GetFullName(lsym.Type);
                    var  typeKind = lsym.Type.TypeKind.ToString();
                    bool isExtern = !SymbolTable.Instance.IsCs2DslSymbol(lsym.Type);
                    if (string.IsNullOrEmpty(type))
                    {
                        type = "null";
                    }
                    sb.AppendFormat("paramtype({0}, {1}, {2}, {3}, {4})", v.Name, type, typeKind, refOrOut, isExtern ? "true" : "false");
                }
            }
            return(sb.ToString());
        }
Ejemplo n.º 11
0
        private void VisitTypeDeclarationSyntax(TypeDeclarationSyntax node)
        {
            INamedTypeSymbol declSym = m_Model.GetDeclaredSymbol(node);

            SymbolTable.Instance.AddGenericTypeDefine(ClassInfo.GetFullNameWithTypeParameters(declSym), node);
        }
Ejemplo n.º 12
0
        internal string CalcFunctionOptions()
        {
            if (string.IsNullOrEmpty(FunctionOptions))
            {
                string returnName = "return";
                string returnType;
                string returnTypeKind;
                bool   returnTypeIsExtern = false;
                if (SemanticInfo.ReturnsVoid)
                {
                    returnType     = "System.Void";
                    returnTypeKind = "TypeKind.Unknown";
                }
                else
                {
                    returnType = ClassInfo.GetFullName(SemanticInfo.ReturnType);
                    if (SemanticInfo.ReturnType.TypeKind == TypeKind.TypeParameter)
                    {
                        var retTypeParam = SemanticInfo.ReturnType as ITypeParameterSymbol;
                        if (null != retTypeParam && retTypeParam.ConstraintTypes.Length > 0)
                        {
                            returnName = returnType;
                            returnType = ClassInfo.GetFullName(retTypeParam.ConstraintTypes[0]);
                        }
                    }
                    if (string.IsNullOrEmpty(returnType))
                    {
                        returnType = "null";
                    }
                    returnTypeKind     = "TypeKind." + SemanticInfo.ReturnType.TypeKind.ToString();
                    returnTypeIsExtern = !SymbolTable.Instance.IsCs2DslSymbol(SemanticInfo.ReturnType);
                }

                var sb = new StringBuilder();
                sb.AppendFormat("needfuncinfo({0}), rettype({1}, {2}, {3}, 0, {4})", NeedFuncInfo ? "true" : "false", returnName, returnType, returnTypeKind, returnTypeIsExtern ? "true" : "false");
                for (int ix = 0; ix < ReturnParamNames.Count; ++ix)
                {
                    var name = ReturnParamNames[ix];
                    var type = ReturnParamTypes[ix];
                    if (string.IsNullOrEmpty(type))
                    {
                        type = "null";
                    }
                    var typekind = ReturnParamTypeKinds[ix];
                    var refOrOut = ReturnParamRefOrOuts[ix];
                    var isExtern = ReturnParamIsExterns[ix];
                    sb.Append(", ");
                    sb.AppendFormat("rettype({0}, {1}, {2}, {3}, {4})", name, type, typekind, refOrOut, isExtern ? "true" : "false");
                }
                for (int ix = 0; ix < ParamNames.Count; ++ix)
                {
                    var name = ParamNames[ix];
                    var type = ParamTypes[ix];
                    if (string.IsNullOrEmpty(type))
                    {
                        type = "null";
                    }
                    var typekind = ParamTypeKinds[ix];
                    var refOrOut = ParamRefOrOuts[ix];
                    var isExtern = ParamIsExterns[ix];
                    sb.Append(", ");
                    sb.AppendFormat("paramtype({0}, {1}, {2}, {3}, {4})", name, type, typekind, refOrOut, isExtern ? "true" : "false");
                }
                FunctionOptions = sb.ToString();
            }
            return(FunctionOptions);
        }
Ejemplo n.º 13
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.GetSymbolInfoEx(node);
                var        sym        = symbolInfo.Symbol;
                if (null != sym)
                {
                    bool isExtern = !SymbolTable.Instance.IsCs2DslSymbol(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)
                    {
                        var    fsym     = sym as IFieldSymbol;
                        var    psym     = sym as IPropertySymbol;
                        string fullName = ClassInfo.GetFullName(sym.ContainingType);
                        if (sym.IsStatic)
                        {
                            if (isExtern && null != fsym && fsym.Type.IsValueType && !SymbolTable.IsBasicType(fsym.Type))
                            {
                                MarkNeedFuncInfo();
                                CodeBuilder.AppendFormat("getexternstaticstructmember(SymbolKind.{0}, {1}, \"{2}\")", SymbolTable.Instance.GetSymbolKind(sym), fullName, sym.Name);
                            }
                            else if (isExtern && null != psym && psym.Type.IsValueType && !SymbolTable.IsBasicType(psym.Type))
                            {
                                MarkNeedFuncInfo();
                                CodeBuilder.AppendFormat("getexternstaticstructmember(SymbolKind.{0}, {1}, \"{2}\")", SymbolTable.Instance.GetSymbolKind(sym), fullName, sym.Name);
                            }
                            else
                            {
                                string luaLibFunc;
                                if (null != fsym && SymbolTable.Instance.IsInvokeToLuaLibField(fsym, out luaLibFunc))
                                {
                                    OutputInvokeToLuaLib(true, luaLibFunc, fsym.Type, "SymbolKind.");
                                    CodeBuilder.AppendFormat("{0}, {1}, \"{2}\")", SymbolTable.Instance.GetSymbolKind(sym), fullName, sym.Name);
                                }
                                else if (null != psym && SymbolTable.Instance.IsInvokeToLuaLibProperty(psym, out luaLibFunc))
                                {
                                    OutputInvokeToLuaLib(true, luaLibFunc, psym.Type, "SymbolKind.");
                                    CodeBuilder.AppendFormat("{0}, {1}, \"{2}\")", SymbolTable.Instance.GetSymbolKind(sym), fullName, sym.Name);
                                }
                                else
                                {
                                    CodeBuilder.AppendFormat("{0}(SymbolKind.{1}, {2}, \"{3}\")", isExtern ? "getexternstatic" : "getstatic", SymbolTable.Instance.GetSymbolKind(sym), fullName, sym.Name);
                                }
                            }
                            return;
                        }
                        else if (IsNewObjMember(name))
                        {
                            if (isExtern && null != fsym && fsym.Type.IsValueType && !SymbolTable.IsBasicType(fsym.Type))
                            {
                                MarkNeedFuncInfo();
                                CodeBuilder.AppendFormat("getexterninstancestructmember(SymbolKind.{0}, newobj, {1}, \"{2}\")", SymbolTable.Instance.GetSymbolKind(sym), fullName, name);
                            }
                            else if (isExtern && null != psym && psym.Type.IsValueType && !SymbolTable.IsBasicType(psym.Type))
                            {
                                MarkNeedFuncInfo();
                                CodeBuilder.AppendFormat("getexterninstancestructmember(SymbolKind.{0}, newobj, {1}, \"{2}\")", SymbolTable.Instance.GetSymbolKind(sym), fullName, name);
                            }
                            else
                            {
                                string luaLibFunc;
                                if (null != fsym && SymbolTable.Instance.IsInvokeToLuaLibField(fsym, out luaLibFunc))
                                {
                                    OutputInvokeToLuaLib(true, luaLibFunc, fsym.Type, "SymbolKind.");
                                    CodeBuilder.AppendFormat("{0}, {1}, newobj, \"{2}\")", SymbolTable.Instance.GetSymbolKind(sym), fullName, sym.Name);
                                }
                                else if (null != psym && SymbolTable.Instance.IsInvokeToLuaLibProperty(psym, out luaLibFunc))
                                {
                                    OutputInvokeToLuaLib(true, luaLibFunc, psym.Type, "SymbolKind.");
                                    CodeBuilder.AppendFormat("{0}, {1}, newobj, \"{2}\")", SymbolTable.Instance.GetSymbolKind(sym), fullName, sym.Name);
                                }
                                else
                                {
                                    CodeBuilder.AppendFormat("{0}(SymbolKind.{1}, newobj, {2}, \"{3}\")", isExtern ? "getexterninstance" : "getinstance", SymbolTable.Instance.GetSymbolKind(sym), fullName, name);
                                }
                            }
                            return;
                        }
                        else if (sym.ContainingType == classInfo.SemanticInfo || sym.ContainingType == classInfo.SemanticInfo.OriginalDefinition || classInfo.IsInherit(sym.ContainingType))
                        {
                            if (isExtern && null != fsym && fsym.Type.IsValueType && !SymbolTable.IsBasicType(fsym.Type))
                            {
                                MarkNeedFuncInfo();
                                CodeBuilder.AppendFormat("getexterninstancestructmember(SymbolKind.{0}, this, {1}, \"{2}\")", SymbolTable.Instance.GetSymbolKind(sym), fullName, sym.Name);
                            }
                            else if (isExtern && null != psym && psym.Type.IsValueType && !SymbolTable.IsBasicType(psym.Type))
                            {
                                MarkNeedFuncInfo();
                                CodeBuilder.AppendFormat("getexterninstancestructmember(SymbolKind.{0}, this, {1}, \"{2}\")", SymbolTable.Instance.GetSymbolKind(sym), fullName, sym.Name);
                            }
                            else
                            {
                                string luaLibFunc;
                                if (null != fsym && SymbolTable.Instance.IsInvokeToLuaLibField(fsym, out luaLibFunc))
                                {
                                    OutputInvokeToLuaLib(true, luaLibFunc, fsym.Type, "SymbolKind.");
                                    CodeBuilder.AppendFormat("{0}, this, {1}, \"{2}\")", SymbolTable.Instance.GetSymbolKind(sym), fullName, sym.Name);
                                }
                                else if (null != psym && SymbolTable.Instance.IsInvokeToLuaLibProperty(psym, out luaLibFunc))
                                {
                                    OutputInvokeToLuaLib(true, luaLibFunc, psym.Type, "SymbolKind.");
                                    CodeBuilder.AppendFormat("{0}, this, {1}, \"{2}\")", SymbolTable.Instance.GetSymbolKind(sym), fullName, sym.Name);
                                }
                                else
                                {
                                    CodeBuilder.AppendFormat("{0}(SymbolKind.{1}, this, {2}, \"{3}\")", isExtern ? "getexterninstance" : "getinstance", SymbolTable.Instance.GetSymbolKind(sym), fullName, sym.Name);
                                }
                            }
                            return;
                        }
                    }
                    else if (sym.Kind == SymbolKind.Method)
                    {
                        var    msym         = sym as IMethodSymbol;
                        string manglingName = NameMangling(msym);
                        var    mi           = new MethodInfo();
                        mi.Init(msym, node);
                        string fullName = ClassInfo.GetFullName(sym.ContainingType);
                        if (sym.IsStatic && node.Parent is InvocationExpressionSyntax)
                        {
                            CodeBuilder.AppendFormat("{0}(SymbolKind.{1}, {2}, \"{3}\")", isExtern ? "getexternstatic" : "getstatic", SymbolTable.Instance.GetSymbolKind(sym), fullName, manglingName);
                            return;
                        }
                        else if (sym.ContainingType == classInfo.SemanticInfo || sym.ContainingType == classInfo.SemanticInfo.OriginalDefinition || classInfo.IsInherit(sym.ContainingType))
                        {
                            if (node.Parent is InvocationExpressionSyntax)
                            {
                                CodeBuilder.AppendFormat("{0}(SymbolKind.{1}, this, {2}, \"{3}\")", isExtern ? "getexterninstance" : "getinstance", SymbolTable.Instance.GetSymbolKind(sym), fullName, manglingName);
                            }
                            else
                            {
                                string srcPos        = GetSourcePosForVar(node);
                                string delegationKey = string.Format("{0}:{1}", fullName, manglingName);
                                if (msym.IsStatic)
                                {
                                    CodeBuilder.AppendFormat("builddelegation(\"{0}\", \"{1}\", {2}, {3}, {4})", srcPos, delegationKey, fullName, manglingName, "true");
                                }
                                else
                                {
                                    CodeBuilder.AppendFormat("builddelegation(\"{0}\", \"{1}\", this, {2}, {3})", srcPos, delegationKey, manglingName, "false");
                                }
                            }
                            return;
                        }
                    }
                }
                else
                {
                    string     fn;
                    SymbolKind kind;
                    if (IsNewObjMember(name, out fn, out kind))
                    {
                        CodeBuilder.AppendFormat("getinstance(SymbolKind.{0}, newobj, {1}, \"{2}\")", kind.ToString(), fn, name);
                        return;
                    }
                    ReportIllegalSymbol(node, symbolInfo);
                }
            }
            CodeBuilder.Append(name);
        }
Ejemplo n.º 14
0
        public override void VisitVariableDeclarator(VariableDeclaratorSyntax node)
        {
            var ci       = m_ClassInfoStack.Peek();
            var localSym = m_Model.GetDeclaredSymbol(node) as ILocalSymbol;

            if (null != localSym && localSym.HasConstantValue)
            {
                if (null != node.Initializer)
                {
                    CodeBuilder.AppendFormat("{0}local({1}); {2}", GetIndentString(), node.Identifier.Text, node.Identifier.Text);
                }
                else
                {
                    CodeBuilder.AppendFormat("{0}local({1})", GetIndentString(), node.Identifier.Text);
                }
                CodeBuilder.Append(" = ");
                OutputConstValue(localSym.ConstantValue, localSym);
                CodeBuilder.AppendLine(";");
                return;
            }
            bool        dslToObject = false;
            ITypeSymbol type        = null;

            if (null != node.Initializer)
            {
                type = m_Model.GetTypeInfoEx(node.Initializer.Value).Type;
                if (null != localSym && null != localSym.Type && null != type)
                {
                    dslToObject = InvocationInfo.IsDslToObject(localSym.Type, type);
                }
            }
            VisitLocalVariableDeclarator(ci, node, dslToObject);
            if (null != node.Initializer)
            {
                var valSyntax = node.Initializer.Value;
                var rightType = m_Model.GetTypeInfoEx(valSyntax).Type;
                var rightOper = m_Model.GetOperationEx(valSyntax);
                if (null == rightType && null != rightOper)
                {
                    rightType = rightOper.Type;
                }
                ;
                bool needWrapStruct = NeedWrapStruct(valSyntax, rightType, rightOper, dslToObject);
                if (needWrapStruct)
                {
                    MarkNeedFuncInfo();
                    if (SymbolTable.Instance.IsCs2DslSymbol(type))
                    {
                        CodeBuilder.AppendFormat("{0}{1} = wrapstruct({2}, {3});", GetIndentString(), node.Identifier.Text, node.Identifier.Text, ClassInfo.GetFullName(type));
                        CodeBuilder.AppendLine();
                    }
                    else
                    {
                        string ns = ClassInfo.GetNamespaces(type);
                        if (ns != "System")
                        {
                            CodeBuilder.AppendFormat("{0}{1} = wrapexternstruct({2}, {3});", GetIndentString(), node.Identifier.Text, node.Identifier.Text, ClassInfo.GetFullName(type));
                            CodeBuilder.AppendLine();
                        }
                    }
                }
            }
        }
Ejemplo n.º 15
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 == "System.Object" || BaseClassKey == "System.ValueType")
            {
                BaseClassKey = string.Empty;
            }
            ExistConstructor       = false;
            ExistStaticConstructor = false;

            if (typeSym.GetAttributes().Length > 0)
            {
                ExistAttributes = true;
            }

            Dictionary <string, int> fieldCounts  = new Dictionary <string, int>();
            Dictionary <string, int> methodCounts = new Dictionary <string, int>();

            SymbolTable.Instance.CalcMemberCount(ClassKey, methodCounts, fieldCounts);

            bool fieldUseExplicitTypeParams  = false;
            bool staticUseExplicitTypeParams = false;

            TypeSymbol = typeSym;
            var members = typeSym.GetMembers();

            foreach (var sym in members)
            {
                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 members)
            {
                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);
                    }
                    bool isOverloaded;
                    int  count;
                    if (msym.MethodKind == MethodKind.Constructor && msym.ContainingType.IsValueType)
                    {
                        //值类型构造都按重载处理,总是会生成一个默认构造
                        isOverloaded = true;
                    }
                    else if (methodCounts.TryGetValue(name, out count))
                    {
                        isOverloaded = count > 1;
                    }
                    else
                    {
                        isOverloaded = false;
                    }
                    if (!SymbolOverloadFlags.ContainsKey(name))
                    {
                        SymbolOverloadFlags.Add(name, isOverloaded);
                    }
                    else
                    {
                        SymbolOverloadFlags[name] = isOverloaded;
                    }
                    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);
        }
Ejemplo n.º 16
0
        internal static void CheckMemberAccess(SemanticModel model, MemberAccessExpressionSyntax node, IMethodSymbol callerSym)
        {
            var esym = model.GetSymbolInfoEx(node).Symbol as IEventSymbol;
            var psym = model.GetSymbolInfoEx(node).Symbol as IPropertySymbol;
            var fsym = model.GetSymbolInfoEx(node).Symbol as IFieldSymbol;
            var msym = model.GetSymbolInfoEx(node).Symbol as IMethodSymbol;
            var oper = model.GetOperationEx(node);

            bool             isExtern  = false;
            INamedTypeSymbol classType = null;

            if (null != esym && !SymbolTable.Instance.IsCs2DslSymbol(esym))
            {
                isExtern  = true;
                classType = esym.ContainingType;
                Logger.Instance.Log(node, "unsupported extern event '{0}.{1}' !", ClassInfo.GetFullName(esym.ContainingType), esym.Name);
            }
            if (null != psym && !SymbolTable.Instance.IsCs2DslSymbol(psym))
            {
                isExtern  = true;
                classType = psym.ContainingType;
                if (SymbolTable.Instance.IsIllegalProperty(psym))
                {
                    Logger.Instance.Log(node, "unsupported extern property '{0}.{1}' !", ClassInfo.GetFullName(psym.ContainingType), psym.Name);
                }
            }
            if (null != fsym && !SymbolTable.Instance.IsCs2DslSymbol(fsym))
            {
                isExtern  = true;
                classType = fsym.ContainingType;
                if (SymbolTable.Instance.IsIllegalField(fsym))
                {
                    Logger.Instance.Log(node, "unsupported extern field '{0}.{1}' !", ClassInfo.GetFullName(fsym.ContainingType), fsym.Name);
                }
            }
            if (null != msym && !(node.Parent is InvocationExpressionSyntax) && !SymbolTable.Instance.IsCs2DslSymbol(msym.ContainingType))
            {
                if (SymbolTable.Instance.IsIllegalMethod(msym))
                {
                    Logger.Instance.Log(node, "unsupported extern event '{0}.{1}' !", ClassInfo.GetFullName(msym.ContainingType), msym.Name);
                }
            }
            if (isExtern && null != oper)
            {
                SymbolTable.TryRemoveNullable(ref classType);
                if (null != classType && (classType.TypeKind == TypeKind.Delegate || classType.IsGenericType && SymbolTable.Instance.IsLegalGenericType(classType, true)))
                {
                    //如果是标记为合法的泛型类或委托类型的成员,则不用再进行类型检查
                }
                else
                {
                    var type = oper.Type as INamedTypeSymbol;
                    SymbolTable.TryRemoveNullable(ref type);
                    if (null != type && !SymbolTable.Instance.IsCs2DslSymbol(type) && type.TypeKind != TypeKind.Delegate)
                    {
                        if (type.IsGenericType)
                        {
                            if (!SymbolTable.Instance.IsLegalParameterGenericType(type))
                            {
                                Logger.Instance.Log(node, "unsupported extern type '{0}' from member access !", SymbolTable.Instance.CalcFullNameAndTypeArguments(type));
                            }
                        }
                        else
                        {
                            if (SymbolTable.Instance.IsIllegalType(type))
                            {
                                Logger.Instance.Log(node, "unsupported extern type '{0}' from member access !", SymbolTable.Instance.CalcFullNameAndTypeArguments(type));
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 17
0
        internal static string CalcMethodMangling(IMethodSymbol methodSym)
        {
            IAssemblySymbol assemblySym = SymbolTable.Instance.AssemblySymbol;

            if (null == methodSym)
            {
                return(string.Empty);
            }
            StringBuilder sb   = new StringBuilder();
            string        name = GetMethodName(methodSym);

            if (!string.IsNullOrEmpty(name) && name[0] == '.')
            {
                name = name.Substring(1);
            }
            sb.Append(name);
            if (SymbolTable.Instance.IsCs2DslSymbol(methodSym))
            {
                foreach (var tparam in methodSym.TypeParameters)
                {
                    sb.Append("_");
                    sb.Append(tparam.Name);
                }
                foreach (var param in methodSym.Parameters)
                {
                    sb.Append("__");
                    if (param.RefKind == RefKind.Ref)
                    {
                        sb.Append("Ref_");
                    }
                    else if (param.RefKind == RefKind.Out)
                    {
                        sb.Append("Out_");
                    }
                    var oriparam = param.OriginalDefinition;
                    if (oriparam.Type.Kind == SymbolKind.ArrayType)
                    {
                        sb.Append("Arr_");
                        var    arrSym = oriparam.Type as IArrayTypeSymbol;
                        string fn;
                        if (arrSym.ElementType.TypeKind == TypeKind.TypeParameter)
                        {
                            fn = ClassInfo.GetFullNameWithTypeParameters(arrSym.ElementType);
                        }
                        else
                        {
                            fn = ClassInfo.GetFullName(arrSym.ElementType);
                        }
                        sb.Append(fn.Replace('.', '_'));
                    }
                    else if (oriparam.Type.TypeKind == TypeKind.TypeParameter)
                    {
                        string fn = ClassInfo.GetFullNameWithTypeParameters(oriparam.Type);
                        sb.Append(fn.Replace('.', '_'));
                    }
                    else
                    {
                        //这里使用泛型形参名作为函数签名的一部分,主要是为适应泛型类实例化后仍能保持函数签名一致
                        //因此导致的缺陷是不能支持依靠泛型类型的实参类型来区分的重载函数(这时候就在c#里给函数换个名字吧)
                        string fn = ClassInfo.GetFullName(oriparam.Type);
                        sb.Append(fn.Replace('.', '_'));
                    }
                }
            }
            return(sb.ToString());
        }
Ejemplo n.º 18
0
        internal void Init(IMethodSymbol sym, SyntaxNode node)
        {
            TryCatchUsingOrLoopSwitchStack.Clear();
            TempReturnAnalysisStack.Clear();

            ParamNames.Clear();
            ReturnParamNames.Clear();
            OriginalParamsName  = string.Empty;
            ExistYield          = false;
            ExistTopLevelReturn = false;

            ExistTry      = false;
            TryUsingLayer = 0;
            ReturnVarName = string.Empty;

            SemanticInfo = sym;
            SyntaxNode   = node;

            if (!sym.IsExtensionMethod && sym.IsGenericMethod)
            {
                //不是扩展方法,泛型参数放在参数表最前面
                foreach (var param in sym.TypeParameters)
                {
                    ParamNames.Add(param.Name);
                    if (param.ConstraintTypes.Length > 0)
                    {
                        ParamTypes.Add(ClassInfo.GetFullName(param.ConstraintTypes[0]));
                    }
                    else if (param.HasReferenceTypeConstraint)
                    {
                        ParamTypes.Add("System.Object");
                    }
                    else if (param.HasValueTypeConstraint)
                    {
                        ParamTypes.Add("System.ValueType");
                    }
                    else
                    {
                        ParamTypes.Add("null");
                    }
                    ParamTypeKinds.Add("TypeKind." + param.TypeKind.ToString());
                }
            }

            bool first = true;

            foreach (var param in sym.Parameters)
            {
                if (param.IsParams)
                {
                    var arrTypeSym = param.Type as IArrayTypeSymbol;
                    if (null != arrTypeSym)
                    {
                        string elementType     = ClassInfo.GetFullName(arrTypeSym.ElementType);
                        string elementTypeKind = "TypeKind." + arrTypeSym.ElementType.TypeKind.ToString();
                        ParamsElementInfo = string.Format("{0}, {1}", elementType, elementTypeKind);
                        if (arrTypeSym.ElementType.IsValueType && !SymbolTable.IsBasicType(arrTypeSym.ElementType) && !CsDslTranslater.IsImplementationOfSys(arrTypeSym.ElementType, "IEnumerator"))
                        {
                            string ns = ClassInfo.GetNamespaces(arrTypeSym.ElementType);
                            if (SymbolTable.Instance.IsCs2DslSymbol(arrTypeSym.ElementType))
                            {
                                NeedFuncInfo = true;
                            }
                            else if (ns != "System")
                            {
                                NeedFuncInfo = true;
                            }
                        }
                    }
                    ParamNames.Add("...");
                    ParamTypes.Add(ClassInfo.GetFullName(param.Type));
                    ParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString());
                    OriginalParamsName = param.Name;
                    //遇到变参直接结束(变参set_Item会出现后面带一个value参数的情形,在函数实现里处理)
                    break;
                }
                else if (param.RefKind == RefKind.Ref)
                {
                    if (param.Type.IsValueType && !SymbolTable.IsBasicType(param.Type) && !CsDslTranslater.IsImplementationOfSys(param.Type, "IEnumerator"))
                    {
                        string ns = ClassInfo.GetNamespaces(param.Type);
                        if (SymbolTable.Instance.IsCs2DslSymbol(param.Type))
                        {
                            ValueParams.Add(ParamNames.Count);
                            NeedFuncInfo = true;
                        }
                        else if (ns != "System")
                        {
                            ExternValueParams.Add(ParamNames.Count);
                            NeedFuncInfo = true;
                        }
                    }
                    //ref参数与out参数在形参处理时机制相同,实参时out参数传入__cs2dsl_out(适应脚本引擎与dotnet反射的调用规则)
                    ParamNames.Add(param.Name);
                    ParamTypes.Add(ClassInfo.GetFullName(param.Type));
                    ParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString());
                    ReturnParamNames.Add(param.Name);
                }
                else if (param.RefKind == RefKind.Out)
                {
                    if (param.Type.IsValueType && !SymbolTable.IsBasicType(param.Type) && !CsDslTranslater.IsImplementationOfSys(param.Type, "IEnumerator"))
                    {
                        string ns = ClassInfo.GetNamespaces(param.Type);
                        if (SymbolTable.Instance.IsCs2DslSymbol(param.Type))
                        {
                            OutValueParams.Add(ParamNames.Count);
                            NeedFuncInfo = true;
                        }
                        else if (ns != "System")
                        {
                            OutExternValueParams.Add(ParamNames.Count);
                            NeedFuncInfo = true;
                        }
                    }
                    //ref参数与out参数在形参处理时机制相同,实参时out参数传入__cs2dsl_out(适应脚本引擎与dotnet反射的调用规则)
                    ParamNames.Add(param.Name);
                    ParamTypes.Add(ClassInfo.GetFullName(param.Type));
                    ParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString());
                    ReturnParamNames.Add(param.Name);
                }
                else
                {
                    if (param.Type.IsValueType && !SymbolTable.IsBasicType(param.Type) && !CsDslTranslater.IsImplementationOfSys(param.Type, "IEnumerator"))
                    {
                        string ns = ClassInfo.GetNamespaces(param.Type);
                        if (SymbolTable.Instance.IsCs2DslSymbol(param.Type))
                        {
                            ValueParams.Add(ParamNames.Count);
                            NeedFuncInfo = true;
                        }
                        else if (ns != "System")
                        {
                            ExternValueParams.Add(ParamNames.Count);
                            NeedFuncInfo = true;
                        }
                    }
                    ParamNames.Add(param.Name);
                    ParamTypes.Add(ClassInfo.GetFullName(param.Type));
                    ParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString());
                }
                if (first && sym.IsExtensionMethod && sym.IsGenericMethod)
                {
                    //扩展方法的泛型参数放在第一个参数后
                    foreach (var tp in sym.TypeParameters)
                    {
                        ParamNames.Add(tp.Name);
                        if (tp.ConstraintTypes.Length > 0)
                        {
                            ParamTypes.Add(ClassInfo.GetFullName(tp.ConstraintTypes[0]));
                        }
                        else if (tp.HasReferenceTypeConstraint)
                        {
                            ParamTypes.Add("System.Object");
                        }
                        else if (tp.HasValueTypeConstraint)
                        {
                            ParamTypes.Add("System.ValueType");
                        }
                        else
                        {
                            ParamTypes.Add("null");
                        }
                        ParamTypeKinds.Add("TypeKind." + tp.TypeKind.ToString());
                    }
                }
                first = false;
            }

            if (!sym.ReturnsVoid)
            {
                string returnType = ClassInfo.GetFullName(sym.ReturnType);
                if (returnType.StartsWith("System.Collections") && (sym.ReturnType.Name == "IEnumerable" || sym.ReturnType.Name == "IEnumerator"))
                {
                    var analysis = new YieldAnalysis();
                    analysis.Visit(node);
                    ExistYield = analysis.YieldCount > 0;
                }
            }

            ReturnValueCount = ReturnParamNames.Count + (sym.ReturnsVoid ? 0 : 1);
        }
Ejemplo n.º 19
0
 internal bool IsCs2DslSymbol(IEventSymbol sym)
 {
     return(sym.ContainingAssembly == m_AssemblySymbol && !m_ExternTypes.ContainsKey(ClassInfo.SpecialGetFullTypeName(sym.ContainingType, true)));
 }
Ejemplo n.º 20
0
        internal void Init(IMethodSymbol sym, SemanticModel model)
        {
            MethodSymbol = sym;
            Model        = model;

            Args.Clear();
            DslToObjectArgs.Clear();
            ArgConversions.Clear();
            DefaultValueArgs.Clear();
            DslToObjectDefArgs.Clear();
            ReturnArgs.Clear();
            ReturnValueArgFlags.Clear();
            ReturnArgOperations.Clear();
            ReturnArgSymbols.Clear();
            GenericTypeArgs.Clear();

            ClassKey            = ClassInfo.GetFullName(sym.ContainingType);
            GenericClassKey     = ClassInfo.GetFullNameWithTypeParameters(sym.ContainingType);
            IsEnumClass         = sym.ContainingType.TypeKind == TypeKind.Enum || ClassKey == "System.Enum";
            IsExtensionMethod   = sym.IsExtensionMethod;
            IsBasicValueMethod  = SymbolTable.IsBasicValueMethod(sym);
            IsArrayStaticMethod = ClassKey == "System.Array" && sym.IsStatic;
            IsExternMethod      = !SymbolTable.Instance.IsCs2DslSymbol(sym);

            if ((ClassKey == "UnityEngine.GameObject" || ClassKey == "UnityEngine.Component") && (sym.Name.StartsWith("GetComponent") || sym.Name.StartsWith("AddComponent")))
            {
                IsComponentGetOrAdd = true;
            }

            NonGenericMethodSymbol          = null;
            PostPositionGenericTypeArgs     = false;
            ExternOverloadedMethodSignature = string.Empty;
            if (IsExternMethod)
            {
                var syms = sym.ContainingType.GetMembers(sym.Name);
                if (sym.IsGenericMethod)
                {
                    bool existNonGenericVersion = false;
                    if (null != syms)
                    {
                        //寻找匹配的非泛型版本
                        foreach (var isym in syms)
                        {
                            var msym = isym as IMethodSymbol;
                            if (null != msym && !msym.IsGenericMethod && msym.Parameters.Length == sym.Parameters.Length + sym.TypeParameters.Length)
                            {
                                existNonGenericVersion = true;
                                for (int i = 0; i < sym.TypeParameters.Length; ++i)
                                {
                                    var psym = msym.Parameters[i];
                                    if (psym.Type.Name != "Type")
                                    {
                                        existNonGenericVersion = false;
                                        break;
                                    }
                                }
                                for (int i = 0; i < sym.Parameters.Length; ++i)
                                {
                                    var psym1 = msym.Parameters[i + sym.TypeParameters.Length];
                                    var psym2 = sym.Parameters[i];
                                    if (psym1.Type.Name != psym2.Type.Name && psym2.OriginalDefinition.Type.TypeKind != TypeKind.TypeParameter)
                                    {
                                        existNonGenericVersion = false;
                                        break;
                                    }
                                }
                                if (existNonGenericVersion)
                                {
                                    NonGenericMethodSymbol      = msym;
                                    PostPositionGenericTypeArgs = false;
                                }
                                else
                                {
                                    existNonGenericVersion = true;
                                    for (int i = 0; i < sym.Parameters.Length; ++i)
                                    {
                                        var psym1 = msym.Parameters[i];
                                        var psym2 = sym.Parameters[i];
                                        if (psym1.Type.Name != psym2.Type.Name && psym2.OriginalDefinition.Type.TypeKind != TypeKind.TypeParameter)
                                        {
                                            existNonGenericVersion = false;
                                            break;
                                        }
                                    }
                                    for (int i = 0; i < sym.TypeParameters.Length; ++i)
                                    {
                                        var psym = msym.Parameters[i + sym.Parameters.Length];
                                        if (psym.Type.Name != "Type")
                                        {
                                            existNonGenericVersion = false;
                                            break;
                                        }
                                    }
                                    if (existNonGenericVersion)
                                    {
                                        NonGenericMethodSymbol      = msym;
                                        PostPositionGenericTypeArgs = true;
                                    }
                                }
                                if (existNonGenericVersion)
                                {
                                    break;
                                }
                            }
                        }

                        if (!existNonGenericVersion)
                        {
                            //寻找匹配的变参版本
                            foreach (var isym in syms)
                            {
                                var msym = isym as IMethodSymbol;
                                if (null != msym && !msym.IsGenericMethod && msym.Parameters.Length > 0 && msym.Parameters.Length <= sym.Parameters.Length)
                                {
                                    bool existParamsVersion = true;
                                    var  lastPsym           = msym.Parameters[msym.Parameters.Length - 1];
                                    if (lastPsym.IsParams)
                                    {
                                        for (int i = 0; i < msym.Parameters.Length; ++i)
                                        {
                                            var psym1 = msym.Parameters[i];
                                            var psym2 = sym.Parameters[i];
                                            if (i < msym.Parameters.Length - 1 && psym1.Type.Name != psym2.Type.Name)
                                            {
                                                existParamsVersion = false;
                                                break;
                                            }
                                        }
                                    }
                                    if (existParamsVersion)
                                    {
                                        NonGenericMethodSymbol = msym;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    if (existNonGenericVersion)
                    {
                        foreach (var arg in sym.TypeArguments)
                        {
                            GenericTypeArgs.Add(arg);
                        }
                    }
                    else
                    {
                        //没有找到参数匹配的非泛型版本,则不传递泛型参数类型
                        //这样处理可以适应2类可能有效的情形:
                        //1、如果有多个重载函数,其中有一个object类型变参,则其他泛型参数版本会适配到这个非泛型变参版本
                        //2、有一些方法不需要明确传递泛型参数类型(比如普通实参可推导出泛型参数类型并且泛型参数类型在函数中不明确使用)
                    }
                }

                if (null != syms)
                {
                    int mcount = 0;
                    if (sym.MethodKind == MethodKind.Constructor && sym.ContainingType.IsValueType)
                    {
                        //值类型构造总是按重载处理,默认构造总是会生成
                        mcount = 2;
                    }
                    else
                    {
                        foreach (var isym in syms)
                        {
                            var msym = isym as IMethodSymbol;
                            if (msym.Parameters.Length == 0)
                            {
                                if (msym.Name == "GetType")
                                {
                                    continue;
                                }
                                if (msym.Name == "GetHashCode")
                                {
                                    continue;
                                }
                            }
                            var fn = ClassInfo.GetFullName(msym.ContainingType);
                            if (null != msym && msym.IsStatic == sym.IsStatic && msym.DeclaredAccessibility == Accessibility.Public && !msym.IsImplicitlyDeclared && !msym.IsGenericMethod && !ClassInfo.HasAttribute(msym, "System.ObsoleteAttribute"))
                            {
                                bool existPointer = false;
                                foreach (var partype in msym.Parameters)
                                {
                                    if (partype.Type.TypeKind == TypeKind.Pointer)
                                    {
                                        existPointer = true;
                                        break;
                                    }
                                }
                                if (!existPointer)
                                {
                                    ++mcount;
                                }
                            }
                        }
                    }
                    if (mcount > 1)
                    {
                        ExternOverloadedMethodSignature = SymbolTable.CalcExternOverloadedMethodSignature(sym, NonGenericMethodSymbol);
                    }
                }
                SymbolTable.Instance.TryAddExternReference(sym);
                if (!sym.ReturnsVoid)
                {
                    SymbolTable.Instance.TryAddExternReference(sym.ReturnType);
                }
                foreach (var p in sym.Parameters)
                {
                    if (p.Kind != SymbolKind.TypeParameter)
                    {
                        SymbolTable.Instance.TryAddExternReference(p.Type);
                    }
                }
            }
            else if (sym.IsGenericMethod)
            {
                foreach (var arg in sym.TypeArguments)
                {
                    GenericTypeArgs.Add(arg);
                }
            }
            if (sym.IsGenericMethod)
            {
                foreach (var t in sym.TypeArguments)
                {
                    if (t.TypeKind != TypeKind.TypeParameter)
                    {
                        SymbolTable.Instance.TryAddExternReference(t);
                    }
                }
            }
        }
Ejemplo n.º 21
0
        private void Init(IMethodSymbol sym)
        {
            MethodSymbol = sym;
            TypeChecker.CheckInvocation(sym, CallerMethodSymbol);

            Args.Clear();
            ArgConversions.Clear();
            ReturnArgs.Clear();
            GenericTypeArgs.Clear();

            ClassKey            = ClassInfo.GetFullName(sym.ContainingType);
            GenericClassKey     = ClassInfo.GetFullNameWithTypeParameters(sym.ContainingType);
            IsEnumClass         = sym.ContainingType.TypeKind == TypeKind.Enum || ClassKey == "System.Enum";
            IsExtensionMethod   = sym.IsExtensionMethod;
            IsBasicValueMethod  = SymbolTable.IsBasicValueMethod(sym);
            IsArrayStaticMethod = ClassKey == "System.Array" && sym.IsStatic;
            IsExternMethod      = !SymbolTable.Instance.IsCs2DslSymbol(sym);

            if ((ClassKey == "UnityEngine.GameObject" || ClassKey == "UnityEngine.Component") && (sym.Name.StartsWith("GetComponent") || sym.Name.StartsWith("AddComponent")))
            {
                IsComponentGetOrAdd = true;
            }

            NonGenericMethodSymbol      = null;
            PostPositionGenericTypeArgs = false;
            if (sym.IsGenericMethod)
            {
                bool existNonGenericVersion = !IsExternMethod;
                var  ctype = sym.ContainingType;
                var  syms  = ctype.GetMembers(sym.Name);
                if (null != syms)
                {
                    foreach (var isym in syms)
                    {
                        var msym = isym as IMethodSymbol;
                        if (null != msym && !msym.IsGenericMethod && msym.Parameters.Length == sym.Parameters.Length + sym.TypeParameters.Length)
                        {
                            existNonGenericVersion = true;
                            for (int i = 0; i < sym.TypeParameters.Length; ++i)
                            {
                                var psym = msym.Parameters[i];
                                if (psym.Type.Name != "Type")
                                {
                                    existNonGenericVersion = false;
                                    break;
                                }
                            }
                            for (int i = 0; i < sym.Parameters.Length; ++i)
                            {
                                var psym1 = msym.Parameters[i + sym.TypeParameters.Length];
                                var psym2 = sym.Parameters[i];
                                if (psym1.Type.Name != psym2.Type.Name && psym2.OriginalDefinition.Type.TypeKind != TypeKind.TypeParameter)
                                {
                                    existNonGenericVersion = false;
                                    break;
                                }
                            }
                            if (existNonGenericVersion)
                            {
                                NonGenericMethodSymbol      = msym;
                                PostPositionGenericTypeArgs = false;
                            }
                            else
                            {
                                existNonGenericVersion = true;
                                for (int i = 0; i < sym.Parameters.Length; ++i)
                                {
                                    var psym1 = msym.Parameters[i];
                                    var psym2 = sym.Parameters[i];
                                    if (psym1.Type.Name != psym2.Type.Name && psym2.OriginalDefinition.Type.TypeKind != TypeKind.TypeParameter)
                                    {
                                        existNonGenericVersion = false;
                                        break;
                                    }
                                }
                                for (int i = 0; i < sym.TypeParameters.Length; ++i)
                                {
                                    var psym = msym.Parameters[i + sym.Parameters.Length];
                                    if (psym.Type.Name != "Type")
                                    {
                                        existNonGenericVersion = false;
                                        break;
                                    }
                                }
                                if (existNonGenericVersion)
                                {
                                    NonGenericMethodSymbol      = msym;
                                    PostPositionGenericTypeArgs = true;
                                }
                            }
                            if (existNonGenericVersion)
                            {
                                break;
                            }
                        }
                    }
                }
                if (existNonGenericVersion)
                {
                    foreach (var arg in sym.TypeArguments)
                    {
                        GenericTypeArgs.Add(arg);
                    }
                }
            }

            ExternOverloadedMethodSignature = string.Empty;
            if (IsExternMethod)
            {
                var syms = sym.ContainingType.GetMembers(sym.Name);
                if (null != syms)
                {
                    int mcount = 0;
                    foreach (var isym in syms)
                    {
                        var msym = isym as IMethodSymbol;
                        var fn   = ClassInfo.GetFullName(msym.ContainingType);
                        if (null != msym && msym.IsStatic == sym.IsStatic && msym.DeclaredAccessibility == Accessibility.Public && !msym.IsImplicitlyDeclared && !msym.IsGenericMethod)
                        {
                            ++mcount;
                        }
                    }
                    if (mcount > 1)
                    {
                        ExternOverloadedMethodSignature = SymbolTable.CalcOverloadedMethodSignature(sym, NonGenericMethodSymbol);
                    }
                }
            }
        }
Ejemplo n.º 22
0
        internal void OutputInvocation(StringBuilder codeBuilder, CsDslTranslater cs2dsl, ExpressionSyntax exp, bool isMemberAccess, SemanticModel model, SyntaxNode node)
        {
            IMethodSymbol sym                = MethodSymbol;
            string        mname              = GetMethodName();
            string        prestr             = string.Empty;
            bool          externReturnStruct = IsExternMethod && !sym.ReturnsVoid && sym.ReturnType.IsValueType && !SymbolTable.IsBasicType(sym.ReturnType);

            if (externReturnStruct)
            {
                cs2dsl.MarkNeedFuncInfo();
            }
            if (isMemberAccess)
            {
                string fnOfIntf = string.Empty;
                var    expOper  = model.GetOperationEx(exp);
                bool   isExplicitInterfaceInvoke = cs2dsl.CheckExplicitInterfaceAccess(sym, ref fnOfIntf);
                bool   expIsBasicType            = false;
                if (!sym.IsStatic && null != expOper && SymbolTable.IsBasicType(expOper.Type))
                {
                    expIsBasicType = true;
                }
                if (sym.MethodKind == MethodKind.DelegateInvoke)
                {
                    var memberAccess = node as MemberAccessExpressionSyntax;
                    if (null != memberAccess)
                    {
                        var symInfo = model.GetSymbolInfoEx(node);
                        var masym   = symInfo.Symbol as ISymbol;
                        if (null != masym)
                        {
                            bool   isCs2Lua = SymbolTable.Instance.IsCs2DslSymbol(masym);
                            string kind     = SymbolTable.Instance.GetSymbolKind(masym);
                            string fn       = ClassInfo.GetFullName(masym.ContainingType);
                            string dt       = ClassInfo.GetFullName(sym);
                            if (externReturnStruct)
                            {
                                codeBuilder.Append("callexterndelegationreturnstruct(getinstance(SymbolKind.");
                            }
                            else if (isCs2Lua)
                            {
                                codeBuilder.AppendFormat("call{0}delegation(getinstance(SymbolKind.", IsExternMethod ? "extern" : string.Empty);
                            }
                            else
                            {
                                codeBuilder.AppendFormat("call{0}delegation(getexterninstance(SymbolKind.", IsExternMethod ? "extern" : string.Empty);
                            }
                            codeBuilder.Append(kind);
                            codeBuilder.Append(", ");
                            cs2dsl.OutputExpressionSyntax(exp);
                            codeBuilder.AppendFormat(", {0}, \"{1}\"), \"{2}\"", fn, memberAccess.Name, dt);
                            prestr = ", ";
                        }
                        else
                        {
                            //error;
                        }
                    }
                    else
                    {
                        //error;
                    }
                }
                else if (isExplicitInterfaceInvoke)
                {
                    //这里不区分是否外部符号了,委托到动态语言的脚本库实现,可根据对象运行时信息判断
                    if (externReturnStruct)
                    {
                        codeBuilder.Append("callexterninstancereturnstruct(");
                    }
                    else
                    {
                        codeBuilder.Append("callinstance(");
                    }
                    cs2dsl.OutputExpressionSyntax(exp);
                    codeBuilder.Append(", ");
                    codeBuilder.Append(ClassKey);
                    codeBuilder.Append(", ");
                    codeBuilder.AppendFormat("\"{0}\"", fnOfIntf);
                    prestr = ", ";
                }
                else if (IsExtensionMethod)
                {
                    if (externReturnStruct)
                    {
                        codeBuilder.Append("callexternextensionreturnstruct(");
                    }
                    else if (IsExternMethod)
                    {
                        codeBuilder.Append("callexternextension(");
                    }
                    else
                    {
                        codeBuilder.Append("callextension(");
                    }
                    codeBuilder.AppendFormat("{0}, \"{1}\", ", ClassKey, mname);
                    cs2dsl.OutputExpressionSyntax(exp);
                    prestr = ", ";
                }
                else if (IsBasicValueMethod || expIsBasicType)
                {
                    //这里不区分是否外部符号了,委托到动态语言的脚本库实现,可根据对象运行时信息判断
                    string ckey = CalcInvokeTarget(IsEnumClass, ClassKey, cs2dsl, expOper);
                    codeBuilder.Append("invokeforbasicvalue(");
                    cs2dsl.OutputExpressionSyntax(exp);
                    codeBuilder.Append(", ");
                    codeBuilder.AppendFormat("{0}, {1}, \"{2}\"", IsEnumClass ? "true" : "false", ckey, mname);
                    prestr = ", ";
                }
                else if (IsArrayStaticMethod)
                {
                    //这里不区分是否外部符号了,委托到动态语言的脚本库实现,可根据对象运行时信息判断
                    codeBuilder.Append("invokearraystaticmethod(");
                    if (null == FirstRefArray)
                    {
                        codeBuilder.Append("null, ");
                    }
                    else
                    {
                        cs2dsl.OutputExpressionSyntax(FirstRefArray);
                        codeBuilder.Append(", ");
                    }
                    if (null == SecondRefArray)
                    {
                        codeBuilder.Append("null, ");
                    }
                    else
                    {
                        cs2dsl.OutputExpressionSyntax(SecondRefArray);
                        codeBuilder.Append(", ");
                    }
                    codeBuilder.AppendFormat("\"{0}\"", mname);
                    prestr = ", ";
                }
                else
                {
                    if (sym.IsStatic)
                    {
                        if (externReturnStruct)
                        {
                            codeBuilder.Append("callexternstaticreturnstruct(");
                        }
                        else if (IsExternMethod)
                        {
                            codeBuilder.Append("callexternstatic(");
                        }
                        else
                        {
                            codeBuilder.Append("callstatic(");
                        }
                        codeBuilder.Append(ClassKey);
                    }
                    else
                    {
                        if (externReturnStruct)
                        {
                            codeBuilder.Append("callexterninstancereturnstruct(");
                        }
                        else if (IsExternMethod)
                        {
                            codeBuilder.Append("callexterninstance(");
                        }
                        else
                        {
                            codeBuilder.Append("callinstance(");
                        }
                        cs2dsl.OutputExpressionSyntax(exp);
                        codeBuilder.Append(", ");
                        codeBuilder.Append(ClassKey);
                    }
                    codeBuilder.AppendFormat(", \"{0}\"", mname);
                    prestr = ", ";
                }
            }
            else
            {
                if (sym.MethodKind == MethodKind.DelegateInvoke)
                {
                    cs2dsl.OutputExpressionSyntax(exp);
                    codeBuilder.Append("(");
                }
                else if (sym.IsStatic)
                {
                    if (externReturnStruct)
                    {
                        codeBuilder.Append("callexternstaticreturnstruct(");
                    }
                    else if (IsExternMethod)
                    {
                        codeBuilder.Append("callexternstatic(");
                    }
                    else
                    {
                        codeBuilder.Append("callstatic(");
                    }
                    codeBuilder.Append(ClassKey);
                    codeBuilder.AppendFormat(", \"{0}\"", mname);
                    prestr = ", ";
                }
                else
                {
                    if (externReturnStruct)
                    {
                        codeBuilder.Append("callexterninstancereturnstruct(");
                    }
                    else if (IsExternMethod)
                    {
                        codeBuilder.Append("callexterninstance(");
                    }
                    else
                    {
                        codeBuilder.Append("callinstance(");
                    }
                    codeBuilder.Append("this");
                    codeBuilder.AppendFormat(", {0}, \"{1}\"", ClassKey, mname);
                    prestr = ", ";
                }
            }
            if (Args.Count + DefaultValueArgs.Count + GenericTypeArgs.Count > 0)
            {
                codeBuilder.Append(prestr);
            }
            bool useTypeNameString = false;

            if (IsComponentGetOrAdd && SymbolTable.DslComponentByString)
            {
                var tArgs = sym.TypeArguments;
                if (tArgs.Length > 0 && SymbolTable.Instance.IsCs2DslSymbol(tArgs[0]))
                {
                    useTypeNameString = true;
                }
            }
            TypeChecker.CheckInvocation(model, sym, Args, DefaultValueArgs, ArgConversions, CallerSyntaxNode, CallerMethodSymbol);
            cs2dsl.OutputArgumentList(this, useTypeNameString, node);
            codeBuilder.Append(")");
        }
Ejemplo n.º 23
0
        public override void VisitVariableDeclarator(VariableDeclaratorSyntax node)
        {
            var ci       = m_ClassInfoStack.Peek();
            var localSym = m_Model.GetDeclaredSymbol(node) as ILocalSymbol;

            if (null != localSym && localSym.HasConstantValue)
            {
                if (null != node.Initializer)
                {
                    CodeBuilder.AppendFormat("{0}local({1}); {2}", GetIndentString(), node.Identifier.Text, node.Identifier.Text);
                }
                else
                {
                    CodeBuilder.AppendFormat("{0}local({1})", GetIndentString(), node.Identifier.Text);
                }
                CodeBuilder.Append(" = ");
                OutputConstValue(localSym.ConstantValue, localSym);
                CodeBuilder.AppendLine(";");
                return;
            }
            VisitLocalVariableDeclarator(ci, node);
            if (null != node.Initializer)
            {
                var oper = m_Model.GetOperation(node.Initializer.Value);
                if (null != oper && null != oper.Type && oper.Type.TypeKind == TypeKind.Struct && !CsDslTranslater.IsImplementationOfSys(oper.Type, "IEnumerator"))
                {
                    if (SymbolTable.Instance.IsCs2DslSymbol(oper.Type))
                    {
                        CodeBuilder.AppendFormat("{0}{1} = wrapstruct({2}, {3});", GetIndentString(), node.Identifier.Text, node.Identifier.Text, ClassInfo.GetFullName(oper.Type));
                        CodeBuilder.AppendLine();
                    }
                    else
                    {
                        string ns = ClassInfo.GetNamespaces(oper.Type);
                        if (ns != "System")
                        {
                            CodeBuilder.AppendFormat("{0}{1} = wrapexternstruct({2}, {3});", GetIndentString(), node.Identifier.Text, node.Identifier.Text, ClassInfo.GetFullName(oper.Type));
                            CodeBuilder.AppendLine();
                        }
                    }
                }
            }
        }
Ejemplo n.º 24
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);
                     }
                 }
             }
         }
     }
 }
Ejemplo n.º 25
0
        public override void VisitTryStatement(TryStatementSyntax node)
        {
            if (null != node.Block)
            {
                ClassInfo  ci = m_ClassInfoStack.Peek();
                MethodInfo mi = m_MethodInfoStack.Peek();

                string srcPos         = GetSourcePosForVar(node);
                string retVar         = string.Format("__try_ret_{0}", srcPos);
                string retValVar      = string.Format("__try_retval_{0}", srcPos);
                string handledVar     = string.Format("__catch_handled_{0}", srcPos);
                string catchRetValVar = string.Format("__catch_retval_{0}", srcPos);

                mi.TryCatchUsingOrLoopSwitchStack.Push(true);

                ReturnContinueBreakAnalysis returnAnalysis0 = new ReturnContinueBreakAnalysis();
                returnAnalysis0.RetValVar = retValVar;
                returnAnalysis0.Visit(node.Block);
                mi.TempReturnAnalysisStack.Push(returnAnalysis0);

                if (mi.IsAnonymousOrLambdaMethod)
                {
                    //嵌入函数里的try块不能拆分成方法
                    CodeBuilder.AppendFormat("{0}local({1}, {2}); multiassign({1}, {2}) = dsltry({3}, {1}){{", GetIndentString(), retVar, retValVar, returnAnalysis0.ExistReturnInLoopOrSwitch ? "true" : "false");
                    CodeBuilder.AppendLine();
                    ++m_Indent;
                    ++mi.TryUsingLayer;
                    VisitBlock(node.Block);
                    --mi.TryUsingLayer;
                    --m_Indent;
                    CodeBuilder.AppendFormat("{0}}};", GetIndentString());
                    CodeBuilder.AppendLine();
                }
                else
                {
                    //普通函数里的try块拆分成方法
                    var           dataFlow = m_Model.AnalyzeDataFlow(node.Block);
                    var           ctrlFlow = m_Model.AnalyzeControlFlow(node.Block);
                    List <string> inputs, outputs;
                    string        paramsStr;
                    string        outParamsStr = mi.CalcTryUsingFuncInfo(dataFlow, ctrlFlow, out inputs, out outputs, out paramsStr);

                    returnAnalysis0.OutParamsStr = outParamsStr;

                    string prestr   = ", ";
                    string tryFunc  = string.Format("__try_func_{0}", srcPos);
                    bool   isStatic = mi.SemanticInfo.IsStatic;

                    CodeBuilder.AppendFormat("{0}local({1}, {2}); multiassign({1}, {2}", GetIndentString(), retVar, retValVar);
                    if (!string.IsNullOrEmpty(outParamsStr))
                    {
                        CodeBuilder.Append(prestr);
                        CodeBuilder.Append(outParamsStr);
                    }
                    CodeBuilder.AppendFormat(") = dsltryfunc({0}, {1}, {2}, {3}", retValVar, tryFunc, isStatic ? ci.Key : "this", dataFlow.DataFlowsOut.Length + (string.IsNullOrEmpty(mi.ReturnVarName) ? 1 : 2));
                    if (!string.IsNullOrEmpty(paramsStr))
                    {
                        CodeBuilder.Append(prestr);
                        CodeBuilder.Append(paramsStr);
                    }
                    CodeBuilder.AppendLine("){");
                    ++m_Indent;
                    ++mi.TryUsingLayer;
                    VisitBlock(node.Block);
                    if (outputs.Count > 0 && ctrlFlow.ReturnStatements.Length <= 0)
                    {
                        //return(0)代表非try块里的返回语句
                        CodeBuilder.AppendFormat("{0}return(0", GetIndentString());
                        if (!string.IsNullOrEmpty(outParamsStr))
                        {
                            CodeBuilder.Append(prestr);
                            CodeBuilder.Append(outParamsStr);
                        }
                        CodeBuilder.AppendLine(");");
                    }
                    --mi.TryUsingLayer;
                    --m_Indent;
                    CodeBuilder.AppendFormat("{0}}}options[{1}];", GetIndentString(), mi.CalcTryUsingFuncOptions(dataFlow, ctrlFlow, inputs, outputs));
                    CodeBuilder.AppendLine();
                }

                mi.TempReturnAnalysisStack.Pop();
                mi.TryCatchUsingOrLoopSwitchStack.Pop();

                if (returnAnalysis0.Exist)
                {
                    CodeBuilder.AppendFormat("{0}if({1}){{", GetIndentString(), retVar);
                    CodeBuilder.AppendLine();
                    ++m_Indent;
                    if (null != node.Finally)
                    {
                        VisitFinallyClause(node.Finally);
                    }
                    OutputTryCatchUsingReturn(returnAnalysis0, mi, retValVar);
                    --m_Indent;
                    CodeBuilder.AppendFormat("{0}}};", GetIndentString());
                    CodeBuilder.AppendLine();
                }

                if (node.Catches.Count > 0)
                {
                    CodeBuilder.AppendFormat("{0}local({1}, {2}); {1} = false;", GetIndentString(), handledVar, catchRetValVar);
                    CodeBuilder.AppendLine();
                    foreach (var clause in node.Catches)
                    {
                        ReturnContinueBreakAnalysis returnAnalysis1 = new ReturnContinueBreakAnalysis();
                        returnAnalysis1.RetValVar = null;//catch块代码部分总是包装成一个函数对象
                        returnAnalysis1.Visit(clause.Block);
                        mi.TempReturnAnalysisStack.Push(returnAnalysis1);

                        CodeBuilder.AppendFormat("{0}{1} = dslcatch({2}, {3}, {4},", GetIndentString(), catchRetValVar, handledVar, retValVar, retVar);
                        CodeBuilder.AppendLine();
                        ++m_Indent;
                        ++mi.TryUsingLayer;
                        VisitCatchClause(clause, handledVar);
                        --mi.TryUsingLayer;
                        --m_Indent;
                        CodeBuilder.AppendFormat("{0});", GetIndentString());
                        CodeBuilder.AppendLine();

                        mi.TempReturnAnalysisStack.Pop();

                        if (returnAnalysis1.Exist)
                        {
                            if (null != node.Finally)
                            {
                                VisitFinallyClause(node.Finally);
                            }
                            OutputTryCatchUsingReturn(returnAnalysis1, mi, catchRetValVar);
                        }
                    }
                    if (node.Catches.Count > 1)
                    {
                        if (SymbolTable.EnableTranslationCheck)
                        {
                            Logger.Instance.Log("Translation Warning", "try have multiple catch ! location: {0}", GetSourcePosForLog(node));
                        }
                    }
                }
                if (null != node.Finally)
                {
                    if (returnAnalysis0.Exist)
                    {
                        CodeBuilder.AppendFormat("{0}if(! {1}){{", GetIndentString(), retVar);
                        CodeBuilder.AppendLine();
                        ++m_Indent;
                        VisitFinallyClause(node.Finally);
                        --m_Indent;
                        CodeBuilder.AppendFormat("{0}}};", GetIndentString());
                        CodeBuilder.AppendLine();
                    }
                    else
                    {
                        VisitFinallyClause(node.Finally);
                    }
                }
            }
        }
Ejemplo n.º 26
0
        private static string CalcFullName(ISymbol type, bool includeSelfName)
        {
            if (null == type)
            {
                return(string.Empty);
            }
            List <string> list = new List <string>();

            if (includeSelfName)
            {
                //如果一个类标记为忽略,如果它是泛型类,则创建对象的名字使用泛型参数构建而不是实际类型参数构建
                //这种类因为需要在脚本里手动实现,假定都是可以一个类实现泛型类的功能的。
                //注意:由于这里是计算类型名称,使用命令行参数标记的忽略是没有效果(它使用名称来标记),此时仍然需要使用属性标记忽略的泛型类
                bool ignore = ClassInfo.HasAttribute(type, "Cs2Dsl.IgnoreAttribute");
                if (ignore)
                {
                    list.Add(CalcNameWithTypeParameters(type));
                }
                else
                {
                    list.Add(CalcNameWithTypeArguments(type));
                }
            }
            INamespaceSymbol ns = type.ContainingNamespace;
            var    ct           = type.ContainingType;
            string name         = string.Empty;

            if (null != ct)
            {
                bool ignore = ClassInfo.HasAttribute(ct, "Cs2Dsl.IgnoreAttribute");
                if (ignore)
                {
                    name = CalcNameWithTypeParameters(ct);
                }
                else
                {
                    name = CalcNameWithTypeArguments(ct);
                }
            }
            while (null != ct && name.Length > 0)
            {
                list.Insert(0, name);
                ns = ct.ContainingNamespace;
                ct = ct.ContainingType;
                if (null != ct)
                {
                    bool ignore = ClassInfo.HasAttribute(ct, "Cs2Dsl.IgnoreAttribute");
                    if (ignore)
                    {
                        name = CalcNameWithTypeParameters(ct);
                    }
                    else
                    {
                        name = CalcNameWithTypeArguments(ct);
                    }
                }
                else
                {
                    name = string.Empty;
                }
            }
            while (null != ns && ns.Name.Length > 0)
            {
                list.Insert(0, ns.Name);
                ns = ns.ContainingNamespace;
            }
            return(string.Join(".", list.ToArray()));
        }