示例#1
0
    public static void AddConfig(AbstractConfig config)
    {
        config.Init();
        Type type = config.GetType();

        Datas.Add(type, config);
        if (type.BaseType != typeof(AbstractConfig))
        {
            type = type.BaseType;
            Datas.Add(type, config);
        }
    }
示例#2
0
        public static TKernel Configure <TKernel>(this AbstractConfig cfg)
            where TKernel : IKernel
        {
            var t_kernel = typeof(TKernel);

            // validate the kernel type to satisfy the criteria
            // more details on this in the spec - here we provide no comments
            // note 1. all runtimes rely on these assumptions!!! => if you change something here, verify all runtimes!!!
            // note 2. annotations and hints are checked separately by every runtime

            typeof(IKernel).IsAssignableFrom(t_kernel).AssertTrue();
            // this is ugly, tho it's the lesser evil (also see comments in Kernel.cs)
            Apis.Ifaces.ForEach(i_api => i_api.IsAssignableFrom(t_kernel).AssertTrue());

            var t_kernels = t_kernel.Unfold(t1 => t1.BaseType, t1 => !t1.SameMetadataToken(typeof(KernelApi))).SkipLast(1).ToReadOnly().AssertNotEmpty();

            t_kernels.ForEach(t1 =>
            {
                (t1.IsClass && t1.IsAbstract).AssertTrue();

                var declared = t1.GetMembers(BF.All | BF.DeclOnly).Where(m => m.Attrs <CompilerGeneratedAttribute>().IsEmpty()).ToReadOnly();
                declared.ForEach(m => m.IsStatic().AssertFalse());
                declared.ForEach(m => (m is FieldInfo || m is PropertyInfo || m is MethodBase).AssertTrue());
                declared.OfType <FieldInfo>().ForEach(fi => fi.IsFamily.AssertTrue());
                declared.OfType <ConstructorInfo>().ForEach(ci => ci.GetParameters().AssertEmpty());
                declared.OfType <MethodInfo>().ForEach(mi =>
                {
                    var aintProtected     = !mi.IsFamily;
                    var isVirtual         = mi.IsVirtual;
                    var isKernel          = mi.Hierarchy().Any(mi2 => mi2.DeclaringType.IsAssignableFrom(typeof(IKernel)));
                    var isKernelApi       = mi.Hierarchy().Any(b => Apis.Ifaces.Contains(b.DeclaringType));
                    var isKernelLifecycle = mi.Hierarchy().Any(mi2 => mi2.DeclaringType == typeof(IKernel));

                    isKernelApi.AssertFalse();
                    isKernelLifecycle.AssertImplies(isVirtual);
                    isKernel.AssertEquiv(aintProtected);
                });

                var compilerGenerated = t1.GetMembers(BF.All | BF.DeclOnly).Where(m => m.Attrs <CompilerGeneratedAttribute>().IsNotEmpty());
                var thunks            = compilerGenerated.OfType <MethodInfo>().Where(mi =>
                {
                    var match = Regex.Match(mi.Name, @"^\<(?<declaringMethod>.*?)\>.*$");
                    if (!match.Success)
                    {
                        return(false);
                    }

                    var declaringMethod = match.Result("${declaringMethod}");
                    return(t1.GetMethods(BF.All | BF.DeclOnly).Any(mi1 => mi1.Name == declaringMethod));
                });
                var cachedAnonymousDelegates = compilerGenerated.OfType <FieldInfo>().Where(fi =>
                                                                                            Regex.IsMatch(fi.Name, @"^CS\$\<\>.*?CachedAnonymousMethodDelegate.*$"));
                thunks.AssertEmpty();
                cachedAnonymousDelegates.AssertEmpty();
                compilerGenerated.Except(thunks.Cast <MemberInfo>()).Except(cachedAnonymousDelegates.Cast <MemberInfo>()).AssertEmpty();
            });

            // here we create a totally useless instance of the kernel class which shouldn't be instantiated
            //
            // this is a consequence of lacking generics+inference features of c# 3.0
            // when C# 4.0 comes, I'll gladly change this sig and the sig below to:
            // * ConfiguredKernel<TKernel> Configure<TKernel>(this BaseConfig cfg) where TKernel : IKernel<T1, T2, R>
            // * R Execute<T1, T2, R>(this IConfiguredKernel<IKernel<T1, T2, R>> kernel, T1 arg1, T2 arg2)
            //
            // the very best of all would be if I could write all this shizzle as follows:
            // * R Execute<TKernel>(this KernelBase<T1, T2, R> kernel, T1 arg1, T2 arg2) where TKernel : IKernel<T1, T2, R>

            var key        = typeof(EntryPoint).Assembly.ReadKey("Conflux.Conflux.snk");
            var unit       = Codegen.Units["Conflux.Runtime", key];
            var t_concrete = unit.Context.GetOrCreate(t_kernel, () => unit.Module.DefineType(t_kernel.FullName + "_Runtime", TA.Public, t_kernel).CreateType()).AssertCast <Type>();
            var kernel     = t_concrete.CreateInstance().AssertCast <TKernel>();

            // todo. here we have a race between a cloning thread and (possibly) modifying thread
            var cloningCtor = cfg.GetType().GetConstructors(BF.PrivateInstance).AssertSingle();
            var cfgClone    = cloningCtor.Invoke(cfg.MkArray()).AssertCast <IConfig>();

            _kernelConfigs.Add(kernel, cfgClone);

            return(kernel);
        }