Пример #1
0
        static void _Patch(CodeMemberProperty prop, CodeDomVisitContext ctx, CodeDomResolver resolver)
        {
            if (null != prop)
            {
                // TODO: make sure the member is actually public
                if (null == prop.PrivateImplementationType)
                {
                    var scope  = resolver.GetScope(prop);
                    var td     = scope.DeclaringType;
                    var binder = new CodeDomBinder(scope);
                    for (int ic = td.BaseTypes.Count, i = 0; i < ic; ++i)
                    {
                        var ctr = td.BaseTypes[i];
                        var t   = resolver.TryResolveType(ctr, scope);
                        if (null != t)
                        {
                            var ma = binder.GetPropertyGroup(t, prop.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
                            if (0 < ma.Length)
                            {
                                var p = binder.SelectProperty(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, ma, null, _GetParameterTypes(prop.Parameters), null);
                                if (null != p)
                                {
                                    prop.ImplementationTypes.Add(ctr);
                                }
                            }
                        }
                    }
                }

                prop.UserData.Remove("slang:unresolved");
            }
        }
Пример #2
0
        static void Demo5(CodeCompileUnit ccu)
        {
            // once again, we need one of these
            var res = new CodeDomResolver();

            res.CompileUnits.Add(ccu);
            res.Refresh();
            // we happen to know Program is the 1st type in the 2nd namespace*
            var prg = ccu.Namespaces[1].Types[0];
            // we need the scope where we're at
            var scope = res.GetScope(prg);
            // because our binder attaches to it
            var binder = new CodeDomBinder(scope);
            // now get all the methods with the specified name and flags
            var members = binder.GetMethodGroup(prg, "TestOverload", BindingFlags.Public | BindingFlags.Static);

            Console.WriteLine("There are {0} TestOverload method overloads.", members.Length);
            // try selecting one that takes a single string parameter
            var argTypes1 = new CodeTypeReference[] { new CodeTypeReference(typeof(string)) };
            var m         = binder.SelectMethod(BindingFlags.Public | BindingFlags.Static, members, argTypes1, null);

            if (null != m)
            {
                Console.WriteLine("Select TestOverload(string) returned:");
                _DumpMethod(m);
            }
            else
            {
                Console.WriteLine("Unable to bind to method");
            }
            // try selecting one that takes a single it parameter
            var argTypes2 = new CodeTypeReference[] { new CodeTypeReference(typeof(int)) };

            m = binder.SelectMethod(BindingFlags.Public | BindingFlags.Static, members, argTypes2, null);
            if (null != m)
            {
                Console.WriteLine("Select TestOverload(int) returned:");
                _DumpMethod(m);
            }
            else
            {
                Console.WriteLine("Unable to bind to method");
            }
            Console.WriteLine("Press any key...");
            Console.ReadKey();
            Console.Clear();
        }
Пример #3
0
        static void RunBinding()
        {
            // we'll need the resolver in a bit
            var res = new CodeDomResolver();

            // read the binding sample into the compile unit
            CodeCompileUnit ccu;

            using (var stm = File.OpenRead(@"..\..\Binding.cs"))
                ccu = SlangParser.ReadCompileUnitFrom(stm);

            // add the compile unit to the resolver
            res.CompileUnits.Add(ccu);

            // prepare the resolver
            res.Refresh();

            // get the first class available
            var tdecl = ccu.Namespaces[1].Types[0];
            // capture the scope at the typedecl level
            var scope = res.GetScope(tdecl);
            // create a new binder with that scope
            var binder = new CodeDomBinder(scope);
            // get the method group for Test(...)
            var methodGroup = binder.GetMethodGroup(tdecl, "Test", BindingFlags.Public | BindingFlags.Instance);

            // select the method that can take a string value
            var m = binder.SelectMethod(BindingFlags.Public, methodGroup, new CodeTypeReference[] { new CodeTypeReference(typeof(string)) }, null);

            Console.WriteLine(CU.ToString((CodeMemberMethod)m));

            // select the method that can take a short value
            // (closest match accepts int)
            m = binder.SelectMethod(BindingFlags.Public, methodGroup, new CodeTypeReference[] { new CodeTypeReference(typeof(short)) }, null);
            Console.WriteLine(CU.ToString((CodeMemberMethod)m));
        }
Пример #4
0
 static void _Patch(CodeFieldReferenceExpression fr, CodeDomVisitContext ctx, CodeDomResolver resolver)
 {
     if (null != fr)
     {
         // this probably means part of our field has been resolved, or at the very least
         // it does not come from a rooted var ref.
         if (!fr.TargetObject.UserData.Contains("slang:unresolved"))
         {
             var scope  = resolver.GetScope(fr);
             var binder = new CodeDomBinder(scope);
             var t      = resolver.GetTypeOfExpression(fr.TargetObject, scope);
             if (null != t && CodeDomResolver.IsNullOrVoidType(t) && fr.TargetObject is CodeVariableReferenceExpression)
             {
                 return;                         // can't patch this field yet - it's part of a var reference that hasn't been filled in
             }
             var isStatic = false;
             var tre      = fr.TargetObject as CodeTypeReferenceExpression;
             if (null != tre)
             {
                 isStatic = true;
             }
             var tt = resolver.TryResolveType(isStatic ? tre.Type : t, scope, true);
             if (null == tt)
             {
                 throw new InvalidOperationException(_AppendLineInfo(string.Format("The type {0} could not be resolved", t.BaseType), t));
             }
             var td = tt as CodeTypeDeclaration;
             // TODO: This code could be a lot faster if we added some functionality to the binder
             // we're just checking to see if the method, property or field exists
             var m = binder.GetField(tt, fr.FieldName, _BindFlags);
             if (null != m)
             {
                 fr.UserData.Remove("slang:unresolved");
                 return;
             }
             m = binder.GetEvent(tt, fr.FieldName, _BindFlags);
             if (null != m)
             {
                 var er = new CodeEventReferenceExpression(fr.TargetObject, fr.FieldName);
                 CodeDomVisitor.ReplaceTarget(ctx, er);
                 return;
             }
             var ml = binder.GetMethodGroup(tt, fr.FieldName, _BindFlags);
             if (0 < ml.Length)
             {
                 var mr = new CodeMethodReferenceExpression(fr.TargetObject, fr.FieldName);
                 CodeDomVisitor.ReplaceTarget(ctx, mr);
                 return;
             }
             ml = binder.GetPropertyGroup(tt, fr.FieldName, _BindFlags);
             if (0 < ml.Length)
             {
                 var pr = new CodePropertyReferenceExpression(fr.TargetObject, fr.FieldName);
                 CodeDomVisitor.ReplaceTarget(ctx, pr);
                 return;
             }
             throw new InvalidProgramException(_AppendLineInfo(string.Format("Cannot deterimine the target reference {0}", fr.FieldName), fr));
         }
         // TODO: This used to be first but I moved it here.
         // This shouldn't be done first because it's resolving types before fields and
         // that is a no no. I still need to make sure it doesn't break things
         var path = _GetUnresRootPathOfExpression(fr);
         if (null != path)
         {
             // now we have something to work with.
             var scope = resolver.GetScope(fr);
             var sa    = path.Split('.');
             if (1 == sa.Length)
             {
                 System.Diagnostics.Debugger.Break();
                 throw new NotImplementedException();
             }
             else
             {
                 object            t   = null;
                 string            tn  = null;
                 CodeExpression    tf  = fr;
                 CodeExpression    ptf = null;
                 CodeTypeReference ctr = null;
                 for (var i = sa.Length - 1; i >= 1; --i)
                 {
                     tn  = string.Join(".", sa, 0, i);
                     ptf = tf;
                     tf  = _GetTargetOfExpression(tf);
                     ctr = new CodeTypeReference(tn);
                     t   = resolver.TryResolveType(ctr, scope);
                     if (null != t)
                     {
                         break;
                     }
                 }
                 if (null != t)
                 {
                     var tt = t as Type;
                     if (null != tt)
                     {
                         ctr = new CodeTypeReference(tt);
                     }
                     else
                     {
                         ctr = resolver.GetQualifiedType(ctr, scope);
                     }
                     // we found a type reference
                     _SetTargetOfExpression(ptf, new CodeTypeReferenceExpression(ctr));
                     return;
                     //args.Cancel = true;
                 }
             }
         }
     }
 }
Пример #5
0
        static void _Patch(CodeMemberMethod meth, CodeDomVisitContext ctx, CodeDomResolver resolver)
        {
            if (null != meth)
            {
                // TODO: make sure the member is actually public
                if (null == meth.PrivateImplementationType)
                {
                    var scope  = resolver.GetScope(meth);
                    var td     = scope.DeclaringType;
                    var binder = new CodeDomBinder(scope);
                    for (int ic = td.BaseTypes.Count, i = 0; i < ic; ++i)
                    {
                        var ctr = td.BaseTypes[i];
                        var t   = resolver.TryResolveType(ctr, scope);
                        if (null != t)
                        {
                            var ma = binder.GetMethodGroup(t, meth.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
                            if (0 < ma.Length)
                            {
                                var isIface = false;
                                var ttd     = t as CodeTypeDeclaration;
                                if (null != ttd)
                                {
                                    isIface = ttd.IsInterface;
                                }
                                else
                                {
                                    var rrt = t as Type;
                                    isIface = rrt.IsInterface;
                                }
                                if (isIface)
                                {
                                    var m = binder.SelectMethod(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, ma, _GetParameterTypes(meth.Parameters), null);
                                    if (null != m)
                                    {
                                        meth.ImplementationTypes.Add(ctr);
                                    }
                                }
                            }
                        }
                    }
                }

                meth.UserData.Remove("slang:unresolved");
                if ("Main" == meth.Name && (meth.Attributes & MemberAttributes.ScopeMask) == MemberAttributes.Static)
                {
                    if (0 == meth.Parameters.Count && null == meth.ReturnType || "System.Void" == meth.ReturnType.BaseType)
                    {
                        var epm = new CodeEntryPointMethod();
                        epm.Attributes = meth.Attributes;
                        epm.LinePragma = meth.LinePragma;
                        epm.StartDirectives.AddRange(meth.StartDirectives);
                        epm.EndDirectives.AddRange(meth.EndDirectives);
                        epm.Comments.AddRange(meth.Comments);
                        epm.CustomAttributes.AddRange(meth.CustomAttributes);
                        epm.ReturnTypeCustomAttributes.AddRange(meth.ReturnTypeCustomAttributes);
                        epm.TypeParameters.AddRange(meth.TypeParameters);
                        epm.PrivateImplementationType = meth.PrivateImplementationType;
                        epm.ImplementationTypes.AddRange(meth.ImplementationTypes);
                        epm.Name = meth.Name;
                        epm.Statements.AddRange(meth.Statements);
                        CodeDomVisitor.ReplaceTarget(ctx, epm);
                    }
                }
                //return;
            }
        }