Reflection.cs :  » Development » Sandcastle » Microsoft » Ddue » Tools » Reflection » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Development » Sandcastle 
Sandcastle » Microsoft » Ddue » Tools » Reflection » Reflection.cs
// Copyright (c) Microsoft Corporation.  All rights reserved.
//

using System;
using System.Collections.Generic;

using System.Compiler;

namespace Microsoft.Ddue.Tools.Reflection{

    public static class ReflectionUtilities {

        public static Event[] GetImplementedEvents(Event trigger) {
            List < Event > list = new List < Event >();

            // get the adder
            Method adder = trigger.HandlerAdder;

            // get interface methods corresponding to this adder
            Method[] implementedAdders = GetImplementedMethods(adder);

            // get the events corresponding to the implemented adders
            foreach (Method implementedAdder in implementedAdders) {
                Event implementedTrigger = GetEventFromAdder(implementedAdder);
                if (implementedTrigger != null) list.Add(implementedTrigger);
            }

            return (list.ToArray());

        }

        public static Method[] GetImplementedMethods(Method method) {
            List < Method > list = new List < Method >();

            // Explicit implementations
            MethodList explicitImplementations = method.ImplementedInterfaceMethods;
            if (explicitImplementations != null) {
                for (int i = 0; i < explicitImplementations.Count; i++) {
                    Method explicitImplementation = explicitImplementations[i];
                    list.Add(explicitImplementation);
                }
            }

            // Implicit implementations
            MethodList implicitImplementations = method.ImplicitlyImplementedInterfaceMethods;
            if (implicitImplementations != null) {
                for (int i = 0; i < implicitImplementations.Count; i++) {
                    Method implicitImplementation = implicitImplementations[i];
                    list.Add(implicitImplementation);
                }
            }

            return (list.ToArray());
        }

        public static Property[] GetImplementedProperties(Property property) {
            List < Property > list = new List < Property >();

            // get an accessor
            Method accessor = property.Getter;
            if (accessor == null) accessor = property.Setter;
            if (accessor == null) return (new Property[0]);

            // get the interface methods corresponding to this accessor
            Method[] methods = GetImplementedMethods(accessor);

            // look for properties corresponding to these methods
            for (int i = 0; i < methods.Length; i++) {
                Method method = methods[i];
                Property entry = GetPropertyFromAccessor(method);
                if (entry != null) list.Add(entry);
            }

            return (list.ToArray());
        }

        public static Namespace GetNamespace(TypeNode type) {
            if (type.DeclaringType != null) {
                return (GetNamespace(type.DeclaringType));
            } else {
                return (new Namespace(type.Namespace));
            }
        }

        public static Member GetTemplateMember(Member member) {

            if (member == null) throw new ArgumentNullException("member");

            // if the containing type isn't generic, the member is the template member
            TypeNode type = member.DeclaringType;
            if (!type.IsGeneric) return (member);

            // if the containing type isn't specialized, the member is the template member
            if (!IsSpecialized(type)) return (member);

            // get the template type, and look for members with the same name
            TypeNode template = ReflectionUtilities.GetTemplateType(member.DeclaringType);
            Identifier name = member.Name;
            MemberList candidates = template.GetMembersNamed(name);

            // if no candidates, say so (this shouldn't happen)
            if (candidates.Count == 0) throw new InvalidOperationException("No members in the template had the name found in the specialization. This is not possible, but apparently it happened.");

            // if only one candidate, return it
            if (candidates.Count == 1) return (candidates[0]);

            // multiple candidates, so now we need to compare parameters
            ParameterList parameters = GetParameters(member);

            for (int i = 0; i < candidates.Count; i++) {
                Member candidate = candidates[i];

                // candidate must be same kind of node
                if (candidate.NodeType != member.NodeType) continue;

                // if parameters match, this is the one
                if (ParametersMatch(parameters, GetParameters(candidate))) return (candidate);

            }

            Console.WriteLine(member.DeclaringType.FullName);
            Console.WriteLine(member.FullName);
            throw new InvalidOperationException("No members in the template matched the parameters of the specialization. This is not possible.");
        }

        public static TypeNode GetTemplateType(TypeNode type) {

            if (type == null) throw new ArgumentNullException("type");
            // Console.WriteLine(type.FullName);

            // only generic types have templates
            if (!type.IsGeneric) return (type);

            if (type.DeclaringType == null) {
                // if the type is not nested, life is simpler

                // if the type is not specified, the type is the template
                if (type.TemplateArguments == null) return (type);

                // otherwise, construct the template type identifier and use it to fetch the template type
                Module templateModule = type.DeclaringModule;
                Identifier name = new Identifier(String.Format("{0}`{1}", type.GetUnmangledNameWithoutTypeParameters(), type.TemplateArguments.Count));
                Identifier space = type.Namespace;
                TypeNode template = templateModule.GetType(space, name);
                return (template);
            } else {
                // if the type is nested, life is harder; we have to walk up the chain, constructing
                // un-specialized identifiers as we go, then walk back down the chain, fetching
                // template types as we go

                // create a stack to keep track of identifiers
                Stack < Identifier > identifiers = new Stack < Identifier >();

                // populate the stack with the identifiers of all the types up to the outermost type
                TypeNode current = type;
                while (true) {
                    int count = 0;
                    if ((current.TemplateArguments != null) && (current.TemplateArguments.Count > count)) count = current.TemplateArguments.Count;
                    if ((current.TemplateParameters != null) && (current.TemplateParameters.Count > count)) count = current.TemplateParameters.Count;
                    TypeNodeList arguments = current.TemplateParameters;
                    if (count == 0) {
                        identifiers.Push(new Identifier(current.GetUnmangledNameWithoutTypeParameters()));
                    } else {
                        identifiers.Push(new Identifier(String.Format("{0}`{1}", current.GetUnmangledNameWithoutTypeParameters(), count)));
                    }
                    // Console.WriteLine("U {0} {1}", identifiers.Peek(), CountArguments(current));
                    if (current.DeclaringType == null) break;
                    current = current.DeclaringType;
                }

                // fetch a TypeNode representing that outermost type
                Module module = current.DeclaringModule;
                Identifier space = current.Namespace;
                current = module.GetType(space, identifiers.Pop());

                // move down the stack to the inner type we want
                while (identifiers.Count > 0) {
                    current = (TypeNode)current.GetMembersNamed(identifiers.Pop())[0];
                    // Console.WriteLine("D {0} {1}", current.GetFullUnmangledNameWithTypeParameters(), CountArguments(current));
                }

                // whew, finally we've got it
                return (current);
            }

        }

        public static bool IsDefaultMember(Member member) {

            if (member == null) throw new ArgumentNullException("member");
            TypeNode type = member.DeclaringType;

            MemberList defaultMembers = type.DefaultMembers;
            for (int i = 0; i < defaultMembers.Count; i++) {
                Member defaultMember = defaultMembers[i];
                if (member == defaultMember) return (true);
            }
            return (false);

        }

        private static Event GetEventFromAdder(Method adder) {
            if (adder == null) throw new ArgumentNullException("adder");
            TypeNode type = adder.DeclaringType;
            MemberList members = type.Members;
            foreach (Member member in members) {
                if (member.NodeType != NodeType.Event) continue;
                Event trigger = member as Event;
                if (trigger.HandlerAdder == adder) return (trigger);
            }
            return (null);
        }

        private static ParameterList GetParameters(Member member) {
            Method method = member as Method;
            if (method != null) return (method.Parameters);

            Property property = member as Property;
            if (property != null) return (property.Parameters);

            return (new ParameterList());
        }

        private static Property GetPropertyFromAccessor(Method accessor) {
            if (accessor == null) throw new ArgumentNullException("accessor");
            TypeNode type = accessor.DeclaringType;
            MemberList members = type.Members;
            foreach (Member member in members) {
                if (member.NodeType != NodeType.Property) continue;
                Property property = member as Property;
                if (property.Getter == accessor) return (property);
                if (property.Setter == accessor) return (property);
            }
            return (null);
        }

        private static bool IsSpecialized(TypeNode type) {
            for (TypeNode t = type; t != null; t = t.DeclaringType) {
                TypeNodeList templates = t.TemplateArguments;
                if ((templates != null) && (templates.Count > 0)) return (true);
            }
            return (false);
        }

        // parameters1 should be fully specialized; parameters2 

        private static bool ParametersMatch(ParameterList parameters1, ParameterList parameters2) {

            if (parameters1.Count != parameters2.Count) return (false);

            for (int i = 0; i < parameters1.Count; i++) {
                TypeNode type1 = parameters1[i].Type;
                TypeNode type2 = parameters2[i].Type;

                // we can't determine the equivilence of template parameters; this is probably not good
                if (type1.IsTemplateParameter || type2.IsTemplateParameter) continue;

                // the node type must be the same; this is probably a fast check
                if (type1.NodeType != type2.NodeType) return (false);

                // if they are "normal" types, we will compare them
                // comparing arrays, pointers, etc. is dangerous, because the types they contian may be template parameters
                if ((type1.NodeType == NodeType.Class) || (type1.NodeType == NodeType.Struct) || (type1.NodeType == NodeType.Interface) ||
                    (type1.NodeType == NodeType.EnumNode) || (type1.NodeType == NodeType.DelegateNode)) {
                    type1 = GetTemplateType(type1);
                    type2 = GetTemplateType(type2);
                    if (!type2.IsStructurallyEquivalentTo(type1)) {
                        // Console.WriteLine("{0} !~ {1}", type1.FullName, type2.FullName);
                        return (false);
                    } else {
                        // Console.WriteLine("{0} ~ {1}", type1.FullName, type2.FullName);
                    }
                }

            }

            return (true);
        }

        private static bool TypeMatch(TypeNode type1, TypeNode type2) {

            // the two types must be of the same kind
            if (type1.NodeType != type2.NodeType) return (false);

            if (type1.NodeType == NodeType.ArrayType) {
                // they are arrays, so check elements
                ArrayType array1 = (ArrayType)type1;
                ArrayType array2 = (ArrayType)type2;
                return (TypeMatch(array1.ElementType, array2.ElementType));
            } else {
                // they are normal types
                return (type1.IsStructurallyEquivalentTo(type2));
            }
        }

    }

}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.