XamlAttachedMembersAddIn.cs :  » Development » Sandcastle » Microsoft » Ddue » Tools » 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 » XamlAttachedMembersAddIn.cs
// Copyright  Microsoft Corporation.
// This source file is subject to the Microsoft Permissive License.
// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
// All other rights reserved.

using System;
using System.Collections.Generic;
using System.Xml;
using System.Xml.XPath;

using System.Compiler;

using Microsoft.Ddue.Tools.Reflection;

namespace Microsoft.Ddue.Tools{

    // XAML add in

    public class XamlAttachedMembersAddIn : MRefBuilderAddIn {

        private Dictionary < Object, Field > attachedMembers = new Dictionary < Object, Field >();

        private Dictionary < TypeNode, Property > contentProperties = new Dictionary < TypeNode, Property >();

        private ManagedReflectionWriter mrw;

        public XamlAttachedMembersAddIn(ManagedReflectionWriter writer, XPathNavigator configuration) : base(writer, configuration) {
            // keep track of the writer
            mrw = writer;

            // register processors as callbacks
            writer.RegisterStartTagCallback("apis", new MRefBuilderCallback(AddAttachedMembers));
            writer.RegisterStartTagCallback("apidata", new MRefBuilderCallback(WriteAttachedMember));
            writer.RegisterStartTagCallback("typedata", new MRefBuilderCallback(WriteContentPropertyData));
            writer.RegisterEndTagCallback("api", new MRefBuilderCallback(WriteAttachmentData));
        }

        private void AddAttachedMembers(XmlWriter writer, object info) {
            NamespaceList spaces = (NamespaceList)info;
            foreach (Namespace space in spaces) {
                TypeNodeList types = space.Types;
                foreach (TypeNode type in types) {

                    MemberList members = type.Members;

                    // go through the members, looking for fields signaling attached properties
                    foreach (Member member in members) {

                        // we need a visible, static, field...
                        if (!member.IsStatic || !member.IsVisibleOutsideAssembly || member.NodeType != NodeType.Field) continue;
                        Field field = (Field)member;

                        // of type dependency property....
                        if (field.Type.FullName != "System.Windows.DependencyProperty") continue;

                        // with a name ending in "Property"...
                        string name = field.Name.Name;
                        if (!name.EndsWith("Property")) continue;
                        name = name.Substring(0, name.Length - 8);

                        // look for a getter and/or a setter

                        Method getter = null;
                        MemberList candidateGetters = type.GetMembersNamed(new Identifier("Get" + name));
                        for (int i = 0; i < candidateGetters.Count; i++) {
                            Member candidateGetter = candidateGetters[i];
                            if ((candidateGetter.NodeType == NodeType.Method) && candidateGetter.IsStatic && candidateGetter.IsVisibleOutsideAssembly) getter = (Method)candidateGetter;
                        }

                        Method setter = null;
                        MemberList candidateSetters = type.GetMembersNamed(new Identifier("Set" + name));
                        for (int i = 0; i < candidateSetters.Count; i++) {
                            Member candidateSetter = candidateSetters[i];
                            if ((candidateSetter.NodeType == NodeType.Method) && candidateSetter.IsStatic && candidateSetter.IsVisibleOutsideAssembly) setter = (Method)candidateSetter;
                        }

                        if ((getter == null) && (setter == null)) continue;

                        // make sure there isn't already such a property

                        Property existingProperty = type.GetProperty(new Identifier(name), new TypeNode[0]);
                        if (existingProperty != null) continue;

                        // okay, this really is an indication of an attached property, so create one

                        Property attachedProperty = new Property(type, null, PropertyFlags.None, new Identifier(name), getter, setter);
                        // attached properties have no parameters
                        attachedProperty.Parameters = ParameterList.Empty;
                        // attached properties are instance properties
                        // somehow mark as attached?
                        type.Members.Add(attachedProperty);
                        attachedMembers.Add(attachedProperty, field);

                    }

                    // go through the members, looking for fields signaling attached events
                    foreach (Member member in members) {

                        if (!member.IsStatic || !member.IsVisibleOutsideAssembly) continue;

                        if (member.NodeType != NodeType.Field) continue;
                        Field field = (Field)member;

                        if (field.Type.FullName != "System.Windows.RoutedEvent") continue;

                        string name = field.Name.Name;
                        if (!name.EndsWith("Event")) continue;
                        name = name.Substring(0, name.Length - 5);

                        Method adder = null;
                        MemberList candidateAdders = type.GetMembersNamed(new Identifier("Add" + name + "Handler"));
                        for (int i = 0; i < candidateAdders.Count; i++) {
                            Member candidateAdder = candidateAdders[i];
                            if ((candidateAdder.NodeType == NodeType.Method) && candidateAdder.IsStatic) adder = (Method)candidateAdder;
                        }

                        Method remover = null;
                        MemberList candidateRemovers = type.GetMembersNamed(new Identifier("Remove" + name + "Handler"));
                        for (int i = 0; i < candidateRemovers.Count; i++) {
                            Member candidateRemover = candidateRemovers[i];
                            if ((candidateRemover.NodeType == NodeType.Method) && candidateRemover.IsStatic) remover = (Method)candidateRemover;
                        }

                        if ((adder == null) || (remover == null)) continue;

                        // make sure there isn't already such an event

                        Event existingEvent = type.GetEvent(new Identifier(name));
                        if (existingEvent != null) continue;

                        // okay, this really is an indication of an attached event, so create one

                        TypeNode handler = adder.Parameters[1].Type;
                        Event attachedEvent = new Event(type, null, EventFlags.None, new Identifier(name), adder, null, remover, handler);
                        attachedEvent.HandlerFlags = adder.Flags;
                        // attached events are instance events
                        // mark as attached?

                        type.Members.Add(attachedEvent);
                        attachedMembers.Add(attachedEvent, field);

                    }

                }
            }

        }

        private Property GetContentProperty(TypeNode type) {
            return (null);
        }

        private void WriteAttachedMember(XmlWriter writer, object info) {

            if (attachedMembers.ContainsKey(info)) {
                if (info is Property) {
                    writer.WriteAttributeString("subsubgroup", "attachedProperty");
                } else if (info is Event) {
                    writer.WriteAttributeString("subsubgroup", "attachedEvent");
                }
            }

        }

        private void WriteAttachmentData(XmlWriter writer, object info) {

            if (attachedMembers.ContainsKey(info)) {

                Member attachedMember = (Member)info;
                if (attachedMember.NodeType == NodeType.Property) {

                    Property attachedProperty = (Property)attachedMember;

                    writer.WriteStartElement("attachedpropertydata");

                    string fieldName = attachedMember.Name + "Property";
                    Field field = attachedMember.DeclaringType.GetField(new Identifier(fieldName));
                    writer.WriteStartElement("field");
                    mrw.WriteMemberReference(field);
                    writer.WriteEndElement();

                    Method getter = attachedProperty.Getter;
                    if (getter != null) {
                        writer.WriteStartElement("getter");
                        mrw.WriteMemberReference(getter);
                        writer.WriteEndElement();
                    }

                    Method setter = attachedProperty.Setter;
                    if (setter != null) {
                        writer.WriteStartElement("setter");
                        mrw.WriteMemberReference(setter);
                        writer.WriteEndElement();
                    }

                    writer.WriteEndElement();

                } else if (attachedMember.NodeType == NodeType.Event) {

                    Event attachedEvent = (Event)attachedMember;

                    writer.WriteStartElement("attachedeventdata");

                    string fieldName = attachedMember.Name + "Event";
                    Field field = attachedMember.DeclaringType.GetField(new Identifier(fieldName));
                    writer.WriteStartElement("field");
                    mrw.WriteMemberReference(field);
                    writer.WriteEndElement();

                    Method adder = attachedEvent.HandlerAdder;
                    writer.WriteStartElement("adder");
                    mrw.WriteMemberReference(adder);
                    writer.WriteEndElement();

                    Method remover = attachedEvent.HandlerRemover;
                    writer.WriteStartElement("remover");
                    mrw.WriteMemberReference(remover);
                    writer.WriteEndElement();

                    writer.WriteEndElement();

                }

            }

        }

        private void WriteContentPropertyData(XmlWriter writer, object info) {
            TypeNode type = (TypeNode)info;
            if (contentProperties.ContainsKey(type)) {

                // get default constructors
                InstanceInitializer constructor = type.GetConstructor(new TypeNode[0]);
                if ((constructor != null) && (!constructor.IsPublic)) constructor = null;

                if (constructor != null) writer.WriteAttributeString("defaultConstructor", mrw.ApiNamer.GetMemberName(constructor));

            }
        }

    }

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