示例#1
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);
            }
        }
示例#2
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"));
        }