<commit_before>using System;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using DotVVM.Framework.Binding;
using DotVVM.Framework.Compilation.ControlTree.Resolved;
using DotVVM.Framework.Configuration;
using DotVVM.Framework.Controls;
using DotVVM.Framework.Runtime;
using DotVVM.Framework.Utils;

namespace DotVVM.Framework.Compilation.ControlTree
{
    public class DefaultControlResolver : ControlResolverBase
    {

        private readonly IControlBuilderFactory controlBuilderFactory;

        private static object locker = new object();
        private static bool isInitialized = false;


        public DefaultControlResolver(DotvvmMarkupConfiguration configuration, IControlBuilderFactory controlBuilderFactory) : base(configuration)
        {
            this.controlBuilderFactory = controlBuilderFactory;

            if (!isInitialized)
            {
                lock (locker)
                {
                    if (!isInitialized)
                    {
                        InvokeStaticConstructorsOnAllControls();
                        isInitialized = true;
                    }
                }
            }
        }

        /// <summary>
        /// Invokes the static constructors on all controls to register all <see cref="DotvvmProperty"/>.
        /// </summary>
        private static void InvokeStaticConstructorsOnAllControls()
        {
            // PERF: too many allocations - type.GetCustomAttribute<T> does ~220k allocs -> 4MB, get all types allocates additional 1.5MB
            var dotvvmAssembly = typeof(DotvvmControl).GetTypeInfo().Assembly.GetName().Name;
            var allTypes = ReflectionUtils.GetAllAssemblies()
                .Where(a => a.GetReferencedAssemblies().Any(r => r.Name == dotvvmAssembly))
                .Concat(new[] { typeof(DotvvmControl).GetTypeInfo().Assembly })
                .SelectMany(a => a.GetTypes()).Where(t => t.GetTypeInfo().IsClass).ToList();
            foreach (var type in allTypes)
            {
                if (type.GetTypeInfo().GetCustomAttribute<ContainsDotvvmPropertiesAttribute>(true) != null)
                {
                    var tt = type;
                    do
                    {
                        RuntimeHelpers.RunClassConstructor(tt.TypeHandle);
                        tt = tt.GetTypeInfo().BaseType;<commit_msg>DefaultControlResolver - used GetLoadableTypes instead of GetTypes<commit_after>using System;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using DotVVM.Framework.Binding;
using DotVVM.Framework.Compilation.ControlTree.Resolved;
using DotVVM.Framework.Configuration;
using DotVVM.Framework.Controls;
using DotVVM.Framework.Runtime;
using DotVVM.Framework.Utils;

namespace DotVVM.Framework.Compilation.ControlTree
{
    public class DefaultControlResolver : ControlResolverBase
    {

        private readonly IControlBuilderFactory controlBuilderFactory;

        private static object locker = new object();
        private static bool isInitialized = false;


        public DefaultControlResolver(DotvvmMarkupConfiguration configuration, IControlBuilderFactory controlBuilderFactory) : base(configuration)
        {
            this.controlBuilderFactory = controlBuilderFactory;

            if (!isInitialized)
            {
                lock (locker)
                {
                    if (!isInitialized)
                    {
                        InvokeStaticConstructorsOnAllControls();
                        isInitialized = true;
                    }
                }
            }
        }

        /// <summary>
        /// Invokes the static constructors on all controls to register all <see cref="DotvvmProperty"/>.
        /// </summary>
        private static void InvokeStaticConstructorsOnAllControls()
        {
            // PERF: too many allocations - type.GetCustomAttribute<T> does ~220k allocs -> 4MB, get all types allocates additional 1.5MB
            var dotvvmAssembly = typeof(DotvvmControl).GetTypeInfo().Assembly.GetName().Name;
            var allTypes = ReflectionUtils.GetAllAssemblies()
                .Where(a => a.GetReferencedAssemblies().Any(r => r.Name == dotvvmAssembly))
                .Concat(new[] { typeof(DotvvmControl).GetTypeInfo().Assembly })
                .SelectMany(a => a.GetLoadableTypes()).Where(t => t.GetTypeInfo().IsClass).ToList();
            foreach (var type in allTypes)
            {
                if (type.GetTypeInfo().GetCustomAttribute<ContainsDotvvmPropertiesAttribute>(true) != null)
                {
                    var tt = type;
                    do
                    {
                        RuntimeHelpers.RunClassConstructor(tt.TypeHandle);
                        tt = tt.GetTypeInfo().BaseType;
{'fraction_non_alphanumeric': 0.0855958549222798, 'fraction_numerical': 0.002487046632124352, 'mean_word_length': 2.089628681177977, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6079984', 'n_tokens_mistral': 1201, 'n_tokens_neox': 1145, 'n_words': 246}