Beispiel #1
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 #2
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> memberCounts = new Dictionary <string, int>();

            SymbolTable.Instance.CalcMemberCount(ClassKey, memberCounts);

            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 (memberCounts.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);
        }
Beispiel #3
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 #4
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);
                         }
                     }
                 }
             }
         }
     }
 }