Exemplo n.º 1
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);
        }
Exemplo n.º 2
0
        internal void OutputInvocation(StringBuilder codeBuilder, CsDslTranslater cs2dsl, ExpressionSyntax exp, bool isMemberAccess, SemanticModel model, SyntaxNode node)
        {
            IMethodSymbol sym    = MethodSymbol;
            string        mname  = cs2dsl.NameMangling(IsExtensionMethod && null != sym.ReducedFrom ? sym.ReducedFrom : sym);
            string        prestr = string.Empty;

            if (isMemberAccess)
            {
                string fnOfIntf = "null";
                bool   isExplicitInterfaceInvoke = cs2dsl.CheckExplicitInterfaceAccess(sym, ref fnOfIntf);
                if (sym.MethodKind == MethodKind.DelegateInvoke)
                {
                    var memberAccess = node as MemberAccessExpressionSyntax;
                    if (null != memberAccess)
                    {
                        codeBuilder.Append("callinstance(");
                        cs2dsl.OutputExpressionSyntax(exp);
                        codeBuilder.AppendFormat(", \"{0}\"", memberAccess.Name);
                        prestr = ", ";
                    }
                    else
                    {
                        //error;
                    }
                }
                else if (isExplicitInterfaceInvoke)
                {
                    codeBuilder.Append("invokewithinterface(");
                    cs2dsl.OutputExpressionSyntax(exp);
                    codeBuilder.Append(", ");
                    codeBuilder.AppendFormat("{0}, \"{1}\"", fnOfIntf, mname);
                    prestr = ", ";
                }
                else if (IsExtensionMethod)
                {
                    codeBuilder.Append("callstatic(");
                    codeBuilder.AppendFormat("{0}, \"{1}\", ", ClassKey, mname);
                }
                else if (IsBasicValueMethod)
                {
                    string ckey = CalcInvokeTarget(IsEnumClass, ClassKey, cs2dsl, exp, model);
                    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)
                    {
                        codeBuilder.Append("callstatic(");
                        codeBuilder.Append(ClassKey);
                    }
                    else
                    {
                        codeBuilder.Append("callinstance(");
                        cs2dsl.OutputExpressionSyntax(exp);
                    }
                    codeBuilder.AppendFormat(", \"{0}\"", mname);
                    prestr = ", ";
                }
            }
            else
            {
                if (sym.MethodKind == MethodKind.DelegateInvoke)
                {
                    cs2dsl.OutputExpressionSyntax(exp);
                    codeBuilder.Append("(");
                }
                else if (sym.IsStatic)
                {
                    codeBuilder.Append("callstatic(");
                    codeBuilder.Append(ClassKey);
                    codeBuilder.AppendFormat(", \"{0}\"", mname);
                    prestr = ", ";
                }
                else
                {
                    codeBuilder.Append("callinstance(");
                    codeBuilder.Append("this");
                    codeBuilder.AppendFormat(", \"{0}\"", 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;
                }
            }
            if (IsExtensionMethod)
            {
                var args = new List <ExpressionSyntax>();
                args.Add(exp);
                args.AddRange(Args);
                cs2dsl.OutputArgumentList(args, DefaultValueArgs, GenericTypeArgs, ArrayToParams, useTypeNameString, node, ArgConversions.ToArray());
            }
            else
            {
                cs2dsl.OutputArgumentList(Args, DefaultValueArgs, GenericTypeArgs, ArrayToParams, useTypeNameString, node, ArgConversions.ToArray());
            }
            codeBuilder.Append(")");
        }
Exemplo n.º 3
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();
                            }
                        }
                    }
                }
            }
        }