/// <summary> /// Generates the code. /// </summary> /// <param name="inputFileName">Name of the input file.</param> /// <param name="inputFileContent">Content of the input file.</param> /// <param name="renderMode">The render mode.</param> /// <param name="desiredNamespace">The desired namespace.</param> /// <returns></returns> public string GenerateCode(string inputFileName, string inputFileContent, RenderMode renderMode, string desiredNamespace) { inputFileContent = RemoveClass(inputFileContent); var parserContext = new ParserContext { BaseUri = new Uri(inputFileName, UriKind.Absolute) }; object source = null; try { //source = XamlReader.Parse(inputFileContent); //, parserContext); using (Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(inputFileContent))) { source = XamlReader.Load(stream, parserContext); } } catch (Exception ex) { Console.WriteLine(ex); throw; } if (source == null) { return "Source is empty. XAML file is not valid."; } Console.WriteLine(); Console.WriteLine("Generating " + inputFileName); string resultCode = string.Empty; string className = Path.GetFileNameWithoutExtension(inputFileName); CodeNamespace ns = new CodeNamespace(desiredNamespace); ns.Imports.Add(new CodeNamespaceImport("System")); ns.Imports.Add(new CodeNamespaceImport("System.CodeDom.Compiler")); ns.Imports.Add(new CodeNamespaceImport("System.Collections.ObjectModel")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Data")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Controls")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Controls.Primitives")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Input")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Media")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Media.Animation")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Media.Imaging")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Shapes")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Renderers")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Themes")); /* switch (renderMode) { case RenderMode.SunBurn: ns.Imports.Add(new CodeNamespaceImport("SynapseGaming.SunBurn.Framework.Primitives")); break; case RenderMode.MonoGame: ns.Imports.Add(new CodeNamespaceImport("Microsoft.Xna.Framework")); ns.Imports.Add(new CodeNamespaceImport("Microsoft.Xna.Framework.Graphics")); break; default: break; } */ CodeTypeDeclaration classType = new CodeTypeDeclaration(className); GeneratedCodeAttribute generatedCodeAttribute = new GeneratedCodeAttribute("Empty Keys UI Generator", Assembly.GetExecutingAssembly().GetName().Version.ToString()); CodeAttributeDeclaration codeAttrDecl = new CodeAttributeDeclaration(generatedCodeAttribute.GetType().Name, new CodeAttributeArgument( new CodePrimitiveExpression(generatedCodeAttribute.Tool)), new CodeAttributeArgument( new CodePrimitiveExpression(generatedCodeAttribute.Version))); classType.CustomAttributes.Add(codeAttrDecl); ns.Comments.Add(new CodeCommentStatement("-----------------------------------------------------------", false)); ns.Comments.Add(new CodeCommentStatement(" ", false)); ns.Comments.Add(new CodeCommentStatement(" This file was generated, please do not modify.", false)); ns.Comments.Add(new CodeCommentStatement(" ", false)); ns.Comments.Add(new CodeCommentStatement("-----------------------------------------------------------", false)); CodeMemberMethod initMethod = null; if (source is UIRoot) { initMethod = CreateUIRootClass(ns, classType, renderMode); generator.ProcessGenerators(source, classType, initMethod, true); } else if (source is UserControl) { initMethod = CreateUserControlClass(ns, classType); generator.ProcessGenerators(source, classType, initMethod, true); } else if (source is ResourceDictionary) { initMethod = CreateDictionaryClass(ns, classType); ResourceDictionary dictionary = source as ResourceDictionary; if (dictionary != null) { ResourceDictionaryGenerator resourcesGenerator = new ResourceDictionaryGenerator(); resourcesGenerator.Generate(dictionary, classType, initMethod, new CodeThisReferenceExpression()); } } else { string errorText = "#error This type is not supported - " + source.GetType(); Console.WriteLine(errorText); return errorText; } ImageAssets.Instance.GenerateManagerCode(initMethod); ImageAssets.Instance.ClearAssets(); FontGenerator.Instance.GenerateManagerCode(initMethod); using (CodeDomProvider provider = new Microsoft.CSharp.CSharpCodeProvider()) { string mappedFileName = memoryMappedFileName + className; using (MemoryMappedFile mappedFile = MemoryMappedFile.CreateNew(mappedFileName, nemoryMappedFileCapacity)) { MemoryMappedViewStream stream = mappedFile.CreateViewStream(); using (StreamWriter sw = new StreamWriter(stream)) { provider.GenerateCodeFromNamespace(ns, sw, new CodeGeneratorOptions()); } stream = mappedFile.CreateViewStream(); TextReader tr = new StreamReader(stream); resultCode = tr.ReadToEnd(); resultCode = resultCode.Trim(new char()); tr.Close(); } } return resultCode; }
/// <summary> /// Processes the generators. /// </summary> /// <param name="source">source</param> /// <param name="classType">Type of the class.</param> /// <param name="method">The initialize method.</param> /// <param name="generateFields">if set to <c>true</c> [generate fields].</param> /// <returns></returns> public CodeExpression ProcessGenerators(object source, CodeTypeDeclaration classType, CodeMemberMethod method, bool generateFields) { if (source == null) { return null; } IGeneratorType generator; Type elementType = source.GetType(); bool customUserControl = false; if (elementType.BaseType == typeof(UserControl)) { // we have to retype any custom user control to fake generator so we can generate code for it customUserControl = true; elementType = typeof(CustomUserControlGeneratorType); } if (Generators.TryGetValue(elementType, out generator)) { DependencyObject xamlSource = source as DependencyObject; if (xamlSource != null) { CodeExpression parent = generator.Generate(xamlSource, classType, method, generateFields); CodeComHelper.GenerateAttachedProperties(method, parent, xamlSource); Type oldDataType = BindingGenerator.Instance.ActiveDataType; Type newType = xamlSource.GetValue(GeneratedBindings.DataTypeProperty) as Type; if (newType != null) { BindingGenerator.Instance.ActiveDataType = newType; } FrameworkElement elem = source as FrameworkElement; if (elem != null) { CodeComHelper.GenerateBindings(method, parent, elem, elem.Name); CodeComHelper.GenerateResourceReferences(method, parent, elem); if (!customUserControl && (elem.Resources.Count != 0 || elem.Resources.MergedDictionaries.Count != 0)) { ResourceDictionaryGenerator resourcesGenerator = new ResourceDictionaryGenerator(); CodeMemberMethod resourcesMethod = new CodeMemberMethod(); resourcesMethod.Attributes = MemberAttributes.Static | MemberAttributes.Private; resourcesMethod.Name = "InitializeElement" + elem.Name + "Resources"; resourcesMethod.Parameters.Add(new CodeParameterDeclarationExpression("UIElement", "elem")); classType.Members.Add(resourcesMethod); resourcesGenerator.Generate(elem.Resources, classType, resourcesMethod, new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("elem"), "Resources")); method.Statements.Add(new CodeMethodInvokeExpression(null,resourcesMethod.Name, parent)); } } IEnumerable children = generator.GetChildren(xamlSource); if (children != null) { foreach (DependencyObject child in children) { if (child == null) { continue; } int index = method.Statements.Count; CodeExpression childRef = ProcessGenerators(child, classType, method, generateFields); if (childRef != null) { generator.AddChild(parent, childRef, method, index + 2); // +1 for creating instance +1 for comment } } } BindingGenerator.Instance.ActiveDataType = oldDataType; return parent; } } string errorText = "Unknown type : " + source.GetType(); Console.WriteLine(errorText); CodeSnippetStatement error = new CodeSnippetStatement("#error " + errorText); method.Statements.Add(error); return null; }
/// <summary> /// Generates the code. /// </summary> /// <param name="inputFileName">Name of the input file.</param> /// <param name="inputFileContent">Content of the input file.</param> /// <param name="renderMode">The render mode.</param> /// <param name="desiredNamespace">The desired namespace.</param> /// <param name="header">The header.</param> /// <returns></returns> public string GenerateCode(string inputFileName, string inputFileContent, RenderMode renderMode, string desiredNamespace, string header) { inputFileContent = RemoveClassAndAddAssembly(inputFileContent); var parserContext = new ParserContext { BaseUri = new Uri(inputFileName, UriKind.Absolute) }; object source = null; try { using (Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(inputFileContent))) { source = XamlReader.Load(stream, parserContext); } } catch (Exception ex) { Console.WriteLine(ex); throw; } if (source == null) { return("Source is empty. XAML file is not valid."); } Console.WriteLine(); Console.WriteLine("Generating " + inputFileName); ElementGeneratorType.NameUniqueId = 0; string className = Path.GetFileNameWithoutExtension(inputFileName); CodeNamespace ns = new CodeNamespace(desiredNamespace); ns.Imports.Add(new CodeNamespaceImport("System")); ns.Imports.Add(new CodeNamespaceImport("System.CodeDom.Compiler")); ns.Imports.Add(new CodeNamespaceImport("System.Collections.ObjectModel")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Charts")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Data")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Controls")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Controls.Primitives")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Input")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Interactions.Core")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Interactivity")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Media")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Media.Effects")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Media.Animation")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Media.Imaging")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Shapes")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Renderers")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Themes")); CodeTypeDeclaration classType = new CodeTypeDeclaration(className); GeneratedCodeAttribute generatedCodeAttribute = new GeneratedCodeAttribute("Empty Keys UI Generator", Assembly.GetExecutingAssembly().GetName().Version.ToString()); CodeAttributeDeclaration codeAttrDecl = new CodeAttributeDeclaration(generatedCodeAttribute.GetType().Name, new CodeAttributeArgument( new CodePrimitiveExpression(generatedCodeAttribute.Tool)), new CodeAttributeArgument( new CodePrimitiveExpression(generatedCodeAttribute.Version))); classType.CustomAttributes.Add(codeAttrDecl); if (string.IsNullOrEmpty(header)) { ns.Comments.Add(new CodeCommentStatement("-----------------------------------------------------------", false)); ns.Comments.Add(new CodeCommentStatement(" ", false)); ns.Comments.Add(new CodeCommentStatement(" This file was generated, please do not modify.", false)); ns.Comments.Add(new CodeCommentStatement(" ", false)); ns.Comments.Add(new CodeCommentStatement("-----------------------------------------------------------", false)); } else { ns.Comments.Add(new CodeCommentStatement(header, false)); } CodeMemberMethod initMethod = null; if (source is UIRoot) { initMethod = CreateUIRootClass(ns, classType, renderMode); generator.ProcessGenerators(source, classType, initMethod, true); } else if (source is UserControl) { initMethod = CreateUserControlClass(ns, classType); generator.ProcessGenerators(source, classType, initMethod, true); } else if (source is ResourceDictionary) { initMethod = CreateDictionaryClass(ns, classType); ResourceDictionary dictionary = source as ResourceDictionary; if (dictionary != null) { ResourceDictionaryGenerator resourcesGenerator = new ResourceDictionaryGenerator(); resourcesGenerator.Generate(dictionary, classType, initMethod, new CodeThisReferenceExpression()); } } else { string errorText = "#error This type is not supported - " + source.GetType(); Console.WriteLine(errorText); return(errorText); } ImageAssets.Instance.GenerateManagerCode(initMethod); ImageAssets.Instance.ClearAssets(); EffectAssets.Instance.GenerateManagerCode(initMethod); EffectAssets.Instance.ClearAssets(); FontGenerator.Instance.GenerateManagerCode(initMethod); if (BindingGenerator.Instance.IsEnabled) { BindingGenerator.Instance.GenerateRegistrationCode(initMethod); } string resultCode = string.Empty; using (CodeDomProvider provider = new Microsoft.CSharp.CSharpCodeProvider()) { string mappedFileName = memoryMappedFileName + className; using (MemoryMappedFile mappedFile = MemoryMappedFile.CreateNew(mappedFileName, nemoryMappedFileCapacity)) { MemoryMappedViewStream stream = mappedFile.CreateViewStream(); using (StreamWriter sw = new StreamWriter(stream)) { provider.GenerateCodeFromNamespace(ns, sw, new CodeGeneratorOptions()); } stream = mappedFile.CreateViewStream(); TextReader tr = new StreamReader(stream); resultCode = tr.ReadToEnd(); resultCode = resultCode.Trim(new char()); tr.Close(); } } return(resultCode); }
/// <summary> /// Processes the generators. /// </summary> /// <param name="source">source</param> /// <param name="classType">Type of the class.</param> /// <param name="method">The initialize method.</param> /// <param name="generateFields">if set to <c>true</c> [generate fields].</param> /// <returns></returns> public CodeExpression ProcessGenerators(object source, CodeTypeDeclaration classType, CodeMemberMethod method, bool generateFields) { if (source == null) { return(null); } IGeneratorType generator; Type elementType = source.GetType(); bool customUserControl = false; if (elementType.BaseType == typeof(UserControl)) { // we have to retype any custom user control to fake generator so we can generate code for it customUserControl = true; elementType = typeof(CustomUserControlGeneratorType); } if (Generators.TryGetValue(elementType, out generator)) { DependencyObject xamlSource = source as DependencyObject; if (xamlSource != null) { CodeExpression parent = generator.Generate(xamlSource, classType, method, generateFields); CodeComHelper.GenerateAttachedProperties(method, parent, xamlSource); Type oldDataType = BindingGenerator.Instance.ActiveDataType; Type newType = xamlSource.GetValue(GeneratedBindings.DataTypeProperty) as Type; if (newType != null) { BindingGenerator.Instance.ActiveDataType = newType; } FrameworkElement elem = source as FrameworkElement; if (elem != null) { CodeComHelper.GenerateBindings(method, parent, elem, elem.Name); CodeComHelper.GenerateResourceReferences(method, parent, elem); if (!customUserControl && (elem.Resources.Count != 0 || elem.Resources.MergedDictionaries.Count != 0)) { ResourceDictionaryGenerator resourcesGenerator = new ResourceDictionaryGenerator(); CodeMemberMethod resourcesMethod = new CodeMemberMethod(); resourcesMethod.Attributes = MemberAttributes.Static | MemberAttributes.Private; resourcesMethod.Name = "InitializeElement" + elem.Name + "Resources"; resourcesMethod.Parameters.Add(new CodeParameterDeclarationExpression("UIElement", "elem")); classType.Members.Add(resourcesMethod); resourcesGenerator.Generate(elem.Resources, classType, resourcesMethod, new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("elem"), "Resources")); method.Statements.Add(new CodeMethodInvokeExpression(null, resourcesMethod.Name, parent)); } } IEnumerable children = generator.GetChildren(xamlSource); if (children != null) { foreach (DependencyObject child in children) { if (child == null) { continue; } int index = method.Statements.Count; CodeExpression childRef = ProcessGenerators(child, classType, method, generateFields); if (childRef != null) { generator.AddChild(parent, childRef, method, index + 2); // +1 for creating instance +1 for comment } } } BindingGenerator.Instance.ActiveDataType = oldDataType; return(parent); } } string errorText = "Unknown type : " + source.GetType(); Console.WriteLine(errorText); CodeSnippetStatement error = new CodeSnippetStatement("#error " + errorText); method.Statements.Add(error); return(null); }
/// <summary> /// Generates the code. /// </summary> /// <param name="inputFileName">Name of the input file.</param> /// <param name="inputFileContent">Content of the input file.</param> /// <param name="renderMode">The render mode.</param> /// <returns></returns> public string GenerateCode(string inputFileName, string inputFileContent, RenderMode renderMode) { inputFileContent = RemoveClass(inputFileContent); object source = null; try { source = XamlReader.Parse(inputFileContent); } catch (Exception ex) { Console.WriteLine(ex); throw; } if (source == null) { return("Source is empty. XAML file is not valid."); } Console.WriteLine(); Console.WriteLine("Generating " + inputFileName); string resultCode = string.Empty; string className = Path.GetFileNameWithoutExtension(inputFileName); CodeNamespace ns = new CodeNamespace("EmptyKeys.UserInterface.Generated"); ns.Imports.Add(new CodeNamespaceImport("System")); ns.Imports.Add(new CodeNamespaceImport("System.CodeDom.Compiler")); ns.Imports.Add(new CodeNamespaceImport("System.Collections.ObjectModel")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Data")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Controls")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Controls.Primitives")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Input")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Media")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Media.Animation")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Media.Imaging")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Shapes")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Renderers")); ns.Imports.Add(new CodeNamespaceImport("EmptyKeys.UserInterface.Themes")); /* * switch (renderMode) * { * case RenderMode.SunBurn: * ns.Imports.Add(new CodeNamespaceImport("SynapseGaming.SunBurn.Framework.Primitives")); * break; * case RenderMode.MonoGame: * ns.Imports.Add(new CodeNamespaceImport("Microsoft.Xna.Framework")); * ns.Imports.Add(new CodeNamespaceImport("Microsoft.Xna.Framework.Graphics")); * break; * default: * break; * } */ CodeTypeDeclaration classType = new CodeTypeDeclaration(className); GeneratedCodeAttribute generatedCodeAttribute = new GeneratedCodeAttribute("Empty Keys UI Generator", Assembly.GetExecutingAssembly().GetName().Version.ToString()); CodeAttributeDeclaration codeAttrDecl = new CodeAttributeDeclaration(generatedCodeAttribute.GetType().Name, new CodeAttributeArgument( new CodePrimitiveExpression(generatedCodeAttribute.Tool)), new CodeAttributeArgument( new CodePrimitiveExpression(generatedCodeAttribute.Version))); classType.CustomAttributes.Add(codeAttrDecl); ns.Comments.Add(new CodeCommentStatement("-----------------------------------------------------------", false)); ns.Comments.Add(new CodeCommentStatement(" ", false)); ns.Comments.Add(new CodeCommentStatement(" This file was generated, please do not modify.", false)); ns.Comments.Add(new CodeCommentStatement(" ", false)); ns.Comments.Add(new CodeCommentStatement("-----------------------------------------------------------", false)); CodeMemberMethod initMethod = null; if (source is UIRoot) { initMethod = CreateUIRootClass(ns, classType, renderMode); generator.ProcessGenerators(source, classType, initMethod, true); } else if (source is UserControl) { initMethod = CreateUserControlClass(ns, classType); generator.ProcessGenerators(source, classType, initMethod, true); } else if (source is ResourceDictionary) { initMethod = CreateDictionaryClass(ns, classType); ResourceDictionary dictionary = source as ResourceDictionary; if (dictionary != null) { ResourceDictionaryGenerator resourcesGenerator = new ResourceDictionaryGenerator(); resourcesGenerator.Generate(dictionary, classType, initMethod, new CodeThisReferenceExpression()); } } else { string errorText = "#error This type is not supported - " + source.GetType(); Console.WriteLine(errorText); return(errorText); } using (CodeDomProvider provider = new Microsoft.CSharp.CSharpCodeProvider()) { string mappedFileName = memoryMappedFileName + className; using (MemoryMappedFile mappedFile = MemoryMappedFile.CreateNew(mappedFileName, nemoryMappedFileCapacity)) { MemoryMappedViewStream stream = mappedFile.CreateViewStream(); using (StreamWriter sw = new StreamWriter(stream)) { provider.GenerateCodeFromNamespace(ns, sw, new CodeGeneratorOptions()); } stream = mappedFile.CreateViewStream(); TextReader tr = new StreamReader(stream); resultCode = tr.ReadToEnd(); resultCode = resultCode.Trim(new char()); tr.Close(); } } return(resultCode); }