private void CreateClass(CodeNamespace cns, CodeDomObjectNode objectNode, CodeMemberMethod initComponentMethod)
        {
            CodeTypeDeclaration rootType;

            if (objectNode.XClassNode == null)
            {
                rootType = new CodeTypeDeclaration("My" + objectNode.Type.Name);
            }
            else
            {
                rootType = new CodeTypeDeclaration((String)((ValueNode)objectNode.XClassNode.ItemNodes[0]).Value);
            }
            // Keep a copy
            MainCodeClassName = rootType.Name;

            rootType.BaseTypes.Add(new CodeTypeReference(objectNode.Type.UnderlyingType));
            rootType.IsPartial  = true;
            rootType.Attributes = MemberAttributes.Public;
            cns.Types.Add(rootType);
            rootType.Members.Add(initComponentMethod);

            CodeMemberField cmf = new CodeMemberField(typeof(CultureInfo), CultureInfoString);

            cmf.InitExpression = new CodeObjectCreateExpression(typeof(CultureInfo), new CodeSnippetExpression("\"en-us\""), new CodePrimitiveExpression(false));

            rootType.Members.Add(cmf);

            RootObject = rootType;
        }
 private void GenerateUsings(CodeNamespace cns, CodeDomObjectNode objectNode)
 {
     cns.Imports.Add(new CodeNamespaceImport("System"));
     foreach (string namespaceName in NamespacesToUse.Keys)
     {
         cns.Imports.Add(new CodeNamespaceImport(namespaceName));
     }
 }
        private CodeMemberMethod CreateInitializeMethod(CodeNamespace cns, CodeDomObjectNode objectNode)
        {
            TypeConverterDictionary = new Dictionary <Type, string>();
            PublicObjects           = new Dictionary <string, CodeDomObjectNode>();

            CodeMemberMethod initComponentMethod = new CodeConstructor();

            initComponentMethod.Attributes = MemberAttributes.Public;

            CodeThisReferenceExpression thisExpression = new CodeThisReferenceExpression();

            AddMembers(initComponentMethod, thisExpression, objectNode);
            return(initComponentMethod);
        }
        private void AddPublicObjectMembers()
        {
            // Type, Name
            foreach (string targetName in PublicObjects.Keys)
            {
                CodeDomObjectNode targetObjectNode = PublicObjects[targetName];
                if (targetObjectNode.Type.IsUnknown)
                {
                    throw new Exception("Unknown type " + targetObjectNode.Type.Name + " found.");
                }
                CodeMemberField cmf = new CodeMemberField(targetObjectNode.Type.UnderlyingType, targetName);
                cmf.Attributes = MemberAttributes.Public;

                RootObject.Members.Add(cmf);
            }
        }
예제 #5
0
        public override void WriteStartMember(XamlMember property)
        {
            MemberNode propertyNode = new MemberNode();

            propertyNode.Member = property;

            CodeDomObjectNode objectNode = (CodeDomObjectNode)writerStack.Peek();

            writerStack.Push(propertyNode);

            if (property == XamlLanguage.Name || (property.DeclaringType != null && property == property.DeclaringType.GetAliasedProperty(XamlLanguage.Name)))
            {
                objectNode.XNameNode = propertyNode;
            }
            else if (property == XamlLanguage.Class)
            {
                objectNode.XClassNode = propertyNode;
            }
            else if (property == XamlLanguage.Initialization)
            {
                objectNode.XInitNode = propertyNode;
            }
            else if (property == XamlLanguage.PositionalParameters)
            {
                objectNode.XPosParamsNode = propertyNode;
            }
            else if (property == XamlLanguage.FactoryMethod)
            {
                objectNode.XFactoryMethodNode = propertyNode;
            }
            else if (property == XamlLanguage.Arguments)
            {
                objectNode.XArgumentsNode = propertyNode;
            }
            else if (property == XamlLanguage.Key)
            {
                objectNode.XKeyNode = propertyNode;
            }
            else
            {
                if (property.DeclaringType != null && property == property.DeclaringType.GetAliasedProperty(XamlLanguage.Key))
                {
                    objectNode.DictionaryKeyProperty = propertyNode;
                }
                objectNode.MemberNodes.Add(propertyNode);
            }
        }
        public string Convert(XamlReader reader, CodeDomProvider cscProvider)
        {
            MainCodeClassName = string.Empty;
            StringBuilder sb           = new StringBuilder();
            StringWriter  stringWriter = new StringWriter(sb);

            NamespacesToUse = new SortedDictionary <string, object>();

            // TODO: XamlXmlReader can sometimes be null, if there is misformed XML in the first sections of XML
            _schemaContext = reader != null ? reader.SchemaContext : new XamlSchemaContext();
            CodeDomDomWriter codeDomDomWriter = new CodeDomDomWriter(_schemaContext);

            // Load XAML into a specialized XAML DOM, for analysis and processing
            Debug.WriteLine("Building codeDOM from XAML...");
            while (reader.Read())
            {
                codeDomDomWriter.WriteNode(reader);
            }
            Debug.WriteLine("codeDOM complete.");
            CodeDomObjectNode objectNode = (CodeDomObjectNode)codeDomDomWriter.Result;

            //DumpNodeTree(objectNode);

            // Initialize CodeDom constructs
            ICodeGenerator cscg = cscProvider.CreateGenerator(stringWriter);

            ccu = new CodeCompileUnit();
            CodeNamespace cns = new CodeNamespace();

            ccu.Namespaces.Add(cns);

            // Go process XAML DOM
            CodeMemberMethod initMethod = CreateInitializeMethod(cns, objectNode);

            GenerateUsings(cns, objectNode);
            CreateClass(cns, objectNode, initMethod);
            AddPublicObjectMembers();

            // Create code from codeDOM
            cscg.GenerateCodeFromCompileUnit(ccu, stringWriter, new CodeGeneratorOptions());
            string returnText = sb.ToString();

            return(returnText);
        }
예제 #7
0
        public override void WriteNamespace(NamespaceDeclaration namespaceDeclaration)
        {
            CodeDomObjectNode objectNode = null;

            if (writerStack.Count == 0)
            {
                objectNode = new CodeDomObjectNode();
                writerStack.Push(objectNode);
            }
            else
            {
                objectNode = writerStack.Peek() as CodeDomObjectNode;
                if (objectNode.Type != null)
                {
                    objectNode = new CodeDomObjectNode();
                    writerStack.Push(objectNode);
                }
            }
            objectNode.NamespaceNodes.Add(namespaceDeclaration.Prefix, namespaceDeclaration);
        }
예제 #8
0
        void WriteObject(XamlType xamlType, bool isGetObject)
        {
            CodeDomObjectNode objectNode   = null;
            MemberNode        propertyNode = writerStack.Peek() as MemberNode;

            if (writerStack.Count > 0)
            {
                objectNode = writerStack.Peek() as CodeDomObjectNode;
                if (!(objectNode != null && objectNode.NamespaceNodes.Count > 0))
                {
                    objectNode = new CodeDomObjectNode();
                    writerStack.Push(objectNode);
                }
                else
                {
                    //root node
                    objectNode.SchemaContext = SchemaContext;
                }
            }
            else
            {
                //root node
                objectNode = new CodeDomObjectNode();
                objectNode.SchemaContext = SchemaContext;
                writerStack.Push(objectNode);
            }
            objectNode.Type        = xamlType;
            objectNode.IsGetObject = isGetObject;

            if (RootNode != null)
            {
                propertyNode.ItemNodes.Add(objectNode);
            }
            else
            {
                RootNode = objectNode;
            }
        }
        private void DumpNodeTree(CodeDomObjectNode rootNode)
        {
            if (rootNode.Type != null)
            {
                Debug.WriteLine(rootNode.Type.Name);
            }

            NodeCollection <MemberNode> members = rootNode.MemberNodes;

            foreach (MemberNode member in members)
            {
                Debug.WriteLine("Member={0}, Type={1}", new object[] { member.Member.Name, member.Member.Type.Name });

                foreach (ItemNode itemNode in member.ItemNodes)
                {
                    ValueNode valueNode = itemNode as ValueNode;

                    if (valueNode != null)
                    {
                        string value = valueNode.Value as String;
                        Debug.WriteLine("Underlying Type={0}, Value={1}", new object[] { member.Member.Type.UnderlyingType, value });
                    }
                    else
                    {
                        CodeDomObjectNode objectNode = (CodeDomObjectNode)itemNode;
                        XamlType          xamlType   = objectNode.Type;

                        if (xamlType == XamlLanguage.Static)
                        {
                            ValueNode valueNode2        = objectNode.XPosParamsNode.ItemNodes[0] as ValueNode;
                            string    xamlTypeReference = valueNode2.Value as string;
                            string    memberName        = null;
                            string    typeName          = null;
                            int       period            = xamlTypeReference.IndexOf('.');
                            if (period > -1)
                            {
                                memberName = xamlTypeReference.Substring(period + 1);
                                typeName   = xamlTypeReference.Substring(0, period);
                            }
                            Type resolvedType = objectNode.Resolve(typeName);
                            //TODO: don't forget to make sure a using happens for the referencedXamlType
                            string typeName2 = resolvedType != null ? resolvedType.Name : xamlTypeReference;

                            Debug.WriteLine("TypeName={0}, MemberName={1}", new object[] { typeName2, memberName });
                        }
                        else if (xamlType == XamlLanguage.Null)
                        {
                            Debug.WriteLine("NULL Expression");
                        }
                        else if (xamlType == XamlLanguage.Type)
                        {
                            ValueNode valueNode2        = objectNode.XPosParamsNode.ItemNodes[0] as ValueNode;
                            string    xamlTypeReference = valueNode2.Value as string;
                            Type      resolvedType      = objectNode.Resolve(xamlTypeReference);
                            //TODO: don't forget to make sure a using happens for the referencedXamlType
                            string typeName = resolvedType != null ? resolvedType.Name : xamlTypeReference;

                            Debug.WriteLine("Type Ref={0}", new object[] { typeName });
                        }
                        else if (xamlType == XamlLanguage.Reference)
                        {
                        }
                        else
                        {
                            if (objectNode.Type != null)
                            {
                                // StartObject case
                                DumpNodeTree(objectNode);
                            }
                            else
                            {
                                // GetObject
                                DumpNodeTree(objectNode);
                            }
                        }
                    }
                }
            }
        }
        private void GenerateMemberAssignment(CodeMemberMethod initComponentMethod, MemberNode member, CodeExpression targetExpression, CodeExpression valueExpression, CodeDomObjectNode targetObjectNode)
        {
            CodeStatement cs = null;

            //if (member.Member.IsUnknown)
            //{
            //    throw new Exception("Unknown member " + member.Member.Name);
            //}
            if (member.Member == XamlLanguage.Items)
            {
                ObjectNode parentObjectNode = member.ParentObjectNode;
                XamlType   parentType       = null;
                if (parentObjectNode.IsGetObject)
                {
                    parentType = parentObjectNode.ParentMemberNode.Member.Type;
                }
                else
                {
                    parentType = parentObjectNode.Type;
                }
                if (parentType.IsDictionary)
                {
                    if (!typeof(IDictionary).IsAssignableFrom(parentType.UnderlyingType))
                    {
                        throw new NotImplementedException("Support non-IDictionary adds");
                    }
                    CodeExpression keyExpression;
                    if (targetObjectNode.XKeyNode != null)
                    {
                        keyExpression = new CodeSnippetExpression("\"" + ((ValueNode)targetObjectNode.XKeyNode.ItemNodes[0]).Value + "\"");
                    }
                    else
                    {
                        if (targetObjectNode.DictionaryKeyProperty == null)
                        {
                            throw new NotSupportedException("No key on dictionary entry");
                        }
                        throw new NotImplementedException();
                    }
                    cs = new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeCastExpression(typeof(IDictionary), targetExpression), "Add", keyExpression, valueExpression));
                }
                else
                {
                    if (!typeof(IList).IsAssignableFrom(parentType.UnderlyingType))
                    {
                        throw new NotImplementedException("Support non-IList adds");
                    }
                    //TODO: calling Add directly is how I'll leave it for now...
                    //cs = new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeCastExpression(typeof(IList), targetExpression), "Add", valueExpression));
                    cs = new CodeExpressionStatement(new CodeMethodInvokeExpression(targetExpression, "Add", valueExpression));
                }
            }
            else if (member.Member.IsEvent)
            {
                throw new NotImplementedException();
            }
            else
            {
                if (member.Member.IsAttachable)
                {
                    cs = new CodeExpressionStatement(new CodeMethodInvokeExpression(
                                                         new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(member.Member.DeclaringType.UnderlyingType.Name),
                                                                                           "Set" + member.Member.Name), targetExpression, valueExpression));
                }
                else //normal property
                {
                    cs = new CodeAssignStatement(
                        new CodePropertyReferenceExpression(targetExpression, member.Member.Name), valueExpression);
                }
            }
            initComponentMethod.Statements.Add(cs);
        }
        private void GenerateMemberAssignmentWithProvideValueIfNecessary(CodeMemberMethod initComponentMethod, CodeExpression parentExpression, CodeDomObjectNode targetObjectNode,
                                                                         MemberNode parentMember, CodeVariableReferenceExpression cvre)
        {
            //if (parentMember.Member.IsUnknown)
            //{
            //    throw new Exception("Unknown member " + parentMember.Member.Name);
            //}
            XamlType xamlType = targetObjectNode.Type;

            if (xamlType.IsMarkupExtension)
            {
                //call ProvideValue on the ME
                GenerateMemberAssignment(initComponentMethod, parentMember, parentExpression,
                                         new CodeMethodInvokeExpression(cvre, "ProvideValue", new CodeExpression[] {
                    new CodeVariableReferenceExpression("context")
                })
                                         , targetObjectNode);
            }
            else
            {
                GenerateMemberAssignment(initComponentMethod, parentMember, parentExpression, cvre, targetObjectNode);
            }
        }
        private void GenerateObject(CodeMemberMethod initComponentMethod, CodeExpression parentExpression, CodeDomObjectNode targetObjectNode, MemberNode parentMember)
        {
            string targetName;
            bool   isPublicObject = false;

            if (targetObjectNode.XNameNode == null)
            {
                targetName = GenerateUniqueName(targetObjectNode.Type);
            }
            else
            {
                ValueNode valueNode = targetObjectNode.XNameNode.ItemNodes[0] as ValueNode;
                targetName     = (string)valueNode.Value;
                isPublicObject = true;
            }
            CodeExpression ctor = null;

            if (targetObjectNode.XInitNode != null)
            {
                string tcName = GenerateTypeConverter(initComponentMethod, targetObjectNode.Type);   // TextSyntax

                ctor = GetTypeConverteredValue(targetObjectNode.Type, ((ValueNode)targetObjectNode.XInitNode.ItemNodes[0]).Value, targetObjectNode.Type.UnderlyingType, tcName);
            }
            else if (targetObjectNode.XFactoryMethodNode != null)
            {
                throw new NotImplementedException();
            }
            else if (targetObjectNode.XPosParamsNode != null)
            {
                IList <XamlType>           types       = targetObjectNode.Type.GetPositionalParameters(targetObjectNode.XPosParamsNode.ItemNodes.Count);
                CodeObjectCreateExpression constructor = new CodeObjectCreateExpression(targetObjectNode.Type.UnderlyingType.Name);
                for (int i = 0; i < types.Count; i++)
                {
                    string tcName = GenerateTypeConverter(initComponentMethod, types[i]);

                    constructor.Parameters.Add(GetTypeConverteredValue(types[i], ((ValueNode)targetObjectNode.XPosParamsNode.ItemNodes[i]).Value, types[i].UnderlyingType, tcName));
                }
                ctor = constructor;
            }
            else if (targetObjectNode.XArgumentsNode != null)
            {
                throw new NotImplementedException();
            }
            else
            {
                if (targetObjectNode.Type.IsUnknown)
                {
                    throw new Exception("Unknown type " + targetObjectNode.Type.Name + " found.");
                }
                ctor = new CodeObjectCreateExpression(targetObjectNode.Type.UnderlyingType.Name);
            }

            if (!isPublicObject)
            {
                CodeVariableDeclarationStatement cvds = new CodeVariableDeclarationStatement(targetObjectNode.Type.UnderlyingType.Name, targetName, ctor);
                initComponentMethod.Statements.Add(cvds);
            }
            else
            {
                CodeAssignStatement cas = new CodeAssignStatement(new CodeVariableReferenceExpression(targetName), ctor);
                initComponentMethod.Statements.Add(cas);

                // Needs to be public
                PublicObjects.Add(targetName, targetObjectNode);
            }

            CodeVariableReferenceExpression cvre = new CodeVariableReferenceExpression(targetName);

            bool isUsuable = GetIsUsableDuringInitialization(targetObjectNode.Type);

            if (isUsuable)
            {
                GenerateMemberAssignmentWithProvideValueIfNecessary(initComponentMethod, parentExpression, targetObjectNode, parentMember, cvre);
            }

            AddMembers(initComponentMethod, cvre, targetObjectNode);

            if (!isUsuable)
            {
                GenerateMemberAssignmentWithProvideValueIfNecessary(initComponentMethod, parentExpression, targetObjectNode, parentMember, cvre);
            }
        }
        private void GenerateGetObject(CodeMemberMethod initComponentMethod, CodeExpression parentExpression, CodeDomObjectNode targetObjectNode, MemberNode parentMember)
        {
            if (parentMember.Member.IsAttachable)
            {
                throw new NotImplementedException();
            }
            CodePropertyReferenceExpression cpfe = new CodePropertyReferenceExpression(parentExpression, parentMember.Member.Name);
            Type   type       = parentMember.Member.Type.UnderlyingType;
            string targetName = GenerateUniqueName(type);
            CodeVariableDeclarationStatement cvds = new CodeVariableDeclarationStatement(type.Name, targetName, cpfe);

            initComponentMethod.Statements.Add(cvds);

            CodeVariableReferenceExpression cvre = new CodeVariableReferenceExpression(targetName);

            AddMembers(initComponentMethod, cvre, targetObjectNode);
        }
        //  MyData myDataObject = new MyData(DateTime.Now);
        //  Binding myBinding = new Binding("MyDataProperty");
        //  myBinding.Source = myDataObject;
        //  myText.SetBinding(TextBlock.TextProperty, myBinding);

        private void GenerateBindingObject(CodeMemberMethod initComponentMethod, CodeExpression parentExpression, CodeDomObjectNode targetObjectNode, MemberNode parentMember)
        {
            // Generate new binding name
            string targetName  = GenerateUniqueName(targetObjectNode.Type);
            string elementName = string.Empty;
            string path        = string.Empty;

            // Grab all the attributes of the binding
            NodeCollection <MemberNode> members = targetObjectNode.MemberNodes;

            foreach (MemberNode member in members)
            {
                switch (member.Member.Name)
                {
                case "ElementName":
                    elementName = ExtractItemMemberValue(member.ItemNodes[0]);
                    break;

                case "Path":
                    path = ExtractItemMemberValue(member.ItemNodes[0]);
                    break;
                }
            }

            // Create a constructor for the binding adding the Path, if it exists
            CodeExpression ctor = new CodeObjectCreateExpression(targetObjectNode.Type.UnderlyingType.Name, new CodePrimitiveExpression(path));
            CodeVariableDeclarationStatement cvds = new CodeVariableDeclarationStatement(targetObjectNode.Type.UnderlyingType.Name, targetName, ctor);

            initComponentMethod.Statements.Add(cvds);

            // Set the source property on the binding
            CodeStatement cs = new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression(targetName), "Source"), new CodeVariableReferenceExpression(elementName));

            initComponentMethod.Statements.Add(cs);

            // Set the binding on the target object
            CodeFieldReferenceExpression cfre = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(parentMember.ParentObjectNode.Type.UnderlyingType), parentMember.Member.Name + "Property");

            CodeMethodInvokeExpression cmie = new CodeMethodInvokeExpression(parentExpression, "SetBinding", new CodeExpression[] { cfre, new CodeVariableReferenceExpression(targetName) });

            initComponentMethod.Statements.Add(cmie);
        }
        private void ProcessItemNode(ItemNode itemNode, CodeMemberMethod initComponentMethod,
                                     MemberNode member, CodeExpression targetExpression)
        {
            CodeDomObjectNode objectNode = (CodeDomObjectNode)itemNode;
            XamlType          xamlType   = objectNode.Type;

            if (xamlType == XamlLanguage.Static)
            {
                //TODO: this could be posParams or named params...
                ValueNode valueNode2        = objectNode.XPosParamsNode.ItemNodes[0] as ValueNode;
                string    xamlTypeReference = valueNode2.Value as string;
                string    memberName        = null;
                string    typeName          = null;
                int       period            = xamlTypeReference.IndexOf('.');
                if (period > -1)
                {
                    memberName = xamlTypeReference.Substring(period + 1);
                    typeName   = xamlTypeReference.Substring(0, period);
                }
                Type resolvedType = objectNode.Resolve(typeName);
                //TODO: don't forget to make sure a using happens for the referencedXamlType
                string typeName2 = resolvedType != null ? resolvedType.Name : xamlTypeReference;
                //CodeTypeReference ctr = new CodeTypeReference(typeName2);
                CodeTypeReferenceExpression     ctre = new CodeTypeReferenceExpression(typeName2);
                CodePropertyReferenceExpression cpre =
                    new CodePropertyReferenceExpression(ctre, memberName);

                GenerateMemberAssignment(initComponentMethod,
                                         member, targetExpression, cpre, objectNode);
            }
            else if (xamlType == XamlLanguage.Null)
            {
                CodePrimitiveExpression nullExpression = new CodePrimitiveExpression(null);
                GenerateMemberAssignment(initComponentMethod,
                                         member, targetExpression, nullExpression, objectNode);
            }
            else if (xamlType == XamlLanguage.Type)
            {
                //TODO: this could be posParams or named params...
                ValueNode valueNode2        = objectNode.XPosParamsNode.ItemNodes[0] as ValueNode;
                string    xamlTypeReference = valueNode2.Value as string;
                Type      resolvedType      = objectNode.Resolve(xamlTypeReference);
                //TODO: don't forget to make sure a using happens for the referencedXamlType
                string               typeName = resolvedType != null ? resolvedType.Name : xamlTypeReference;
                CodeTypeReference    ctr      = new CodeTypeReference(typeName);
                CodeTypeOfExpression typeof1  = new CodeTypeOfExpression(ctr);
                GenerateMemberAssignment(initComponentMethod,
                                         member, targetExpression, typeof1, objectNode);
            }
            else if (xamlType == XamlLanguage.Reference)
            {
            }
            else
            {
                // We have something other than a ValueNode.  Must be a StartObject or GetObject
                initComponentMethod.Statements.Add(new CodeCommentStatement("---------------------------"));
                if (objectNode.Type != null)
                {
                    // Handle special case for Bindings
                    if (objectNode.Type.Name == "Binding")
                    {
                        GenerateBindingObject(initComponentMethod, targetExpression, objectNode, member);
                    }
                    else
                    {
                        // StartObject case
                        GenerateObject(initComponentMethod, targetExpression, objectNode, member);
                    }
                }
                else
                {
                    // GetObject
                    GenerateGetObject(initComponentMethod, targetExpression, objectNode, member);
                }
            }
        }
        private void AddMembers(CodeMemberMethod initComponentMethod, CodeExpression targetExpression, CodeDomObjectNode objectNode)
        {
            NodeCollection <MemberNode> members = objectNode.MemberNodes;

            foreach (MemberNode member in members)
            {
                if (member.Member.Name == "Implementation")
                {
                    GenerateImplementation(initComponentMethod, member, targetExpression);
                }
                else
                {
                    GenerateMemberValue(initComponentMethod, member, targetExpression);
                }
            }
        }