コード例 #1
0
ファイル: MethodInfo.cs プロジェクト: dreamanlan/Cs2Dsl
        internal void Init(IMethodSymbol sym, SyntaxNode node)
        {
            IsAnonymousOrLambdaMethod = node is SimpleLambdaExpressionSyntax || node is ParenthesizedLambdaExpressionSyntax || node is AnonymousMethodExpressionSyntax;
            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());
                    ParamRefOrOuts.Add(0);
                    ParamIsExterns.Add(false);
                }
            }

            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);
                    }
                    ParamNames.Add("...");
                    ParamTypes.Add(ClassInfo.GetFullName(param.Type));
                    ParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString());
                    ParamRefOrOuts.Add(0);
                    ParamIsExterns.Add(!SymbolTable.Instance.IsCs2DslSymbol(param.Type));
                    OriginalParamsName = param.Name;
                    //遇到变参直接结束(变参set_Item会出现后面带一个value参数的情形,在函数实现里处理)
                    break;
                }
                else if (param.RefKind == RefKind.Ref)
                {
                    //ref参数与out参数在形参处理时机制相同,实参时out参数传入__cs2dsl_out(适应脚本引擎与dotnet反射的调用规则)
                    var fn = ClassInfo.GetFullName(param.Type);
                    ParamNames.Add(param.Name);
                    ParamTypes.Add(fn);
                    ParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString());
                    ParamRefOrOuts.Add(1);
                    ParamIsExterns.Add(!SymbolTable.Instance.IsCs2DslSymbol(param.Type));
                    ReturnParamNames.Add(param.Name);
                    ReturnParamTypes.Add(fn);
                    ReturnParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString());
                    ReturnParamRefOrOuts.Add(1);
                    ReturnParamIsExterns.Add(!SymbolTable.Instance.IsCs2DslSymbol(param.Type));
                }
                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反射的调用规则)
                    var fn = ClassInfo.GetFullName(param.Type);
                    ParamNames.Add(param.Name);
                    ParamTypes.Add(fn);
                    ParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString());
                    ParamRefOrOuts.Add(2);
                    ParamIsExterns.Add(!SymbolTable.Instance.IsCs2DslSymbol(param.Type));
                    ReturnParamNames.Add(param.Name);
                    ReturnParamTypes.Add(fn);
                    ReturnParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString());
                    ReturnParamRefOrOuts.Add(2);
                    ReturnParamIsExterns.Add(!SymbolTable.Instance.IsCs2DslSymbol(param.Type));
                }
                else
                {
                    ParamNames.Add(param.Name);
                    ParamTypes.Add(ClassInfo.GetFullName(param.Type));
                    ParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString());
                    ParamRefOrOuts.Add(0);
                    ParamIsExterns.Add(!SymbolTable.Instance.IsCs2DslSymbol(param.Type));
                }
                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());
                        ParamRefOrOuts.Add(0);
                        ParamIsExterns.Add(!SymbolTable.Instance.IsCs2DslSymbol(param.Type));
                    }
                }
                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);
            if (!NeedFuncInfo && ClassInfo.HasAttribute(sym, "Cs2Dsl.NeedFuncInfoAttribute"))
            {
                NeedFuncInfo = true;
            }
        }
コード例 #2
0
        internal void Init(IMethodSymbol sym, SyntaxNode node)
        {
            TryCatchUsingOrLoopSwitchStack.Clear();
            TempReturnAnalysisStack.Clear();

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

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

            SemanticInfo = sym;
            SyntaxNode   = node;

            if (sym.IsGenericMethod)
            {
                foreach (var param in sym.TypeParameters)
                {
                    ParamNames.Add(param.Name);
                    ParamTypes.Add("null");
                    ParamTypeKinds.Add("TypeKind." + param.TypeKind.ToString());
                    GenericMethodTypeParamNames.Add(param.Name);
                }
            }

            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);
                    }
                    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)
                {
                    //ref参数与out参数在形参处理时机制相同,实参时out参数传入__cs2dsl_out(适应脚本引擎与dotnet反射的调用规则)
                    ParamNames.Add(string.Format("ref({0})", 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)
                {
                    //ref参数与out参数在形参处理时机制相同,实参时out参数传入__cs2dsl_out(适应脚本引擎与dotnet反射的调用规则)
                    ParamNames.Add(string.Format("out({0})", param.Name));
                    ParamTypes.Add(ClassInfo.GetFullName(param.Type));
                    ParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString());
                    ReturnParamNames.Add(param.Name);
                    OutParamNames.Add(param.Name);
                }
                else
                {
                    if (param.Type.TypeKind == TypeKind.Struct && !CsDslTranslater.IsImplementationOfSys(param.Type, "IEnumerator"))
                    {
                        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);
                    ParamTypes.Add(ClassInfo.GetFullName(param.Type));
                    ParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString());
                }
            }

            if (!sym.ReturnsVoid)
            {
                var 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;
                }
            }
        }