Beispiel #1
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();
                            }
                        }
                    }
                }
            }
        }
Beispiel #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";
                var    expOper  = model.GetOperation(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)
                    {
                        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 || expIsBasicType)
                {
                    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 (!string.IsNullOrEmpty(ExternOverloadedMethodSignature) || 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, ExternOverloadedMethodSignature, PostPositionGenericTypeArgs, ArrayToParams, useTypeNameString, node, ArgConversions.ToArray());
            }
            else
            {
                cs2dsl.OutputArgumentList(Args, DefaultValueArgs, GenericTypeArgs, ExternOverloadedMethodSignature, PostPositionGenericTypeArgs, ArrayToParams, useTypeNameString, node, ArgConversions.ToArray());
            }
            codeBuilder.Append(")");
        }
Beispiel #3
0
        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;
            }
        }
Beispiel #4
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
                            {
                                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
                            {
                                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
                            {
                                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);
        }
Beispiel #5
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(")");
        }
Beispiel #6
0
        internal void Init(IMethodSymbol sym, BracketedArgumentListSyntax argList, SemanticModel model)
        {
            Init(sym, model);

            if (null != argList)
            {
                var moper = model.GetOperationEx(argList) as IInvocationExpression;
                var args  = argList.Arguments;

                Dictionary <string, ExpressionSyntax> namedArgs = new Dictionary <string, ExpressionSyntax>();
                int ct = 0;
                for (int i = 0; i < args.Count; ++i)
                {
                    var arg     = args[i];
                    var argOper = model.GetOperationEx(arg.Expression);
                    TryAddExternEnum(IsEnumClass, argOper);
                    if (null != arg.NameColon)
                    {
                        namedArgs.Add(arg.NameColon.Name.Identifier.Text, arg.Expression);
                        continue;
                    }
                    if (null != argOper)
                    {
                        TryAddDslToObjectArg(ct, argOper.Type, i);
                    }
                    IConversionExpression lastConv = null;
                    if (ct < sym.Parameters.Length)
                    {
                        var param = sym.Parameters[ct];
                        if (null != moper)
                        {
                            var iarg = moper.GetArgumentMatchingParameter(param);
                            if (null != iarg)
                            {
                                lastConv = iarg.Value as IConversionExpression;
                            }
                        }
                        if (!param.IsParams && param.Type.TypeKind == TypeKind.Array)
                        {
                            RecordRefArray(arg.Expression);
                        }
                        if (param.RefKind == RefKind.Ref)
                        {
                            Args.Add(arg.Expression);
                            ReturnArgs.Add(arg.Expression);
                            var argSym = model.GetSymbolInfoEx(arg.Expression);
                            ReturnArgOperations.Add(argOper);
                            ReturnArgSymbols.Add(argSym.Symbol);
                            if (null != argOper && argOper.Type.IsValueType && !SymbolTable.IsBasicType(argOper.Type))
                            {
                                ReturnValueArgFlags.Add(true);
                            }
                            else
                            {
                                ReturnValueArgFlags.Add(false);
                            }
                        }
                        else if (param.RefKind == RefKind.Out)
                        {
                            //方法的out参数,为与脚本引擎的机制一致,在调用时传入__cs2dsl_out,这里用null标记一下,在实际输出参数时再变为__cs2dsl_out
                            Args.Add(null);
                            ReturnArgs.Add(arg.Expression);
                            var argSym = model.GetSymbolInfoEx(arg.Expression);
                            ReturnArgOperations.Add(argOper);
                            ReturnArgSymbols.Add(argSym.Symbol);
                            if (null != argOper && argOper.Type.IsValueType && !SymbolTable.IsBasicType(argOper.Type))
                            {
                                ReturnValueArgFlags.Add(true);
                            }
                            else
                            {
                                ReturnValueArgFlags.Add(false);
                            }
                        }
                        else if (param.IsParams)
                        {
                            if (null != argOper && null != argOper.Type && argOper.Type.TypeKind == TypeKind.Array)
                            {
                                ArrayToParams = true;
                            }
                            Args.Add(arg.Expression);
                        }
                        else
                        {
                            Args.Add(arg.Expression);
                        }
                        ++ct;
                    }
                    else
                    {
                        Args.Add(arg.Expression);
                    }
                    ArgConversions.Add(lastConv);
                }
                for (int i = ct; i < sym.Parameters.Length; ++i)
                {
                    var param = sym.Parameters[i];
                    if (param.HasExplicitDefaultValue)
                    {
                        IConversionExpression lastConv = null;
                        if (null != moper)
                        {
                            var iarg = moper.GetArgumentMatchingParameter(param);
                            if (null != iarg)
                            {
                                lastConv = iarg.Value as IConversionExpression;
                            }
                        }
                        ArgConversions.Add(lastConv);
                        ExpressionSyntax expval;
                        if (namedArgs.TryGetValue(param.Name, out expval))
                        {
                            var argOper = model.GetOperationEx(expval);
                            if (null != argOper)
                            {
                                TryAddDslToObjectDefArg(i, argOper.Type, i - ct);
                            }
                            DefaultValueArgs.Add(new ArgDefaultValueInfo {
                                Expression = expval
                            });
                        }
                        else
                        {
                            var  decl    = param.DeclaringSyntaxReferences;
                            bool handled = false;
                            if (decl.Length >= 1)
                            {
                                var node = param.DeclaringSyntaxReferences[0].GetSyntax() as ParameterSyntax;
                                if (null != node)
                                {
                                    var exp      = node.Default.Value;
                                    var tree     = node.SyntaxTree;
                                    var newModel = SymbolTable.Instance.Compilation.GetSemanticModel(tree, true);
                                    if (null != newModel)
                                    {
                                        var oper = newModel.GetOperationEx(exp);
                                        if (null != oper)
                                        {
                                            TryAddDslToObjectDefArg(i, oper.Type, i - ct);
                                        }
                                        DefaultValueArgs.Add(new ArgDefaultValueInfo {
                                            Value = param.ExplicitDefaultValue, OperOrSym = oper
                                        });
                                        handled = true;
                                    }
                                }
                            }
                            if (!handled)
                            {
                                DefaultValueArgs.Add(new ArgDefaultValueInfo {
                                    Value = param.ExplicitDefaultValue, OperOrSym = null
                                });
                            }
                        }
                    }
                }
            }
        }