Ejemplo n.º 1
0
        public void ImplementBamlInitializer(Builder builder)
        {
            this.LogInfo($"Checking for xaml/baml resources without initializers.");

            var xamlList = builder.ResourceNames?.Where(x => x.EndsWith(".baml")).Select(x => x.Replace(".baml", ".xaml")).ToArray();

            if (xamlList == null || xamlList.Length == 0 || !builder.TypeExists("System.Windows.Application"))
            {
                return;
            }

            var application        = new __Application(builder);
            var extensions         = new __Extensions(builder);
            var resourceDictionary = new __ResourceDictionary(builder);
            var collection         = new __ICollection_1(builder);

            this.LogInfo($"Implementing XAML initializer for baml resources.");

            // First we have to find every InitializeComponent method so that we can remove bamls that are already initialized.
            var allInitializeComponentMethods = builder.FindMethodsByName(SearchContext.Module, "InitializeComponent", 0).Where(x => !x.IsAbstract);
            var ldStrs = new ConcurrentBag <string>();

            Parallel.ForEach(allInitializeComponentMethods, methods =>
            {
                foreach (var str in methods.GetLoadStrings())
                {
                    ldStrs.Add(str);
                }
            });

            var xamlWithInitializers         = ldStrs.Select(x => x.Substring(x.IndexOf("component/") + "component/".Length)).ToArray();
            var xamlThatRequiredInitializers = xamlList.Where(x => !xamlWithInitializers.Contains(x));

            var resourceDictionaryMergerClass = builder.CreateType("XamlGeneratedNamespace", TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Sealed, "<>_generated_resourceDictionary_Loader");

            resourceDictionaryMergerClass.CustomAttributes.Add(builder.GetType("Cauldron.Activator.ComponentAttribute"), resourceDictionary.Type.Fullname);
            resourceDictionaryMergerClass.CustomAttributes.AddEditorBrowsableAttribute(EditorBrowsableState.Never);
            resourceDictionaryMergerClass.CustomAttributes.AddCompilerGeneratedAttribute();

            //var method = resourceDictionaryMergerClass.CreateMethod(Modifiers.Private, "AddToDictionary", typeof(string));
            resourceDictionaryMergerClass.CreateConstructor().NewCode().Context(x =>
            {
                x.Load(x.This).Call(builder.GetType(typeof(object)).Import().ParameterlessContructor.Import());

                var resourceDick = x.CreateVariable(collection.Type.MakeGeneric(resourceDictionary.Type));
                x.Call(
                    x.NewCode().Call(x.NewCode().Call(application.Current) /* Instance */, application.Resources) /* Instance */, resourceDictionary.MergedDictionaries)
                .StoreLocal(resourceDick);

                var resourceDictionaryInstance = x.CreateVariable(resourceDictionary.Type);

                foreach (var item in xamlThatRequiredInitializers)
                {
                    x.NewObj(resourceDictionary.Ctor).StoreLocal(resourceDictionaryInstance);
                    x.Call(resourceDick, collection.Add.MakeGeneric(resourceDictionary.Type), resourceDictionaryInstance);
                    x.Call(resourceDictionaryInstance, resourceDictionary.SetSource,
                           x.NewCode().Call(extensions.RelativeUri, $"/{Path.GetFileNameWithoutExtension(this.Builder.Name)};component/{item}")); // TODO -Need modification for UWP)
                }
            })
            .Return()
            .Replace();

            resourceDictionaryMergerClass.ParameterlessContructor.CustomAttributes.AddEditorBrowsableAttribute(EditorBrowsableState.Never);
            resourceDictionaryMergerClass.ParameterlessContructor.CustomAttributes.Add(builder.GetType("Cauldron.Activator.ComponentConstructorAttribute"));
        }
Ejemplo n.º 2
0
        public void ImplementBamlInitializer(Builder builder)
        {
            var xamlList = builder.ResourceNames?.Where(x => x.EndsWith(".baml")).Select(x => x.Replace(".baml", ".xaml")).ToArray();

            if (!this.IsActivatorReferenced || !this.IsXAML || xamlList == null || xamlList.Length == 0 || !builder.TypeExists("System.Windows.Application"))
            {
                return;
            }

            using (new StopwatchLog(this, "xaml/baml resources"))
            {
                this.Log($"Checking for xaml/baml resources without initializers.");

                var application        = new __Application();
                var extensions         = new __Extensions();
                var resourceDictionary = new __ResourceDictionary();
                var collection         = new __ICollection_1();
                var uri = new __Uri();

                this.Log($"Implementing XAML initializer for baml resources.");

                // First we have to find every InitializeComponent method so that we can remove bamls that are already initialized.
                var allInitializeComponentMethods = builder.FindMethodsByName(SearchContext.Module, "InitializeComponent", 0).Where(x => !x.IsAbstract);
                var ldStrs = new ConcurrentBag <string>();

                Parallel.ForEach(allInitializeComponentMethods, methods =>
                {
                    foreach (var str in methods.GetLoadStrings())
                    {
                        ldStrs.Add(str);
                    }
                });

                var xamlWithInitializers         = ldStrs.Select(x => x.Substring(x.IndexOf("component/") + "component/".Length)).ToArray();
                var xamlThatRequiredInitializers = xamlList
                                                   .Where(x => !xamlWithInitializers.Contains(x))
                                                   .Select(x =>
                {
                    var index = uint.MaxValue;
                    if (x.IndexOf('-') > 0)
                    {
                        var dashPosition  = x.LastIndexOf('-') + 1;
                        var pointPosition = x.IndexOf('.', dashPosition);

                        if (uint.TryParse(x.Substring(dashPosition, pointPosition > dashPosition ? pointPosition - dashPosition : x.Length - dashPosition), out uint result))
                        {
                            index = result;
                        }
                    }

                    return(new { Index = index, Item = x });
                })
                                                   .OrderBy(x => x.Index)
                                                   .ThenBy(x => x.Item)
                                                   .ToArray();

                var resourceDictionaryMergerClass = builder.CreateType("XamlGeneratedNamespace", TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Sealed, "<>_generated_resourceDictionary_Loader");
                resourceDictionaryMergerClass.CustomAttributes.Add(__ComponentAttribute.Type, __ResourceDictionary.Type.Fullname);
                resourceDictionaryMergerClass.CustomAttributes.AddEditorBrowsableAttribute(EditorBrowsableState.Never);
                resourceDictionaryMergerClass.CustomAttributes.AddCompilerGeneratedAttribute();

                //var method = resourceDictionaryMergerClass.CreateMethod(Modifiers.Private, "AddToDictionary", typeof(string));
                resourceDictionaryMergerClass.CreateConstructor().NewCode().Context(x =>
                {
                    var resourceDick = x.CreateVariable(__ICollection_1.Type.MakeGeneric(__ResourceDictionary.Type));
                    x.Call(
                        x.NewCode().Call(x.NewCode().Call(application.Current) /* Instance */, application.Resources) /* Instance */, resourceDictionary.MergedDictionaries)
                    .StoreLocal(resourceDick);

                    var resourceDictionaryInstance = x.CreateVariable(__ResourceDictionary.Type);

                    foreach (var item in xamlThatRequiredInitializers)
                    {
                        this.Log($"- Adding XAML '{item.Item}' with index '{item.Index}' to the Application's MergeDictionary");
                        x.NewObj(resourceDictionary.Ctor).StoreLocal(resourceDictionaryInstance);
                        x.Call(resourceDictionaryInstance, resourceDictionary.SetSource,
                               x.NewCode().NewObj(uri.Ctor, $"pack://application:,,,/{Path.GetFileNameWithoutExtension(this.Builder.Name)};component/{item.Item}")); // TODO -Need modification for UWP)
                        x.Call(resourceDick, collection.Add.MakeGeneric(__ResourceDictionary.Type), resourceDictionaryInstance);
                    }
                })
                .Return()
                .Replace();

                // Let us look for ResourceDictionaries without a InitializeComponent in their ctor
                // TODO

                resourceDictionaryMergerClass.ParameterlessContructor.CustomAttributes.AddEditorBrowsableAttribute(EditorBrowsableState.Never);
                resourceDictionaryMergerClass.ParameterlessContructor.CustomAttributes.Add(__ComponentConstructorAttribute.Type);
            }
        }
Ejemplo n.º 3
0
    public static void ImplementBamlInit(Builder builder)
    {
        if (builder.ResourceNames == null)
        {
            return;
        }

        var xamlList = builder.ResourceNames.Where(x => x.EndsWith(".baml")).Select(x => x.Replace(".baml", ".xaml")).ToArray();

        builder.Log(LogTypes.Info, "Checking for xaml/baml resources without initializers.");

        var resourceDictionary = new __ResourceDictionary();

        builder.Log(LogTypes.Info, "Implementing XAML initializer for baml resources.");

        // First we have to find every InitializeComponent method so that we can remove bamls that are already initialized.
        var allInitializeComponentMethods = builder.FindMethodsByName(SearchContext.Module, "InitializeComponent", 0).Where(x => !x.IsAbstract);
        var ldStrs = new ConcurrentBag <string>();

        Parallel.ForEach(allInitializeComponentMethods, methods =>
        {
            foreach (var str in methods.GetLoadStrings())
            {
                ldStrs.Add(str);
            }
        });

        var xamlWithInitializers         = ldStrs.Select(x => x.Substring(x.IndexOf("component/") + "component/".Length)).ToArray();
        var xamlThatRequiredInitializers = xamlList
                                           .Where(x => !xamlWithInitializers.Contains(x))
                                           .Select(x =>
        {
            var index = uint.MaxValue;
            if (x.IndexOf('-') > 0)
            {
                var dashPosition  = x.LastIndexOf('-') + 1;
                var pointPosition = x.IndexOf('.', dashPosition);

                if (uint.TryParse(x.Substring(dashPosition, pointPosition > dashPosition ? pointPosition - dashPosition : x.Length - dashPosition), out uint result))
                {
                    index = result;
                }
            }

            return(new { Index = index, Item = x });
        })
                                           .OrderBy(x => x.Index)
                                           .ThenBy(x => x.Item)
                                           .ToArray();

        var resourceDictionaryMergerClass = builder.CreateType(
            "XamlGeneratedNamespace",
            TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Sealed,
            "<>_generated_resourceDictionary_Loader",
            BuilderTypes.ResourceDictionary);

        resourceDictionaryMergerClass.CustomAttributes.Add(builder.GetType("Cauldron.Activator.ComponentAttribute"), __ResourceDictionary.Type.Fullname);
        resourceDictionaryMergerClass.CustomAttributes.AddEditorBrowsableAttribute(EditorBrowsableState.Never);
        resourceDictionaryMergerClass.CustomAttributes.AddCompilerGeneratedAttribute();

        //var method = resourceDictionaryMergerClass.CreateMethod(Modifiers.Private, "AddToDictionary", typeof(string));
        resourceDictionaryMergerClass.CreateConstructor().NewCoder().Context(context =>
        {
            if (xamlThatRequiredInitializers.Length > 0)
            {
                var resourceDick = context.AssociatedMethod.GetOrCreateVariable(BuilderTypes.ICollection1.BuilderType.MakeGeneric(__ResourceDictionary.Type));
                context
                .SetValue(resourceDick, x =>
                          x.Call(BuilderTypes.Application.GetMethod_get_Current())
                          .Call(BuilderTypes.Application.GetMethod_get_Resources())
                          .Call(resourceDictionary.MergedDictionaries));

                var resourceDictionaryInstance = context.AssociatedMethod.GetOrCreateVariable(__ResourceDictionary.Type);

                foreach (var item in xamlThatRequiredInitializers)
                {
                    builder.Log(LogTypes.Info, $"- Adding XAML '{item.Item}' with index '{item.Index}' to the Application's MergeDictionary");
                    context.SetValue(resourceDictionaryInstance, x => x.NewObj(resourceDictionary.Ctor));
                    context.Load(resourceDictionaryInstance)
                    .Call(resourceDictionary.SetSource,
                          x => x.NewObj(BuilderTypes.Uri.GetMethod_ctor(), $"pack://application:,,,/{Path.GetFileNameWithoutExtension(builder.Name)};component/{item.Item}"));
                    context.Load(resourceDick)
                    .Call(BuilderTypes.ICollection1.GetMethod_Add().MakeGeneric(__ResourceDictionary.Type), resourceDictionaryInstance);
                }
            }

            return(context);
        })
        .Return()
        .Replace();

        // Let us look for ResourceDictionaries without a InitializeComponent in their ctor and it
        foreach (var method in allInitializeComponentMethods)
        {
            foreach (var ctor in method.DeclaringType.GetRelevantConstructors().Where(x => x.Name == ".ctor"))
            {
                if (!ctor.HasMethodCall(method))
                {
                    ctor.NewCoder().Call(method).End.Insert(InsertionPosition.Beginning);
                }
            }
        }

        resourceDictionaryMergerClass.ParameterlessContructor.CustomAttributes.AddEditorBrowsableAttribute(EditorBrowsableState.Never);
        resourceDictionaryMergerClass.ParameterlessContructor.CustomAttributes.Add(BuilderTypes.ComponentConstructorAttribute.BuilderType);
    }