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); } }
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); }
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); }
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); } } }