예제 #1
0
        private IDictionary <string, Binding> ProcessCompleteModule(
            ModuleGenerator moduleGenerator,
            bool ignoreCompletenessErrors)
        {
            var bindings   = new Dictionary <string, Binding>(StringComparer.Ordinal);
            var overrides  = new Dictionary <string, Binding>(StringComparer.Ordinal);
            var allModules = new Dictionary <string, ModuleGenerator>(StringComparer.Ordinal);
            var hasError   = false;

            GatherIncludedModules(moduleGenerator, allModules, new Stack <string>());

            var resolver = new Resolver(null, loader, errors =>
            {
                if (ignoreCompletenessErrors)
                {
                    return;
                }

                hasError = true;
                foreach (var e in errors)
                {
                    errorReporter.LogError(e);
                }
            });

            foreach (var module in allModules.Values)
            {
                // Request entry-point bindings
                var addTo = module.IsOverride ? overrides : bindings;

                foreach (var injectType in module.Injects)
                {
                    var key = injectType.Resolve().IsInterface
                                  ? CompilerKeys.ForType(injectType)
                                  : CompilerKeys.GetMemberKey(injectType);

                    resolver.RequestBinding(key, module.ModuleType.FullName, false, true);
                }

                foreach (var providerGenerator in module.ProviderGenerators)
                {
                    var binding = new CompilerProvidesBinding(providerGenerator);

                    if (addTo.ContainsKey(binding.ProviderKey))
                    {
                        var message  = "Duplicate bindings for {0} in {1}{2}.";
                        var addendum = module.IsOverride ? "overriding module " : string.Empty;

                        throw new ValidationException(string.Format
                                                          (message, binding.ProviderKey, addendum, module.ModuleType.FullName));
                    }

                    switch (providerGenerator.ProvidesType)
                    {
                    case ProvidesType.Default:
                        addTo.Add(binding.ProviderKey, binding);
                        break;

                    case ProvidesType.Set:
                        var setKey = CompilerKeys.GetSetKey(binding.ProviderKey);
                        CompilerSetBinding.Add(addTo, setKey, binding);
                        break;

                    default:
                        throw new ArgumentException("Unknown ProvidesType value: " + providerGenerator.ProvidesType);
                    }
                }
            }

            resolver.InstallBindings(bindings);
            resolver.InstallBindings(overrides);
            var allBindings = resolver.ResolveAllBindings();

            return(!hasError ? allBindings : null);
        }
예제 #2
0
        private void EmitGetBindings(TypeDefinition runtimeModule)
        {
            /**
             * public override void GetBindings(Dictionary<string, Binding> bindings)
             * {
             *     var module = this.Module;
             *     bindings.Add("keyof binding0", new ProviderBinding0(module));
             *     ...
             *     bindings.Add("keyof bindingN", new ProviderBindingN(module));
             * }
             */
            var getBindings = new MethodDefinition(
                "GetBindings",
                MethodAttributes.Public | MethodAttributes.Virtual,
                References.Void);

            var vModule = new VariableDefinition("module", importedModuleType);

            getBindings.Body.Variables.Add(vModule);
            getBindings.Body.InitLocals = true;

            getBindings.Parameters.Add(new ParameterDefinition(References.DictionaryOfStringToBinding));

            var il = getBindings.Body.GetILProcessor();

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Callvirt, References.RuntimeModule_ModuleGetter);
            il.Emit(OpCodes.Castclass, importedModuleType);
            il.Emit(OpCodes.Stloc, vModule);

            foreach (var binding in ProviderGenerators)
            {
                switch (binding.ProvidesType)
                {
                case ProvidesType.Default:
                    il.Emit(OpCodes.Ldarg_1);
                    il.Emit(OpCodes.Ldstr, binding.Key);
                    il.Emit(OpCodes.Ldloc, vModule);
                    il.Emit(OpCodes.Newobj, binding.GeneratedCtor);
                    il.Emit(OpCodes.Callvirt, References.DictionaryOfStringToBinding_Add);
                    break;

                case ProvidesType.Set:
                    var addMethodRef = new GenericInstanceMethod(References.SetBindings_AddOfT);
                    addMethodRef.GenericArguments.Add(binding.ProviderMethod.ReturnType);
                    il.Emit(OpCodes.Ldarg_1);
                    il.Emit(OpCodes.Ldstr, CompilerKeys.GetSetKey(binding.Key));
                    il.Emit(OpCodes.Ldloc, vModule);
                    il.Emit(OpCodes.Newobj, binding.GeneratedCtor);
                    il.Emit(OpCodes.Call, addMethodRef);
                    break;

                default:
                    throw new InvalidOperationException("Unknown ProvidesType value: " + binding.ProvidesType);
                }
            }

            il.Emit(OpCodes.Ret);

            runtimeModule.Methods.Add(getBindings);
        }